import chess
import chess.svg
from chessboard import display
from chess import Move
import time
import random
import math

board = chess.Board("8/8/8/8/8/8/8/8 w - - 0 1")

# Erste Königing setzen
"""board.set_piece_at(16,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(9,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(34,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(27,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(20,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(13,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(6,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(23,chess.Piece(chess.QUEEN,chess.WHITE))"""

"""board.set_piece_at(16,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(9,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(50,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(35,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(12,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(29,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(6,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(7,chess.Piece(chess.QUEEN,chess.WHITE))"""

"""board.set_piece_at(8,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(25,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(50,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(27,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(60,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(37,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(38,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(15,chess.Piece(chess.QUEEN,chess.WHITE))"""

"""board.set_piece_at(8,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(25,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(26,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(3,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(5,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(14,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(31,chess.Piece(chess.QUEEN,chess.WHITE))
board.set_piece_at(36,chess.Piece(chess.QUEEN,chess.WHITE))"""

def test(i):
    if i == 1:
        board.set_piece_at(16,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(9,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(34,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(27,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(20,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(13,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(6,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(23,chess.Piece(chess.QUEEN,chess.WHITE))

    if i == 2:
        board.set_piece_at(16,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(9,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(50,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(35,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(12,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(29,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(6,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(7,chess.Piece(chess.QUEEN,chess.WHITE))
    if i == 3:
        board.set_piece_at(8,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(25,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(50,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(27,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(60,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(37,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(38,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(15,chess.Piece(chess.QUEEN,chess.WHITE))
    if i == 4:
        board.set_piece_at(8,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(25,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(26,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(3,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(5,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(14,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(31,chess.Piece(chess.QUEEN,chess.WHITE))
        board.set_piece_at(36,chess.Piece(chess.QUEEN,chess.WHITE))

#schauen wo meine damen sind
#print(board.piece_map().keys())
"""
alle damen felder
for square in chess.SQUARES:
    piece = board.piece_at(square)
    if piece is not None:
        # Den Feldnamen der Figur ausgeben
        print(chess.square_name(square))
"""

#
#print(board.piece_at(7))
#print(ord('a'))
#print(chr(97))
#print(chess.square_rank(16))

class Queen:
    notPossibleMoves = []
    transModel = []
    initialState = None
    arrVisited = []
    totalFitness = 0
    populationsArr = []

    #genetic algorithm
    population = []

    def __init__(self, initialState = None, transModel = None):
        if initialState is None:
            self.initialState = [0,0,0,0,0,0,0,0]

        if transModel is None:
            for i in range(0,64):
                if i not in self.notPossibleMoves and i not in self.transModel:
                    self.transModel.append(i)

    def checkNotInArray(self, i):
        if i not in self.notPossibleMoves:
            self.notPossibleMoves.append(i)

    def possibleMoves(self):
        self.notPossibleMoves = []
        for i in range(0, 64):
            if board.piece_at(i) != None:
                self.checkRowQueen(i,True)
                self.checkColumnQueen(i,True)
                self.checkDiagonalQueen(i,True)

        return self.notPossibleMoves

    def actions(self, state):
        # aktion um den zustand zu ändern
        # Figur bewegen
        #move = Move.from_uci(state)
        #board.push(move)
        board.set_piece_at(state,chess.Piece(chess.QUEEN,chess.WHITE))

    def checkRowQueen(self, state,justNotPossibleMoves = False):
        # überprüft wie viele threads in der zeile sind
        # mit Parameterwert True werden mit der Methode checkNotInFunction in das Array notPossibleMoves alle werte geschrieben die nicht mehr möglich sind
        counter = 0
        rowNumber = chess.square_rank(state)

        rowBeginning = (rowNumber * 8)
        rowEnd = (((rowNumber + 1) * 8) -1)

        #print("rowNumber: " + str(rowNumber))
        #print("rowBeginning: " + str(rowBeginning))
        #print("rowEnd: " + str(rowEnd))

        #ZEILE ÜBERPRÜFEN
        test = False
        for cnt in range(rowBeginning , rowEnd + 1):

            if board.piece_at(cnt) != None :

                    test = True
                    counter = counter + 1
                    #print("Row Collision mit: " + str(cnt) + " = COUNTER:  " + str(counter))
            if justNotPossibleMoves == True:
                #print(justNotPossibleMoves)
                self.checkNotInArray(cnt)

        if test == True:
            return counter -1
        else:
            return 0

    def checkColumnQueen(self, state, justNotPossibleMoves = False):
        # überprüft wie viele threads in der spalte sind
        # mit Parameterwert True werden mit der Methode checkNotInFunction in das Array notPossibleMoves alle werte geschrieben die nicht mehr möglich sind
        columnBegin = state
        columnEnd = state
        counter = 0
        while columnBegin > 0:
            if (columnBegin - 8) >= 0:
                columnBegin = columnBegin-8
            if columnBegin >= 0 and columnBegin <= 7:
                break

        while columnEnd <= 63:
            if (columnEnd + 8 ) <= 63:
                columnEnd = columnEnd + 8
            if columnEnd >= 56 and columnEnd <= 63:
                break

        test = False

        for cnt in range(columnBegin , columnEnd + 1, 8):
                if board.piece_at(cnt) != None:
                    test = True
                    counter = counter + 1
                    #print("counter : " + str(counter))
                    self.arrVisited.append(cnt)
                    #print(self.arrVisited)
                    #print("Column Collision mit: " + str(cnt) + " = COUNTER:  " + str(counter))
                if justNotPossibleMoves == True:
                    self.checkNotInArray(cnt)
        #print("BEFORE RETURN COUNTER: " + str(counter))

        if test == True:
            #print("RETURN COUNTER: " + str(counter))
            return counter - 1
        else:
            return 0

    def LBU(self, state, justNotPossibleMoves = False):
        counter = 0
        yBorderLeft = []
        yBorderRight = []
        xBorderUnder = []
        xBorderAbove = []

        leftBeginUnder = state
        rightEndAbove = state

        for cnt in range(0,57,8):
            yBorderLeft.append(cnt)
        for cnt in range(7,64,8):
            yBorderRight.append(cnt)
        for cnt in range(0,8,1):
            xBorderUnder.append(cnt)
        for cnt in range(56,64,1):
            xBorderAbove.append(cnt)

        if leftBeginUnder not in yBorderLeft:
            while leftBeginUnder not in yBorderLeft:
                if ((leftBeginUnder - 8) - 1) < 0:
                    break
                leftBeginUnder = (leftBeginUnder - 8) - 1

        if rightEndAbove not in yBorderRight:
            while rightEndAbove not in yBorderRight:
                if ((rightEndAbove +8) +1) > 63:
                    break
                rightEndAbove = (rightEndAbove + 8) + 1

        checkFirst = False
        #schaut diagonal von unten links nach oben rechts ob eine dame gesetzt ist
        if justNotPossibleMoves == True:
                self.checkNotInArray(leftBeginUnder)

        #print("LeftBeginUnder: " + str(leftBeginUnder))
        #print("rightEndAbove: " + str(rightEndAbove))
        #print()

        while (leftBeginUnder + 1) + 8 < rightEndAbove + 1:

            if board.piece_at(leftBeginUnder) is not None:
                checkFirst = True
                counter = counter + 1
                #print("LBU: " + str(leftBeginUnder) + " :::: " + str(counter) )
            leftBeginUnder = (leftBeginUnder + 8) +1

            if justNotPossibleMoves == True:
                self.checkNotInArray(leftBeginUnder)

        #print("KOLLISION MIT DIAGONAL: " + str(leftBeginUnder) + " -" + str(counter))

        if checkFirst == True:
            counter = counter - 1
        return counter

    def LBA(self, state, justNotPossibleMoves = False):
             # überprüft wie viele threads in der diagonale sind
        # mit Parameterwert True werden mit der Methode checkNotInFunction in das Array notPossibleMoves alle werte geschrieben die nicht mehr möglich sind
        counter = 0
        yBorderLeft = []
        yBorderRight = []
        xBorderUnder = []
        xBorderAbove = []

        leftBeginUnder = state
        rightEndAbove = state
        leftBeginAbove = state
        rightEndUnder = state

        for cnt in range(0,57,8):
            yBorderLeft.append(cnt)
        for cnt in range(7,64,8):
            yBorderRight.append(cnt)
        for cnt in range(0,8,1):
            xBorderUnder.append(cnt)
        for cnt in range(56,64,1):
            xBorderAbove.append(cnt)

        if leftBeginAbove not in yBorderLeft:
            while leftBeginAbove not in yBorderLeft:
                if ((leftBeginAbove + 8) - 1) > 63:
                    break
                leftBeginAbove = (leftBeginAbove + 8 ) - 1

        if rightEndUnder not in yBorderRight:
                while rightEndUnder not in yBorderRight:
                    if ((rightEndUnder - 8) +1) < 0:
                        break
                    rightEndUnder = (rightEndUnder - 8) + 1

        checkSecond = False
        #print("LeftBeginAbove: " + str(leftBeginAbove))
        #print("rightEndAbove: " + str(rightEndUnder))
        # print()
        # schaut diagonal von oben links nach unten rechts ob eine dame gesetzt ist
        if justNotPossibleMoves == True:
                self.checkNotInArray(leftBeginAbove)

        test = False
        while (leftBeginAbove - 8 ) + 1 >= rightEndAbove :
            if board.piece_at(leftBeginAbove) is not None:
                #print(leftBeginAbove)
                checkSecond = True
                counter = counter + 1

                #print("LBA: " + str(leftBeginAbove) + " :::: " + str(counter))

            #print(leftBeginUnder)

            #print("T: " + str(leftBeginAbove))
            if justNotPossibleMoves == True:
                self.checkNotInArray(leftBeginAbove)

            leftBeginAbove = (leftBeginAbove - 8) + 1

        if board.piece_at(leftBeginAbove) is not None:
                #print(leftBeginAbove)

                checkSecond = True
                counter = counter+1
                #print("LBA: " + str(leftBeginAbove) + " :::: " + str(counter))

        #print("KOLLISION MIT DIAGONAL: " + str(leftBeginUnder) + " ::::: " + str(counter))

        if checkSecond == True:
            counter = counter - 1

        #print(self.notPossibleMoves)
        return counter

    def checkDiagonalQueen(self, state, justNotPossibleMoves = False):
        # überprüft wie viele threads in der diagonale sind
        # mit Parameterwert True werden mit der Methode checkNotInFunction in das Array notPossibleMoves alle werte geschrieben die nicht mehr möglich sind

        #leftbeginAbove#############################rightEndAbove
        #########################################################
        #########################################################
        #########################################################
        #########################################################
        #########################################################
        #########################################################
        #########################################################
        #########################################################
        #########################################################
        #leftBeginUnder#############################rightEndUnder

        c = self.LBA(state)
        d = self.LBU(state)

        #print(self.notPossibleMoves)
        return c + d

    def heuristic(self, state):
        # pairs of threatening queens
        # state sollte ein integer sein!!!

        #board.piece_at(1) prüft ob sich das Feld belegt ist wenn nein dann None

        #zeile in der sich die queen befindet
        rowThreadingCount = self.checkRowQueen(state)
        columnThreadingCount = self.checkColumnQueen(state)
        diagonalThreadUA = self.checkDiagonalQueen(state)

        #zähle die Threads zusammen

        counter = rowThreadingCount  + columnThreadingCount + diagonalThreadUA

        return counter
        #return rowThreadingCount

    def cost(self, state, action):
        # berechnet die kosten der aktion
        # previousCost sind die Kosten von der letzten platzierung der Dame und expectedCost sind die Kosten
        # von der aktuellen position wenn ich die Dame auf das Feld setzen möchte. Wenn die Kosten höher sind
        # als davor dann soll ein neues feld gesucht werden
        previousCost = self.heuristic(state)
        exceptedCost = self.heuristic(action)
        return previousCost + exceptedCost

    def boardASCII(self):
        #ASCII vom Board ausgeben
        print(board)

    def threadeningLBUCount(self):
            val = 64
            t = False
            counter = 0
            while t == False:
                if (val-8) >= 0:
                    val = val -8
                else:
                    val = val + 1
                #print(val)

                counter = counter + queen.LBU(val)
                #print("Bei " + str(val) + " wurden so viele Threadings entdeckt : " + str(cnt) )
                if val == 7:
                    t = True

            return counter
    def threadeningLBACount(self):
            val = 0
            t = False
            counter = 0
            while t == False:
                if (val + 1) < 8:
                    val = val + 1
                else:
                    val = val + 8
                #print(val)

                counter = counter + queen.LBA(val)
                #print("Bei " + str(val) + " wurden so viele Threadings entdeckt : " + str(cnt) )
                if val == 63:
                    t = True

            return counter

    def threadeningRowCount(self):
            counter = 0
            spalteX = []

            for i in range(0,64):
                if board.piece_at(i) != None:
                    if chess.square_rank(i) not in spalteX:
                        if queen.checkRowQueen(i) >= 1:
                            counter = queen.checkRowQueen(i) + counter
                    spalteX.append(chess.square_rank(i))
            return counter
    def threadeningColumnCount(self):
           counter = 0
           for i in range(0,8):
                #spalte 1 bis 7 geben um pro spalte zuschauen
                counter  = queen.checkColumnQueen(i) + counter
           return counter

    def countOfThreadeningQueens(self):

            counter = self.threadeningLBUCount() + self.threadeningRowCount() + self.threadeningLBACount() + self.threadeningColumnCount()

            return counter

    def fitnessFunctionPercentage(self, val):
        # val ist die anzahl der threatenings

        if self.totalFitness != 0:
            val = round((val / self.totalFitness) * 100, 2)

            return val

    def fitnessFunction(self, setTotalFitnessCalc = False):
                fitness = self.threadeningLBUCount() + self.threadeningRowCount() + self.threadeningLBACount() + self.threadeningColumnCount()
                return 28 - (fitness)

    def setTotalFitnessCalc(self, fitness):
        # berechnet die gesamsumme der fitness
        #print(str(self.totalFitness) + " + (28 - " + str(fitness) + " )")
        #self.totalFitness = self.totalFitness + (28 -  fitness)
        fitnessVal = 0
        for i in self.populationsArr:
            fitnessVal = fitnessVal + int(i["fitness"])

        #print(fitnessVal)
        self.totalFitness = fitnessVal

    def is_valid_state(self, state):
            # Überprüfen, ob das gegebene state eine gültige Lösung für das 8-Damen-Problem ist
            n = len(state)
            if len(set(state)) != n:
                return False
            if len(set(i+state[i] for i in range(n))) != n:
                return False
            if len(set(i-state[i] for i in range(n))) != n:
                return False
            return True

    def generate_valid_state(self):
    # zufällige generierte states
        while True:
            state = random.sample(range(8), 8)
            if self.is_valid_state(state):
                return state

    def populations(self, k):
        randValArr = []
        for i in range(k):
            randValArr.append(self.generate_valid_state())
        return randValArr

    def printPopulations(self):
         for i in self.populationsArr:
              fitness = int(i["fitness"])
              fitnessPercentage = float(self.fitnessFunctionPercentage(fitness))
              i["fitnessPercentage"]  = fitnessPercentage
              print("\nPopulationnumber: " + str(i["populationNumber"]))
              print("Fitness: " + str(i["fitness"]))
              print("TotalFitness: "  + str(self.totalFitness))
              print("Fitnesspercentage: " + str(fitnessPercentage) + " % ")

    def printAndCheckBestOnBoard(self,popNewArr):
        fitness = 0
        populationNumber = 0
        sieg  = False
        for i in popNewArr:
            fitness = i["fitness"]
            if fitness == 28:
                populationNumber = int(i["populationNumber"])
                sieg = True
                break

        columnCounter = 0
        check = 0

        for i in popNewArr:
            queens = i["population"]
            if int(i["populationNumber"]) == populationNumber and sieg == True:
                for j in queens:
                    if columnCounter == 8:
                            columnCounter = 0

                    board.set_piece_at((( 8 * j) + columnCounter),chess.Piece(chess.QUEEN,chess.WHITE))

                    columnCounter = columnCounter + 1

        for i in popNewArr:
             if int(i["populationNumber"]) == populationNumber and sieg == True:
                print()
                print("''''''''''''''''''''''''''''''''''''''''''''''''''''''''''")
                print("Gewonnen hat: " +str(i["populationNumber"]))
                print("Population: " +str(i["population"]))
                print("Mit einer Fitness von: "+ str(i["fitness"]))
                print("Mit einer Fitness Percentage: " + str(i["fitnessPercentage"]))
                break

        print()

    def selection(self):
            popArr = self.populationsArr
            #print(self.populationsArr)
            popNewArr = []
            solutionArr = []
            for i in range(0, len(self.populationsArr)):
                rand = random.randrange(0,len(self.populationsArr))
                #print(rand)
                popNewArr.append(popArr[rand])

            #print(popNewArr)
            newRand = 0
            ungerade = False
            for i in range(0,len(popNewArr)):
                population1 = None
                population2 = None
                if (len(popNewArr) % 2) != 0 and i == len(popNewArr[len(popNewArr)-1]):
                    newRand = random.randrange(0,len(popNewArr))
                    ungerade = True

                if i == len(popNewArr) - 1 and ungerade == True:

                    population1 = popNewArr[len(popNewArr)-1]["population"]
                    population2 = popNewArr[newRand]["population"]
                    #print("Pop1: " + str(population1))
                    #print("Pop2: " + str(population2))
                    #print("LAST: " + str( len(popNewArr)-1))
                    #print("NEWRAND: " + str(newRand))
                    arr = self.crossover(population1, population2)

                    popNewArr[len(popNewArr)-1]["population"] = arr[0]
                    popNewArr[newRand]["population"] = arr[1]

                    #print("AFTER CROSS " + str(popNewArr[len(popNewArr)-1]["population"]))
                    #print(popNewArr[newRand]["population"])
                else:
                    newRand = random.randrange(0,len(popNewArr))
                    newRand2 = newRand
                    while newRand == newRand2:
                        newRand2 = random.randrange(0,len(popNewArr))
                    population1 = popNewArr[newRand]["population"]
                    population2 = popNewArr[newRand2]["population"]

                    arr = self.crossover(population1,population2)

                    popNewArr[newRand]["population"] = arr[0]
                    popNewArr[newRand2]["population"] = arr[1]

                rand = random.randrange(0,len(popNewArr))

            popNewArr = self.mutation(popNewArr)
            self.printAndCheckBestOnBoard(popNewArr)

    def crossover(self, arr1, arr2):
        splitt = random.sample(range(1, 7), 1)
        tmpArr1 = []
        tmpArr2 = []
        for i in range(0,8):
            if i <= splitt[0]:
                #print(arr1)
                #print(arr2)
                #print("SPLITT: " + str(splitt))
                tmpArr1.append(arr1[i])
                tmpArr2.append(arr2[i])
            else:
                tmpArr1.append(arr2[i])
                tmpArr2.append(arr1[i])

        arr1 = tmpArr1
        arr2 = tmpArr2

        return [arr1, arr2]

    def mutation(self, arr):
        randomVal = random.randrange(8)
        rand = random.randrange(8)

        while randomVal == rand:
            rand = random.randrange(8)
        for i in arr:
            #print("BEFORE: " + str(i["population"]))
            newArr = i["population"]
            newArr[randomVal] = rand
            i["population"] = newArr
            #print("aFter: " + str(i["population"]))
        return arr

    def orderPopulationArray(self):
        # ordnet das assoziative array nach fitnessfunction größe
        self.populationsArr.sort(key=lambda x: x["fitnessPercentage"], reverse=True)

    def setQueens(self, populationsAnzahl, Test = False):
         popuArr = self.populations( populationsAnzahl)
         arr = []
         counter = 0
         columnCounter = 0
         populationNumber = 0
         print(popuArr)
         for i in popuArr:
            new_arr = arr.copy()

            #print("Counter: " + str(counter))
            if Test == False:
                for j in i:
                    new_arr.append(j)
                    if columnCounter == 8:
                        columnCounter = 0

                    #print("COLUMNCOUNTER: " + str(columnCounter) + " j: " + str(j))

                    board.set_piece_at((( 8 * j) + columnCounter),chess.Piece(chess.QUEEN,chess.WHITE))
                    columnCounter = columnCounter + 1

                #print(arr)
                self.populationsArr.append({
                            "populationNumber" : populationNumber ,
                            "fitness" : self.fitnessFunction(),
                            "population" : new_arr,
                            "fitnessPercentage" : 0
                })
                #print(self.populationsArr)

                print("PopulationNumber: " + str(populationNumber))
                self.boardASCII()

                self.setTotalFitnessCalc(self.fitnessFunction())
                        #print(self.populationsArr)
                        #self.fitnessFunctionPercentage(populations)
                print()
                #print("HIER: "+ str(self.populationsArr))
                board.clear()

                counter = counter + 1
                populationNumber = populationNumber +1

                queen.orderPopulationArray()

            else:
                for i in range(1,5):
                    test(i)
                    self.boardASCII()

                    self.populationsArr.append({
                        "populationNumber" : populationNumber ,
                        "fitness" : self.fitnessFunction(),
                        "population" : arr,
                        "fitnessPercentage" : 0
                    })

                    self.setTotalFitnessCalc(self.fitnessFunction())
                    #print(self.populationsArr)
                    #self.fitnessFunctionPercentage(populations)
                    print()

                    board.clear()

                    counter = counter + 1
                    populationNumber = populationNumber +1

         #self.printPopulations()
         self.selection()

         #print(selected)
         #board.set_piece_at(8,chess.Piece(chess.QUEEN,chess.WHITE))

    def geneticAlgorithm(self):

        return

queen = Queen()

#print("Fitness: " + str(queen.fitnessFunction()))
#print("Threadening: "  +str(queen.countOfThreadeningQueens()))
#print("TotalFitness: " + str(queen.totalFitness))
#print("TotalFitness: " + str(queen.populations(1)))

# test
#queen.setQueens(1, True)

queen.setQueens(100)

#arr1 = [3,2,7,5,2,4,1,1]
#arr2 = [2,4,7,4,8,5,5,2]
#print(queen.crossover(arr1,arr2))

#print("BEFORE: " + str(arr1))
#rint("AFTER:  " + str(queen.mutation(arr1)))

#queen.possibleMoves()
#print(queen.heuristic(17))
#print(queen.fitnessFunction())
#print(queen.geneticAlgorithm(100,100,1000))

# Fen ist eine Notation um die Posititon der Schachfiguren auf einem Schabrett darzustellen
valid_fen = board.fen()
game_board = display.start()

n = 0
while True:
    #valid_fen = board.fen()
    #n = (n + 8)
    #board.set_piece_at(n,chess.Piece(chess.QUEEN,chess.WHITE))

    display.check_for_quit()
    display.update(valid_fen, game_board)
    time.sleep(0.5)

display.terminate()


import nltk
nltk.download('twitter_samples')
from nltk.corpus import twitter_samples
import json
from twitter import *
import gender_guesser.detector as gender
from datetime import *
from ethnicity import *
#import numpy as np
#import os
#import copy
#import difflib

class TweetEmotionClassifier:
    def __init__(self):
        """
        Intialize a new twitter emotion classifier self which is trained by dataset
        in nltk.corpus. It is an sentiment analysis tool which inputs a text and return
        a positve or negative attitude.
        """
        tweets = [(map(lambda x:x.lower(), pos_tweet.split()), 'pos') for pos_tweet in twitter_samples.strings('positive_tweets.json')] + [(map(lambda x:x.lower(), neg_tweet.split()), 'neg') for neg_tweet in twitter_samples.strings('negative_tweets.json')]
        all_words = self._TweetEmotionClassifier__get_all_words()
        word_freq_dist = nltk.FreqDist(all_words)
        self.features = [word for (word, _) in word_freq_dist.most_common(600)]
        training_samples = [(self._TweetEmotionClassifier__extract_features(tweet), category) for (tweet, category) in tweets]
        self.classifier = nltk.NaiveBayesClassifier.train(training_samples)

    def __get_all_words(self):
        """
        helpfunction that read input from twitter classification with both positive tweet and
        negative tweet.
        """
        pos_words = [word.lower() for pos_tweet in twitter_samples.strings('positive_tweets.json') for word in pos_tweet.split()]
        neg_words = [word.lower() for neg_tweet in twitter_samples.strings('negative_tweets.json') for word in neg_tweet.split()]
        all_words = pos_words + neg_words
        return all_words

    def classify(self, tweet):
        """
        classify based on features of text
        """
        featurized_tweet = self._TweetEmotionClassifier__extract_features(map(lambda x:x.lower(), tweet.split()))
        return self.classifier.classify(featurized_tweet)

    def __extract_features(self, tweet):
        """
        extract feature of the text
        """
        tweet_words = set(tweet)
        extracted_features = {}
        for feature in self.features:
            extracted_features['contains(%s)' % feature] = (feature in tweet_words)
        return extracted_features

# Tweet data object
class Tweet:
    def __init__(self, tweet):
        """
        Intialize a new tweet class based on the filter return json file,
        and extract core attribute like text, date, location and etc to
        benefit for the
        """
       # self.emotion_classifier = emotion_classifier
        self.text = tweet['text']
        self.date = tweet['created_at']
        self.user_name = tweet['user']['name']
        self.user_screen_name = tweet['user']['screen_name']
        self.location = tweet['user']['location']
        self.attitude = "None"
    def get_text(self):
        return self.text

    def get_user_name(self):
        return self.user_name

    def get_user_screen_name(self):
        return self.user_screen_name

    def get_location(self):
        return self.location

    def get_date(self):
        return self.date

    def get_attitude(self):
        return self.attitude

class Tweets:
    def __init__(self, query, size=1000):
        """
        Initialize a new Tweets class that implement lots of core function
        of this project like using Twitter Search Api to fetch tweets,
        filtered tweets and all kinds of statistic analysis
        """
        credential = json.loads(open("credential.json", "r").read())
        auth = OAuth(credential['OAUTH_TOKEN'], credential['OAUTH_TOKEN_SECRET'], credential['CONSUMER_KEY'], credential['CONSUMER_SECRET'])
        twitter = Twitter(auth=auth)
        self.tweets = self._Tweets__fetch_tweets(query, twitter, size)
        self.ethnicity_predictor = Ethnicity().make_dicts()
       # self.emotion_classifier = emotion_classifier

    def __filter_non_informative_tweets(self, tweets):
        """
        filtering no informative tweets that has redundant symbol
        """
        filtered_tweets = []
        MINIMUM_WORD_COUNT = 6
        MAXIMUM_SHORT_SENTENCE_COUNT = 2
        for tweet in tweets:
            tweet_word_count = len(tweet.get_text().split())
            short_sentence_count = len([len(sentence) for sentence in tweet.get_text().split('\n') if len(sentence.split()) < 5 and len(sentence.split()) > 0])
            ata_count = len([char for char in tweet.get_text() if char == '@'])
            if tweet_word_count < MINIMUM_WORD_COUNT or short_sentence_count > MAXIMUM_SHORT_SENTENCE_COUNT or is_advertisement(tweet.get_text()):
                continue
            filtered_tweets.append(tweet)
        return filtered_tweets

    def __remove_duplicate_tweets(self, tweets):
        """
        filtering duplicate tweets to make analysis more accurate
        """
        filtered_tweets = []
        tweet_text_set = set()
        for tweet in tweets:
            if tweet.get_text() not in tweet_text_set:
                filtered_tweets.append(tweet)
                tweet_text_set.add(tweet.get_text())
        return filtered_tweets

    def __fetch_tweets(self, query, twitter, size):
        """
        using twitter search api to fetch tweets with english language.
        And each payload is restricted to 100 based on the requirement.
        More over,doing the basic data preprocess about fetched information.
        """
        tweets = []
        try:
            max_id = twitter.search.tweets(q=query,lang='en',count=1)['search_metadata']['max_id']
        except:
            return tweets
        while (len(tweets)<size):
            load_size = 100
            if size - len(tweets) <= 100:
                load_size = size - len(tweets)
            try:
                tweet_search = twitter.search.tweets(q=query, lang='en',count=load_size, max_id=max_id)
            except:
                return tweets
            number_of_tweets = len(tweet_search['statuses'])
            if number_of_tweets == 0:
                break
            max_id = tweet_search['statuses'][number_of_tweets-1]['id'] - 1
            ###
            tweets += [Tweet(tweet) for tweet in tweet_search['statuses']]
            tweets = self._Tweets__filter_non_informative_tweets(tweets)
            tweets = self._Tweets__remove_duplicate_tweets(tweets)

        return tweets

    def get_tweets(self):
        return self.tweets

    def __predict_gender(self, names, screen_names):
        """
        predict gender distribution based on the Gender Detector
        """
        d = gender.Detector()
        predictions = []
        names_count = len(names)
        for i in range(names_count):
            prediction = d.get_gender(names[i])
            if prediction != 'female' and prediction != 'male':
                prediction = d.get_gender(screen_names[i])
            predictions.append(prediction)

        return predictions

    def gender_statistics(self):
        """
        the statistics result of gender distribution
        """
        names = [tweet.get_user_name() for tweet in self.tweets]
        screen_names = [tweet.get_user_screen_name() for tweet in self.tweets]

        predictions = self._Tweets__predict_gender(names, screen_names)
        stats = {}
        total = len(predictions)
        male_total, female_total, NA_total = 0, 0, 0
        for prediction in predictions:
            if prediction == 'male':
                male_total += 1
            elif prediction == 'female':
                female_total += 1
            else:
                NA_total += 1
        stats['male'] = male_total/total
        stats['female'] = female_total/total
        stats['NA'] = NA_total/total
        return stats

    def race_statistics(self):
        """
        predict race distribution based on the ethnicity_predictor
        """
        names = [tweet.get_user_name() for tweet in self.tweets]
        predictions = self.ethnicity_predictor.get(names)
        stats = {}
        total = len(names)
        for ethnicity in predictions["Ethnicity"]:
            if ethnicity not in stats:
                stats[ethnicity] = 1
            else:
                stats[ethnicity] += 1
        return {(k+"_percentage"): v/total for k, v in stats.items()}

    def __filter_invalid_location(self, locations):
        """
        filter invalid us location, based on the imported json file
        """
        cities_states_lookup_table = json.loads(open("cities_and_states.json", "r").read())
        filtered_locations = [location for location in locations if ', ' in location]
        filtered_locations = [location for location in filtered_locations if location.split(', ')[1] in cities_states_lookup_table]
        filtered_locations = [location for location in filtered_locations if location.split(', ')[0] in cities_states_lookup_table[location.split(', ')[1]]]
        return filtered_locations

    def location_statistics(self):
        """
        the statistics result of location distribution
        """
        locations = [tweet.get_location() for tweet in self.tweets if tweet.get_location() != '']
        non_filtered_locations_count = len(locations)
        locations = self._Tweets__filter_invalid_location(locations)
        stats = {}
        for location in locations:
            if location not in stats:
                stats[location] = 1
            else:
                stats[location] += 1
        if non_filtered_locations_count != 0:
            stats['unknown'] = non_filtered_locations_count - len(locations)
        return stats

    def __pos_attitude_percentage(self, attitudes):
        attitudes_total = len(attitudes)
        pos_total = 0
        for attitude in attitudes:
            if attitude == 'pos':
                pos_total += 1

        return pos_total/attitudes_total

    def pos_attitude_percentage(self, emotion_classifier):
        """
        using sentiment analysis tool to get the statistics result
        of positve attitude tweets
        """
        attitudes = []
        for tweet in self.get_tweets():
            attitudes.append(emotion_classifier.classify(tweet.get_text()))

        return self._Tweets__pos_attitude_percentage(attitudes)

    def __neg_attitude_percentage(self, attitudes):
        attitudes_total = len(attitudes)
        neg_total = 0
        for attitude in attitudes:
            if attitude == 'neg':
                neg_total += 1

        return neg_total/attitudes_total

    def neg_attitude_percentage(self, emotion_classifier):
        """
        using sentiment analysis tool to get the statistics result
        of negative attitude tweets
        """
        attitudes = []
        for tweet in self.get_tweets():
            attitudes.append(emotion_classifier.classify(tweet.get_text()))

        return self._Tweets__neg_attitude_percentage(attitudes)

    def overall_attitude(self, emotion_classifier):
        """
        based on statistic of pos/neg sentiment analysis to compute
        the overall attitude
        """
        attitudes = []
        for tweet in self.get_tweets():
            attitudes.append(emotion_classifier.classify(tweet.get_text()))

        pos_percentage = self._Tweets__pos_attitude_percentage(attitudes)
        neg_percentage = self._Tweets__neg_attitude_percentage(attitudes)
        overall_attitude = ''
        if pos_percentage > neg_percentage:
            return 'pos'
        if neg_percentage > pos_percentage:
            return 'neg'
        if neg_percentage == pos_percentage:
            return 'neutral'

def is_advertisement(tweet):
    """
    filtering advertisment tweet to make sentiment analysis more accurate.
    """
    is_advertisement = False
    advertisement_keywords = ['sale', 'sales', 'sell', 'buy', 'blackfriday', 'black friday', 'cyber monday', 'discount', 'discounts', 'ebay', 'amazon', 'best buy', 'bestbuy', 'walmart', 'target', 'used', 'new', 'condition']
    for advertisement_keyword in advertisement_keywords:
        if advertisement_keyword in tweet.lower():
            is_advertisement = True
            break
    return is_advertisement

#main function
e9c = TweetEmotionClassifier()

#test = Tweets("@KingJames", 2000)
#test = Tweets("@kobebryant", 1500)
test = Tweets("@KDTrey5", 20)
#test = Tweets("@StephenCurry30", 2000)
#test = Tweets("@SHAQ", 2000)
for item in test.get_tweets():
    item.attitude = e9c.classify(item.get_text())
    print(item.get_text() + '\n ' + item.get_user_screen_name() + '\n '+item.get_date()  +'\n'+ item.get_attitude()+'\n ===================')
print(test.pos_attitude_percentage(e9c))
print(test.neg_attitude_percentage(e9c))
print(test.location_statistics())
print(test.race_statistics())
print(test.gender_statistics())

#print(test.ethnicity_predictor)


import numpy

from compapp import Computer, Plotter, Link, AutoUpstreams

class HistPlotter(Plotter):
    bins = 100
    data = Link('..sim.results.data')

    def run(self):
        _, ax = self.figure.subplots()
        ax.hist(self.data, **self.params())

class CumHistPlotter(HistPlotter):
    cumulative = True

class MySimulator(Computer):
    samples = 1000

    def run(self):
        self.results.data = numpy.random.randn(self.samples)

class MyApp(Computer):
    autoupstreams = AutoUpstreams
    sim = MySimulator
    density = HistPlotter
    cumdist = CumHistPlotter

if __name__ == '__main__':
    MyApp().execute()


import os, psutil, time, signal, sqlite3, config, subprocess, json
from ruamel.yaml import YAML
import girder_client
import xml.etree.ElementTree as ET
import girder_client

def check_pid(pid):
    try:
        os.kill(pid, 0)

        if (psutil.Process(pid).status() == psutil.STATUS_ZOMBIE):
            return False

        return True
    except OSError:
        return False

def get_wf_status(pid, guid):
    if (pid == None):
        return "NOT_YET_EXECUTED"
    if (pid<0):
        return "TERMINATED"

    if (check_pid(pid)):
        return "RUNNING"

    input_path = os.path.join(config.INPUTS,guid)

    dir_name = os.path.join(config.RESULTS, guid)

    for root, directories, files in os.walk(dir_name):
        directories[:] = [d for d in directories if d not in ['tmp']]
        for filename in files:
            return "FINISHED_OK"

    return "FINISHED_ERROR"

def terminate(GUID, pid, flag, timeout = 0):
    time.sleep(timeout)
    parent = psutil.Process(pid)
    for child in parent.children(recursive=True):  # or parent.children() for recursive=False
        os.kill(child.pid, signal.SIGINT)
    os.kill(pid, signal.SIGINT)
    conn = sqlite3.connect(config.DATABASE)
    c = conn.cursor()

    c.execute('UPDATE workflows SET PID='+str(flag)+' WHERE GUID="'+GUID+'"')

    conn.commit()
    conn.close()

def get_wf_pid(GUID):
    conn = sqlite3.connect(config.DATABASE)
    c = conn.cursor()
    c.execute('SELECT * FROM workflows WHERE GUID="'+GUID+'"')
    row = c.fetchone()

    conn.close()
    if (row is None):
        return None

    return row[3]

def get_wf(GUID):
    conn = sqlite3.connect(config.DATABASE)
    c = conn.cursor()
    c.execute('SELECT * FROM workflows WHERE GUID="'+GUID+'"')
    row = c.fetchone()

    conn.close()
    return row

def validate_yaml(input_dir):
    yaml = YAML()
    cwd = os.getcwd()
    os.chdir(input_dir)
    missing = list()
    with open('inputs.yaml') as file:

        yaml_in = yaml.load(file)
        for key in yaml_in:
            if (yaml_in[key] is not None and key!="girderIds"):
                if isinstance(yaml_in[key] , list):
                    for d in yaml_in[key]:
                        if (not os.path.isfile(d['path'])):
                            missing.append(d['path'])
                if isinstance(yaml_in[key],dict):
                    if (not os.path.isfile(yaml_in[key]['path'])):
                        missing.append(yaml_in[key]['path'])

    os.chdir(cwd)
    return missing

def getGirderIds(input_dir):
    yaml = YAML()
    cwd = os.getcwd()
    os.chdir(input_dir)
    with open('inputs.yaml') as file:
        os.chdir(cwd)
        yaml_in = yaml.load(file)
        if yaml_in.get('girderIds') is not None:
            return yaml_in['girderIds']
        else:
            return []

def downloadGirderFile(girderId, pathToInputs, girder_api_key):
    gc = girder_client.GirderClient(apiUrl=config.GIRDER_API)
    gc.authenticate(apiKey=girder_api_key)
    girderFile = gc.getFile(girderId)
    gc.downloadItem(girderFile['itemId'], pathToInputs)

def uploadToGirder(folderPath, girder_api_key, girder_parent_id):
    gc = girder_client.GirderClient(apiUrl=config.GIRDER_API)
    gc.authenticate(apiKey=girder_api_key)

    gc.upload(folderPath, girder_parent_id)

    ls = gc.listFolder(girder_parent_id, name=folderPath.split("/")[-1])
    return list(ls)[0]

def ifReadOnlyWf(workflow):
    jsonFile = json.load(open("read-only-wfs.json",'r'))
    wfs = jsonFile['wfs']

    if (workflow in wfs):
        return True
    return False

def getWfOutputDir(GUID):
    return os.path.join(config.RESULTS,GUID)

def getWfInputDir(GUID):
    return os.path.join(config.INPUTS,GUID)

def getDownloadOutputLink(GUID,path):
    link = "get-output-file?GUID="+GUID+"&filepath="+path
    return link

def getDownloadInputLink(GUID,path):
    link = "get-input-file?GUID="+GUID+"&filepath="+path
    return link

def getZipLink(GUID):
    link = "get-results?GUID="+GUID
    return link

def getGirderOutputDir(wf):
    if (wf[4] is None):
        return wf[0]
    try:
        tree = ET.fromstring(wf[4])
        return tree.find('output').text
    except:
        return wf[0]

def deleteFolderFromGirder(wf, girder_api_key):

    try:
        gc = girder_client.GirderClient(apiUrl=config.GIRDER_API)
        userId = gc.authenticate(apiKey=girder_api_key)['_id']
        privateFolder = gc.loadOrCreateFolder('Private', userId, parentType="user")

        outFolder = gc.loadOrCreateFolder('workflow-outputs', privateFolder['_id'], parentType="folder")
        #wf = get_wf(guid)
        wfFolder = gc.loadOrCreateFolder(wf[2], outFolder['_id'], parentType="folder")

        outputFolder = gc.loadOrCreateFolder(getGirderOutputDir(wf), wfFolder['_id'], parentType="folder")
        gc.delete("folder/"+outputFolder['_id'])
    except:
        return


import numpy as np

from server.rule_utils.card import action_space
from server.rule_utils.decomposer import Decomposer
from server.rule_utils.evaluator import cards_value, dapai

card_list = [
    "3", "4", "5", "6",
    "7", "8", "9", "10",
    "J", "Q", "K", "A",
    "2", "*", "$"
]

# 返回当前局面上剩余最大的单牌（没考虑炸弹）
def maxcard(other_hand, l, ll):
    max = 0
    # for i, j in enumerate(other_hand):
    #     if j != 0:
    #         max = i
    for i in other_hand[l]:
        if i > max:
            max = i
    for j in other_hand[ll]:
        if j > max:
            max = j
    return max - 2

def choose(payload3):
    # 获得手牌
    hand_card = payload3['cur_cards']

    # 拆牌器和引擎用了不同的编码 1 -> A, B -> *, R -> $
    trans_hand_card = [card_list[i - 3] for i in hand_card]
    # 获得上家出牌
    role_id = payload3['role_id']
    lrole_id = (role_id - 1 + 3) % 3  # 上家ID
    llrole_id = (role_id - 2 + 3) % 3  # 上上家ID
    last_pid = lrole_id  # 上一个有效出牌
    tlast_move = payload3['last_taken'][last_pid]
    if not tlast_move:
        last_pid = llrole_id
        tlast_move = payload3['last_taken'][last_pid]
    last_move = [card_list[i - 3] for i in tlast_move]
    # last_move = [card_list[i] for i in range(15) for _ in range(state.last_move[i])]
    # 拆牌
    D = Decomposer()
    combs, fine_mask = D.get_combinations(trans_hand_card, last_move)
    # 根据对手剩余最少牌数决定每多一手牌的惩罚
    # left_crads = [sum(p.get_hand_card()) for p in self.game.players]
    # min_oppo_crads = min(left_crads[1], left_crads[2]) if self.player_id == 0 else left_crads[0]
    min_oppo_crads = min(payload3['left'][lrole_id], payload3['left'][llrole_id])
    round_penalty = 17 - 12 * min_oppo_crads / 20  # 惩罚值调整为与敌人最少手牌数负线性相关

    if not last_move:
        if role_id == 0:  # 地主
            round_penalty += 7
        elif role_id == 1:  # 地主下家
            round_penalty += 5
        else:  # 地主上家
            round_penalty += 3

    if role_id == 2 and not last_move:  # 队友没要地主牌
        round_penalty += 5
    if role_id == 1 and not last_move:  # 地主没要队友牌
        round_penalty -= 8

    # 寻找最优出牌
    best_move = None
    max_value = -np.inf
    for i in range(len(combs)):
        # 手牌总分
        total_value = sum([cards_value[x] for x in combs[i]])
        # small_num = 0
        # for j in range(0, len(combs[i])):
        #     if j > 0 and action_space[j][0] not in ["2", "R", "B"]:
        #         small_num += 1
        # total_value -= small_num * round_penalty
        small_num = hand_card[-1] + hand_card[-2] + hand_card[-3]
        small_num = (len(combs[i]) - small_num)  # 如果一手牌为小牌, 需要加上惩罚值, 所以要统计小牌数量
        total_value -= small_num * round_penalty

        # 手里有火箭和另一手牌
        if len(combs[i]) == 3 and combs[i][0] == 0 or len(combs[i]) == 2:
            if cards_value[combs[i][-1]] == 12 or cards_value[combs[i][-2]] == 12:
                print('*****rule  火箭直接走')
                return [0] * 13 + [1, 1], None

        # 下家农民手里只有一张牌,送队友走
        # if role_id == 1 and sum(self.game.players[2].get_hand_card()) == 1 and not last_move:
        if role_id == 1 and payload3['left'][2] == 1 and not last_move:
            for i, j in enumerate(hand_card):
                if j != 0:
                    tem = [0] * 15
                    tem[i] = 1
                    print('******rule  下家农民手里只有一张牌,送队友走')
                    return tem, None

        # 队友出大牌能走就压
        if role_id == 2 and len(combs[i]) == 3 and combs[i][0] == 0:
            if action_space[combs[i][1]] in dapai and (fine_mask is None or fine_mask[i, 1] == True):
                print('******rule  队友出大牌能走就压')
                best_move = combs[i][1]
                break
            elif action_space[combs[i][2]] in dapai and (fine_mask is None or fine_mask[i, 2] == True):
                print('******rule  队友出大牌能走就压')
                best_move = combs[i][2]
                break

        # 队友出大牌走不了就不压
        if role_id == 2 and last_pid == 1 and sorted(last_move) in dapai:
            print('******rule  队友出大牌走不了就不压')
            best_move = 0
            break

        for j in range(0, len(combs[i])):
            # Pass 得分
            if combs[i][j] == 0 and min_oppo_crads > 8:
                if total_value > max_value:
                    max_value = total_value
                    best_move = 0
                    # print('pass得分',max_value,end='   //   ')
            # 出牌得分
            elif combs[i][j] > 0 and (fine_mask is None or fine_mask[i, j] == True):  # 枚举非pass且fine_mask为True的出牌
                # 特判只有一手
                if len(combs[i]) == 1 or len(combs[i]) == 2 and combs[i][0] == 0:
                    max_value = np.inf
                    best_move = combs[i][-1]
                    break

                move_value = total_value - cards_value[combs[i][j]] + round_penalty

                # 手里有当前最大牌和另一手牌
                if len(combs[i]) == 3 and combs[i][0] == 0 or len(combs[i]) == 2:
                    if combs[i][j] > maxcard(payload3['hand_card'], lrole_id, llrole_id) and combs[i][j] <= 15:
                        move_value += 100

                # 地主只剩一张牌时别出单牌
                # if role_id != 0 and sum(self.game.players[0].get_hand_card()) == 1:
                if role_id != 0 and payload3['left'][0] == 1:
                    if combs[i][j] <= maxcard(payload3['hand_card'], lrole_id, llrole_id):
                        move_value -= 100

                # 农民只剩一张牌时别出单牌
                if role_id == 0 and (payload3['left'][1] == 1 or payload3['left'][2] == 1):
                    if combs[i][j] <= maxcard(payload3['hand_card'], lrole_id, llrole_id):
                        move_value -= 100

                if move_value > max_value:
                    max_value = move_value
                    best_move = combs[i][j]
        if best_move is None:
            best_move = 0

    # 最优出牌
    best_cards = action_space[best_move]
    move = [best_cards.count(x) for x in card_list]
    # print('出牌得分', max_value)
    # 输出选择的牌组
    # print("\nbest comb: ")
    # for m in best_comb:
    #     print(action_space[m], cards_value[m])
    # 输出 player i [手牌] // [出牌]
    # print("Player {}".format(role_id), ' ', Card.visual_card(hand_card), end=' // ')
    # print(Card.visual_card(move))
    return move

if __name__ == "__main__":
    payload = {
        'role_id': 1,  # 0代表地主上家，1代表地主，2代表地主下家
        'last_taken': {  # 更改处
            0: [],
            1: [9, 9, 9, 6],
            2: [],
        },
        'cur_cards': [17, 16, 15, 14, 14, 12, 10],  # 无需保持顺序
        'history': {  # 各家走过的牌的历史The environment
            0: [],
            1: [5, 5, 5, 4, 4, 3, 3, 3, 3, 9, 9, 9, 6],
            2: [11, 11, 11, 8, 8],
        },
        'left': {  # 各家剩余的牌
            0: 17,
            1: 7,
            2: 12,
        },
        'hand_card': {
            0: [15, 14, 13, 13, 12, 10, 10, 9, 8, 8, 7, 7, 7, 6, 6, 6, 4],
            1: [17, 16, 15, 14, 14, 12, 10],
            2: [15, 15, 14, 13, 13, 12, 12, 11, 10, 7, 5, 4],
        },
        'debug': False,  # 是否返回debug
    }
    import time

    start = time.time()
    print(choose(payload))
    end = time.time()
    print(end - start)


"""
Created on Mon Sep 16 18:31:35 2013
PHYS 613, Assignment 3
Nick Crump
"""

# Problem 2 (EBB2)
"""
Generating the density of states (DOS) by finding energy eigenvalues of
a particle in a 2D infinite square well.
"""

import numpy as np
from math import exp
from LeastSquares import gaussNewton3
import matplotlib.pyplot as plt

# Part A
# generate the lowest 500,000 energy eigenvalues from E(nx,ny) = nx**2 + ny**2
# ----------------------------------------------------------------------------
nstates = 500000  # keep this many states
nxy = 1000        # iterate over this many to make sure to get 500,000 lowest
states = []       # stores all E(nx,ny)

# iterate to get all E(nx,ny)
for i in range(1,nxy):
    for j in range(1,nxy):
        s = i**2 + j**2
        states.append(s)

# sort E(nx,ny) list and keep only lowest 500,000
states = np.sort(states)
states = states[0:nstates]

# plot histogram of density of states (DOS) vs energy
plt.figure(1)
plt.hist(states,bins=20,label='2D Infinite Well')
plt.xlabel('Energy')
plt.ylabel('Density of States')
plt.legend()

# Part B & C
# find energy differences E(i+1)-E(i) and E(i+2)-E(i) up to i = 100000
# ----------------------------------------------------------------------------
# keep duplicates (degeneracies) from array of energy states
num = 100000

# get E(i+1) - E(i)
delta1 = [states[i+1] - states[i] for i in range(num)]
# get E(i+2) - E(i)
delta2 = [states[i+2] - states[i] for i in range(num)]

# plot histogram of energy differences vs energy
plt.figure(2)
plt.subplot(211)
# gets the histogram data and plots histogram
n1, bins1, patches1 = plt.hist(delta1,bins=20,label='First Neighboring Levels')
plt.xlim(0,20)
plt.ylabel(r'Frequency of $\Delta E_{1}$')
plt.legend()

plt.subplot(212)
# gets the histogram data and plots histogram
n2, bins2, patches2 = plt.hist(delta2,bins=20,label='Second Neighboring Levels')
plt.xlim(0,20)
plt.xlabel(r'$\Delta\ $ Energy')
plt.ylabel(r'Frequency of $\Delta E_{2}$')
plt.legend()

# Part D
# fitting parameters of a known function to distributions
# ----------------------------------------------------------------------------
# guess at parameters for exponential decay f = A*exp(-Bx) to fit dataset 1
A1 = 75600
B1 = 1.1
x1 = np.linspace(min(bins1),max(bins1),1000)
exp1 = [A1*exp(-B1*i) for i in x1]

# guess at parameters for exponential decay f = A*exp(-Bx) to fit dataset 1
A2 = 52100
B2 = 0.7
x2 = np.linspace(min(bins2),max(bins2),1000)
exp2 = [A2*exp(-B2*i) for i in x2]

# plot histogram of energy differences vs energy with exponential fits
plt.figure(3)
plt.subplot(211)
plt.hist(delta1,bins=20,label='First Neighboring Levels')
plt.plot(x1+0.7,exp1,'r-',linewidth=3,label='Exponential Fit')
plt.xlim(0,20)
plt.ylabel(r'Frequency of $\Delta E_{1}$')
plt.legend()

plt.subplot(212)
plt.hist(delta2,bins=20,label='Second Neighboring Levels')
plt.plot(x2+0.7,exp2,'r-',linewidth=3,label='Exponential Fit')
plt.xlim(0,20)
plt.xlabel(r'$\Delta\ $ Energy')
plt.ylabel(r'Frequency of $\Delta E_{2}$')
plt.legend()


# -*- coding: utf-8 -*-
# from gevent import monkey
# monkey.patch_all()
import codecs
import json
import os
import random

import flask
from flask import Flask, jsonify
from flask import request
from flask import send_from_directory
from gevent import wsgi

# Подготавливаем tenants.json
tenants_json = os.path.join('.', 'data', 'tenants.json')
if not os.path.exists(tenants_json):
    f = os.path.join('.', 'data', 'tenats.txt')
    with codecs.open(f, 'r', "utf-8") as file:
        pairs = [ line.split('-') for line in file.readlines()]
        tenants = [ dict(id=it[0].strip(), title=it[1].strip(), floor=i % 3 + 1, geometry=None) for i, it in enumerate(pairs) ]
        with codecs.open(tenants_json, 'w', 'utf-8') as json_file:
            json_file.write(json.dumps(tenants, ensure_ascii=False))

graph_json = os.path.join('.','data', 'graph.json')
if not os.path.exists(graph_json):
    with codecs.open(graph_json, 'w', 'utf-8') as json_file:
        graph = { "points": [], "graph": {}}
        json_file.write(json.dumps(graph, ensure_ascii=False))

app = Flask(__name__, static_folder='')

@app.route('/')
def index():
  return app.send_static_file('index.html')

@app.route('/site')
def site():
  return app.send_static_file('site.html')

@app.route('/js/<path:path>')
def send_js(path):
    return send_from_directory('js', path)

@app.route('/css/<path:path>')
def send_css(path):
    return send_from_directory('css', path)

@app.route('/data/<path:path>')
def send_data(path):
    return send_from_directory('data', path)

@app.route('/tenants/')
def tenants():
    with codecs.open(tenants_json, 'r', "utf-8") as file:
        return file.read()

@app.route('/tenants/<id>', methods=['POST'])
def post_tenant(id):
    geometry =  request.data
    with codecs.open(tenants_json, 'r', "utf-8") as file:
        tenants = json.load(file)
        tenant = next( ( t for t in tenants if t['id'] == id), None )
        tenant['geometry'] = json.loads(geometry) if geometry else  None
        with codecs.open(tenants_json, 'w', 'utf-8') as json_file:
            json_file.write(json.dumps(tenants, ensure_ascii=False))

    return 'ok'

@app.route('/graph/')
def graph():
    with codecs.open(graph_json, 'r', "utf-8") as file:
        return file.read()

@app.route('/graph/', methods=['POST'])
def post_graph():
    graph = request.data
    graph = json.loads(graph)
    with codecs.open(graph_json, 'w', "utf-8") as json_file:
        json_file.write(json.dumps(graph, ensure_ascii=False, indent=2))
    return 'ok'

@app.route('/point_types/')
def point_types():
    return flask.jsonify([
        { "id": "path", "name": "Проход"},
        { "id": "entry", "name": "Точка входа"},
        { "id": "escalator", "name": "Экскалатор"},
        { "id": "lift", "name": "Лифт"},
        { "id": "stairs", "name": "Лестница"},
        { "id": "terminal", "name": "Терминал"},
        { "id": "atm", "name": "Банкомат"},
        { "id": "wc", "name": "Туалет"},
        { "id": "medpunkt", "name": "Медпункт"},
        { "id": "info", "name": "Информация"}
    ]);

server = wsgi.WSGIServer(('127.0.0.1', 5000), application=app, log=None)
server.serve_forever()


import os

import torch
import torch.nn.functional as F
from torch.utils.tensorboard import SummaryWriter

from src.models.network import Net
from src.data.preprocess import testset
from src.constants import MODEL_DIR_PATH, CLASSES

class Evaluator:
    def __init__(self):
        self.load(os.path.join(MODEL_DIR_PATH, 'model.pt'))

        self.testloader = torch.utils.data.DataLoader(
            testset, batch_size=4, shuffle=False
        )
        self.writer = SummaryWriter('runs/evaluate')

    def load(self, checkpoint_path):
        self.net = Net()
        self.net.load_state_dict(torch.load(checkpoint_path, map_location=lambda storage, loc: storage))

    def evaluate(self):
        class_probs = []
        class_label = []
        with torch.no_grad():
            for data in self.testloader:
                images, labels = data
                output = self.net(images)
                class_probs_batch = [F.softmax(el, dim=0) for el in output]

                class_probs.append(class_probs_batch)
                class_label.append(labels)

        test_probs = torch.cat([torch.stack(batch) for batch in class_probs])
        test_label = torch.cat(class_label)

        return test_label, test_probs

    def add_pr_curve_tensorboard(self, global_step=0):
        test_label, test_probs = self.evaluate()

        for class_index in range(len(CLASSES)):
            tensorboard_truth = test_label == class_index
            tensorboard_probs = test_probs[:, class_index]

            self.writer.add_pr_curve(
                CLASSES[class_index],
                tensorboard_truth,
                tensorboard_probs,
                global_step=global_step
            )
            self.writer.close()


from typing import List, Optional, Union

import hvplot
import pandas

from .plot import Plot

class ParetoFront(Plot):
    """
    This class is used to create a pareto frontier plot of inference time v/s winrate, by framework.

    Attributes
    ----------
    plot_title: str,
        title of the plot on the dashboard website
    df_process: hvplot.Interactive,
        interactive pandas dataframe that is used to create the plot
        this should be the dataset of all frameworks aggregated across all datasets
    plot_type: str,
        type of hvplot. hvplot, table, pareto
    x_axis: Optional[Union[str, List[str]]],
        values to plot on x-axis
    y_axis: Optional[Union[str, List[str]]],
        values to plot on y-axis
    xlabel: str,
        label of x-axis
    ylabel: str,
        label of y-axis
    label_rot: int,
        rotation value of labels on axes

    Usage
    ------
    >>> pareto_front = ParetoFront("pareto plot", all_frameworks_df, "pareto", x_axis=TIME_INFER_S_RESCALED, y_axis=WINRATE)

    You can now call the `.plot()` method on this object to render the table as a Panel object on the dashboard website.

    """

    def __init__(
        self,
        plot_title: str,
        df_process: hvplot.Interactive,
        plot_type: str,
        x_axis: Optional[Union[str, List[str]]] = None,
        y_axis: Optional[Union[str, List[str]]] = None,
        graph_type: str = "bar",
        xlabel: str = "",
        ylabel: str = "",
        label_rot: int = 90,
    ) -> None:
        super().__init__(
            plot_title,
            df_process,
            plot_type,
            x_axis,
            y_axis,
            graph_type,
            xlabel,
            ylabel,
            label_rot,
        )


import argparse
import os
from sys import exit
from config import Config
from mangatracker import main

# Allow __main__ to run CLI without PySide2 installed
try:
    from mangatracker_gui import gui_main
    pyside2_installed = True
except ImportError:
    pyside2_installed = False

    def gui_main():
        print("PySide2 not installed, starting CLI")
        main()

def start_cli():
    main()
    exit()

def start_gui():
    gui_main()
    exit()

def start_default():
    """Starts default user interface as defined in config.ini"""
    if Config().default_to_gui and pyside2_installed:
        start_gui()
    else:
        start_cli()

if __name__ == "__main__":
    os.chdir(os.path.dirname(os.path.realpath(__file__)))

    parser = argparse.ArgumentParser(prog="MangaTracker",
                                     description="Track a manga collection.")
    group = parser.add_mutually_exclusive_group()
    group.add_argument("-g",
                       "--gui",
                       action="store_true",
                       help="Start GUI (Requires PySide2)")
    group.add_argument("-c",
                       "--cli",
                       action="store_true",
                       help="Start CLI")

    args = parser.parse_args()

    if args.gui:
        start_gui()
    if args.cli:
        start_cli()

    start_default()


from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.http import HttpResponseRedirect, HttpResponse, JsonResponse
from django.urls import reverse_lazy
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator
from accounts.models import User, Student
from institution.models import Session, Trimester
from course.models import Course
from accounts.decorators import lecturer_required, student_required
from .models import UsersCourses, Result
from .models import *

@login_required
@lecturer_required
def provisional_score(request):
    current_session = Session.objects.get(is_current_session=True)
    current_trimester = get_object_or_404(Trimester, is_current_trimester=True, session=current_session)
    courses = Course.objects.filter(allocated_course__lecturer__pk=request.user.id).filter(trimester=current_trimester)
    context = {
        "current_session": current_session,
        "current_trimester": current_trimester,
        "courses": courses,
    }
    return render(request, 'scores/provisional_score.html', context)

@login_required
@lecturer_required
def lecturer_confirm_score(request, id):
    """
    Shows a page where a lecturer will add score for students that are taking courses allocated to him
    in a specific trimester and session
    """
    current_session = Session.objects.get(is_current_session=True)
    current_trimester = get_object_or_404(Trimester, is_current_trimester=True, session=current_session)
    if request.method == 'GET':
        courses = Course.objects.filter(allocated_course__lecturer__pk=request.user.id).filter(
            trimester=current_trimester)
        course = Course.objects.get(pk=id)
        students = UsersCourses.objects.filter(course__allocated_course__lecturer__pk=request.user.id).filter(
            course__id=id).filter(course__trimester=current_trimester)
        context = {
            "title": "Submit Score",
            "courses": courses,
            "course": course,
            "students": students,
            "current_session": current_session,
            "current_trimester": current_trimester,
        }
        return render(request, 'scores/lecturer_confirm_score.html', context)

    if request.method == 'POST':
        ids = ()
        data = request.POST.copy()
        data.pop('csrfmiddlewaretoken', None)  # remove csrf_token
        for key in data.keys():
            ids = ids + (str(key),)  # gather all the all students id (i.e the keys) in a tuple
        for s in range(0, len(ids)):  # iterate over the list of student ids gathered above
            student = UsersCourses.objects.get(id=ids[s])
            courses = Course.objects.filter(level=student.student.level).filter(program__pk=student.student.department.id).filter(
                trimester=current_trimester)
            total_credit_in_trimester = 0
            for i in courses:
                if i == courses.count():
                    break
                else:
                    total_credit_in_trimester += int(i.credit)
            score = data.getlist(ids[s])
            print(score, score[0])
            assignment = score[0]
            obj = UsersCourses.objects.get(pk=ids[s])  # get the current student data
            obj.assignment = assignment  # set current student assignment score
            obj.total = obj.get_score(assignment=assignment)
            obj.grade = obj.get_marked_grade(total=obj.total)
            obj.point = obj.get_point(grade=obj.grade)
            obj.comment = obj.get_comment(grade=obj.grade)
            obj.save()
            try:
                a = Result.objects.get(student=student.student, trimester=current_trimester, session=current_session, level=student.student.level)
                a.score = obj.total
                a.comment = obj.comment
                a.save()
            except:
                Result.objects.get_or_create(student=student.student, comment=obj.comment, trimester=current_trimester,
                                             session=current_session, level=student.student.level)

        messages.success(request, 'Score Updated. ')
        return HttpResponseRedirect(reverse_lazy('lecturer_confirm_score', kwargs={'id': id}))
    return HttpResponseRedirect(reverse_lazy('lecturer_confirm_score', kwargs={'id': id}))

@login_required
@student_required
def provisional_result(request):
    student = Student.objects.get(student__pk=request.user.id)
    assess_courses = UsersCourses.objects.filter(student__student__pk=request.user.id).filter(course__level=student.level)
    assess_results = Result.objects.filter(student__student__pk=request.user.id)

    result_set = set()

    for result in assess_results:
        result_set.add(result.session)

    sorted_result = sorted(result_set)

    total_first_trimester_credit = 0
    total_sec_trimester_credit = 0
    for i in assess_courses:
        if i.course.trimester == "First":
            total_first_trimester_credit += int(i.course.credit)
        if i.course.trimester == "Second":
            total_sec_trimester_credit += int(i.course.credit)

    past_gp = 0
    for i in assess_results:
        past_level = i.level
        try:
            a = Result.objects.get(student__student__pk=request.user.id, level=past_level, trimester="Second")
            past_gp = a.cgpa
            break
        except:
            past_gp = 0

    context = {
        "courses": assess_courses,
        "results": assess_results,
        "sorted_result": sorted_result,
        "student": student,
        'total_first_trimester_credit': total_first_trimester_credit,
        'total_sec_trimester_credit': total_sec_trimester_credit,
        'total_first_and_second_trimester_credit': total_first_trimester_credit + total_sec_trimester_credit,
        "previousCGPA": past_gp,
    }

    return render(request, 'scores/provisional_result.html', context)

@login_required
@student_required
def com_result(request):
    student = Student.objects.get(student__pk=request.user.id)
    assess_courses = UsersCourses.objects.filter(student__student__pk=request.user.id, course__level=student.level)
    assess_result = Result.objects.filter(student__student__pk=request.user.id)

    context = {
        "courses": assess_courses,
        "scores": assess_result,
        "student": student,
    }

    return render(request, 'scores/com_result.html', context)


#!/usr/bin/python

from time import sleep, strftime, localtime
from Adafruit_CharLCDPlate import Adafruit_CharLCDPlate
import RPi.GPIO as GPIO
import os
import sys
from jsonreader2 import flat

lcd = Adafruit_CharLCDPlate()
lcd.backlight(lcd.ON)

GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)

GPIO.setup(16, GPIO.OUT)
GPIO.setup(18, GPIO.OUT)
GPIO.setup(22, GPIO.OUT)
GPIO.setup(24, GPIO.OUT)
GPIO.setup(26, GPIO.OUT)

GPIO.output(16, False)
GPIO.output(18, False)
GPIO.output(22, False)
GPIO.output(24, False)
GPIO.output(26, False)
sleep(1)

while(1==1):
 #turn them on
 GPIO.output(18, True)
 sleep(0.05)
 GPIO.output(18, False)
 sleep(0.08)
 GPIO.output(18, True)
 sleep(1.5)
 GPIO.output(26, True)
 sleep(0.5)
 GPIO.output(22, True)
 sleep(0.7)
 GPIO.output(24, True)
 sleep(0.3)

 blink = 0
 while (blink < 10):
  GPIO.output(16, True)
  sleep(0.06)
  GPIO.output(16, False)
  sleep(0.06)
  blink = blink +1

 # Clear display and show some status messages
 #loop=0;
 lcd.backlight(lcd.RED)
 lcd.clear()
 lcd.message("nugg.ad \ntargetometer")
 sleep(3)
 lcd.clear()
 lcd.message(strftime("%a, %d %b %Y \n %H:%M:%S", localtime()))
 sleep(3)
 lcd.clear()

 #check internet and IP adress
 import socket
 ip = ""
 try:
  s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  s.connect(('nugg.ad', 0))
  ip = s.getsockname()[0]
  if ip != "":
   lcd.message("IP-Adresse:\n" + ip)
   sleep(2)
  else:
   lcd.message("connection error")
  sleep(2)
  lcd.clear()
 except:
  pass

#display some kpis from the list
 for index  in flat:
  lcd.message(index[0] + "\n" + str(index[1]))
  sleep(3)
  lcd.clear()

 lcd.message("Enjoy your\n weekend")
 sleep(3)
 lcd.clear()
 sleep(0.2)
 lcd.message("my\n friend")
 sleep(0.7)
 lcd.clear()
 #loop = loop + 1

 GPIO.output(16, False)
 GPIO.output(18, False)
 GPIO.output(22, False)
 GPIO.output(24, False)
 GPIO.output(26, False)

 t = 0
 while(t < 60):
  lcd.message(strftime("%a, %d %b %Y \n %H:%M:%S        ", localtime()))
  sleep(1)
  t = t+1

lcd.backlight(lcd.OFF)

GPIO.cleanup()


name = input("Enter file:")
file = open(name)
counts = dict()

for line in file:
    if line.startswith('From ') :
        words = line.split()
        time = words[5]
        hours = time[:2]
        counts[hours] = counts.get(hours,0) + 1

for key, val in sorted(counts.items()):
    print (key, val)


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

import numpy as np
import tensorflow as tf
import tflearn
from tflearn.layers.core import input_data, dropout, fully_connected
from tflearn.layers.conv import conv_2d, max_pool_2d
from tflearn.layers.normalization import local_response_normalization
from tflearn.layers.estimator import regression

def cnn(run_label, X, Y, testX, testY):

    run_id = run_label + '_convnet_ern'
    time_point_number = len(X[0])
    channel_number = len(X[0][1])

    X = X.reshape([-1, time_point_number, channel_number, 1])
    testX = testX.reshape([-1, time_point_number, channel_number, 1])

    # Building convolutional network
    network = input_data(shape=[None, time_point_number, channel_number, 1], name='input')
    network = conv_2d(network, 32, 3, activation='relu', regularizer="L2")
    network = max_pool_2d(network, 2)
    network = local_response_normalization(network)
    network = conv_2d(network, 64, 3, activation='relu', regularizer="L2")
    network = max_pool_2d(network, 2)
    network = local_response_normalization(network)
    network = fully_connected(network, 128, activation='tanh')
    network = dropout(network, 0.8)
    network = fully_connected(network, 256, activation='tanh')
    network = dropout(network, 0.8)
    network = fully_connected(network, 2, activation='softmax')
    network = regression(network, optimizer='adam', learning_rate=0.01,
                         loss='categorical_crossentropy', name='target')

    # Training
    model = tflearn.DNN(network, tensorboard_dir='..\\out\\tflearn_logs', tensorboard_verbose=3)
    model.fit({'input': X}, {'target': Y}, n_epoch=20,
              validation_set=({'input': testX}, {'target': testY}),
              snapshot_step=100, show_metric=True, run_id=run_id)

def test(features, labels):

    features_placeholder = tf.placeholder(features.dtype, features.shape)
    labels_placeholder = tf.placeholder(labels.dtype, labels.shape)

    dataset = tf.data.Dataset.from_tensor_slices((features_placeholder, labels_placeholder))

    iterator = dataset.make_initializable_iterator()

    sess = tf.Session()
    sess.run(iterator.initializer, feed_dict={features_placeholder: features,
                                              labels_placeholder: labels})

    x = tf.constant([[1], [2], [3], [4]], dtype=tf.float32)
    y_true = tf.constant([[0], [-1], [-2], [-3]], dtype=tf.float32)

    linear_model = tf.layers.Dense(units=1)

    y_pred = linear_model(x)

    sess = tf.Session()
    init = tf.global_variables_initializer()
    sess.run(init)

    print(sess.run(y_pred))

    loss = tf.losses.mean_squared_error(labels=y_true, predictions=y_pred)

    print(sess.run(loss))

    optimizer = tf.train.GradientDescentOptimizer(0.01)
    train = optimizer.minimize(loss)

    for i in range(1000):
        _, loss_value = sess.run((train, loss))
        print(loss_value)

    print(sess.run(y_pred))


import pandas as pd
from settings import FEATURE_CHIN_ENG_DICT
import matplotlib.pyplot as plt
import numpy as np

path = '/media/reid/ext_disk1/blue_alage/dushu/geography_point.csv'

df = pd.read_csv(path)

lon_min, lon_max = df['lon'].min(), df['lon'].max()
lat_min, lat_max = df['lat'].min(), df['lat'].max()
range_step = 0.001

grid_lon = np.arange(lon_min, lon_max, range_step)
grid_lat = np.arange(lat_min, lat_max, range_step)

result = np.array([[(xi, yj) for yj in grid_lat] for xi in grid_lon])

whole_data = result.reshape(-1, 2)

lake_data = df[['lon', 'lat']].to_numpy()

result = np.any(np.all(whole_data[:, np.newaxis, :] == lake_data, axis=2), axis=1).astype(int)
ss = np.intersect1d(whole_data, lake_data)

fig, ax = plt.subplots()

# ax.scatter(combined_coordinates[:, 0], combined_coordinates[:, 1], color='green')

df.plot(kind='scatter', x='lon', y='lat', ax=ax)

plt.legend()

plt.show()


students = [
    {"name": "Sarah", "hometown": "Detroit", "favorite_food": "sushi"},
    {"name": "Fred", "hometown": "Ann Arbor", "favorite_food": "pizza"},
    {"name": "Mike","hometown": "Sterling Heights", "favorite_food":"tacos" },
    {"name": "Aria", "hometown": "Grand Rapids", "favorite_food": "burgers"}
]
while True:
    action = input("Please select which action you'd like to do: add, view, or quit ")
    if action == "add":
        def get_new_student():
            student = {}
            name = input("Enter name: ")
            hometown = input("Enter hometown: ")
            favorite_food = input("Enter favorite food: ")
            student['name'] = name
            student['hometown'] = hometown
            student['favorite food'] = favorite_food
            return student
        new_student = get_new_student()
        students.append(new_student)
        print(students)
    elif action == "view":
        def list_names(students):
            for student in students:
                print(student["name"])
        list_names(students)
        number_of_students = len(students)
        student_choice = int(input(f"Welcome! Which student would you like to learn more about? Enter number 1 through {number_of_students} "))
        student = students[student_choice-1]
        information = input("Enter hometown or favorite food ")
        if information == "hometown":
            print(f"{student['name']} is from {student['hometown']}")
            continue
        elif information == "favorite food":
            print(f"{student['name']} favorite food is {student['favorite_food']}")
        else:
            print("Invalid choice. Try again.")

    elif action == "quit":
        print("Good bye!")
        break
    else:
        print("Invalid. Try again.")


import unittest
import os
import pkg_resources
import sys

try:
    # Python 3.3 forward includes the mock module
    from unittest import mock
    could_import_mock = True
except ImportError:
    # Fallback for older python (not included in standard library)
    try:
        import mock
        could_import_mock = True
    except ImportError:
        # Mock appears to not be installed
        could_import_mock = False

try:
    # Python3:  use importlib.reload
    from importlib import reload as import_reload
except ImportError:
    # Python2:
    from imp import reload as import_reload

import opentimelineio as otio
from tests import baseline_reader

@unittest.skipIf(
    not could_import_mock,
    "mock module not found. Install mock from pypi or use python >= 3.3."
)
class TestSetuptoolsPlugin(unittest.TestCase):
    def setUp(self):
        # Get the location of the mock plugin module metadata
        mock_module_path = os.path.join(
            baseline_reader.path_to_baseline_directory(),
            'plugin_module',
        )
        self.mock_module_manifest_path = os.path.join(
            mock_module_path,
            "otio_jsonplugin",
            "plugin_manifest.json"
        )

        # Create a WorkingSet as if the module were installed
        entries = [mock_module_path] + pkg_resources.working_set.entries

        self.sys_patch = mock.patch('sys.path', entries)
        self.sys_patch.start()

        working_set = pkg_resources.WorkingSet(entries)

        # linker from the entry point
        self.entry_patcher = mock.patch(
            'pkg_resources.iter_entry_points',
            working_set.iter_entry_points
        )
        self.entry_patcher.start()

    def tearDown(self):
        self.sys_patch.stop()
        self.entry_patcher.stop()
        if 'otio_mockplugin' in sys.modules:
            del(sys.modules['otio_mockplugin'])

    def test_detect_plugin(self):
        """This manifest uses the plugin_manifest function"""

        # Create a manifest and ensure it detected the mock adapter and linker
        man = otio.plugins.manifest.load_manifest()

        # Make sure the adapter is included in the adapter list
        adapter_names = [adapter.name for adapter in man.adapters]
        self.assertIn('mock_adapter', adapter_names)

        # Make sure the linker is included in the linker list
        linker_names = [linker.name for linker in man.media_linkers]
        self.assertIn('mock_linker', linker_names)

        # Make sure adapters and linkers landed in the proper place
        for adapter in man.adapters:
            self.assertIsInstance(adapter, otio.adapters.Adapter)

        for linker in man.media_linkers:
            self.assertIsInstance(linker, otio.media_linker.MediaLinker)

    def test_pkg_resources_disabled(self):
        os.environ["OTIO_DISABLE_PKG_RESOURCE_PLUGINS"] = "1"
        import_reload(otio.plugins.manifest)

        # detection of the environment variable happens on import, force a
        # reload to ensure that it is triggered
        with self.assertRaises(AssertionError):
            self.test_detect_plugin()

        # remove the environment variable and reload again for usage in the
        # other tests
        del os.environ["OTIO_DISABLE_PKG_RESOURCE_PLUGINS"]
        import_reload(otio.plugins.manifest)

    def test_detect_plugin_json_manifest(self):
        # Test detecting a plugin that rather than exposing the plugin_manifest
        # function, just simply has a plugin_manifest.json provided at the
        # package top level.
        man = otio.plugins.manifest.load_manifest()

        # Make sure the adapter is included in the adapter list
        adapter_names = [adapter.name for adapter in man.adapters]
        self.assertIn('mock_adapter_json', adapter_names)

        # Make sure the linker is included in the linker list
        linker_names = [linker.name for linker in man.media_linkers]
        self.assertIn('mock_linker_json', linker_names)

        # Make sure adapters and linkers landed in the proper place
        for adapter in man.adapters:
            self.assertIsInstance(adapter, otio.adapters.Adapter)

        for linker in man.media_linkers:
            self.assertIsInstance(linker, otio.media_linker.MediaLinker)

        self.assertTrue(
            any(
                True for p in man.source_files
                if self.mock_module_manifest_path in p
            )
        )

    def test_deduplicate_env_variable_paths(self):
        "Ensure that duplicate entries in the environment variable are ignored"

        # back up existing manifest
        bak_env = os.environ.get('OTIO_PLUGIN_MANIFEST_PATH')

        relative_path = self.mock_module_manifest_path.replace(os.getcwd(), '.')

        # set where to find the new manifest
        os.environ['OTIO_PLUGIN_MANIFEST_PATH'] = os.pathsep.join(
            (
                # absolute
                self.mock_module_manifest_path,

                # relative
                relative_path
            )
        )

        result = otio.plugins.manifest.load_manifest()
        self.assertEqual(
            len(
                [
                    p for p in result.source_files
                    if self.mock_module_manifest_path in p
                ]
            ),
            1
        )
        if relative_path != self.mock_module_manifest_path:
            self.assertNotIn(relative_path, result.source_files)

        if bak_env:
            os.environ['OTIO_PLUGIN_MANIFEST_PATH'] = bak_env
        else:
            del os.environ['OTIO_PLUGIN_MANIFEST_PATH']

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


from datetime import datetime, timedelta

import pandas as pd
from pymongo import MongoClient

from misc.inserter import get_actual_cards_info, wh_code
from misc.pathManager import PathManager

try:
    conn = MongoClient()
    db = conn["gram_base"]
    print("Connected successfully!!!")
except:
    print("Could not connect to MongoDB")

def add_all_old_reports_to_db():
    actual_cards_data = get_actual_cards_info()

    barcodes = actual_cards_data[0]
    articles = actual_cards_data[1]
    sizes = actual_cards_data[2]

    for day in range(13, 100):
        try:
            data_day_ago = datetime.now() - timedelta(days=day)
            new_time = data_day_ago.strftime("%d-%m-%Y")
            print(new_time)
            data = pd.read_excel(
                PathManager.get(f'excels/speed_calc/sales_stats_{new_time}.xlsx'))
            data_arrayed = data.values.tolist()

            for excel_line in data_arrayed:
                barcode = excel_line[1]
                wh_name = excel_line[0]
                wh_code_num = int(wh_code(wh_name))
                print(wh_code_num)
                article = articles[barcodes.index(barcode)]
                print(article)
                size = sizes[barcodes.index(barcode)]
                insert_any_day_doc(barcode, excel_line[2], wh_code_num, article, size, new_time)
                print(barcode, excel_line[2], wh_code_num, article, size, new_time)
                for qnt in excel_line[3:-4]:
                    add_sell_speed(barcode, qnt, wh_code_num, new_time)
        except Exception as e:
            print(e)

def add_all_old_reports_to_db_new_format():
    for day in range(1, 13):
        try:
            data_day_ago = datetime.now() - timedelta(days=day)
            new_time = data_day_ago.strftime("%d-%m-%Y")
            print(new_time)
            data = pd.read_excel(
                PathManager.get(f'excels/speed_calc/sales_stats_{new_time}.xlsx'))
            data_arrayed = data.values.tolist()

            for excel_line in data_arrayed:
                wh_code_num = excel_line[0]
                barcode = excel_line[1]
                article = excel_line[2]
                size = excel_line[3]
                insert_any_day_doc(barcode, excel_line[4], wh_code_num, article, size, new_time)
                for qnt in excel_line[4:-4]:
                    add_sell_speed(barcode, qnt, wh_code_num, new_time)
        except Exception as e:
            print(e)

def insert_any_day_doc(barcode, qnt, wh_code_number, article, size, date):
    speed_data = {
        "date": date,
        "quantity": [qnt, qnt],
        "barcode": barcode,
        "article": article,
        "size": size,
        "wh_code": wh_code_number
    }
    db.sell_speed.insert_one(speed_data)

def insert_todays_doc(barcode, qnt, wh_code, article, size):
    speed_data = {
        "date": datetime.now().strftime('%d-%m-%Y'),
        "quantity": [qnt],
        "barcode": barcode,
        "article": article,
        "size": size,
        "wh_code": wh_code,
        'time_stamps': [datetime.now().strftime("%H:%M")]
    }
    db.sell_speed.insert_one(speed_data)

def add_sell_speed(barcode, qnt, wh_code_param, date):
    db.sell_speed.update_one({"barcode": barcode, "wh_code": wh_code_param, "date": date}, {"$push": {"quantity": qnt, 'time_stamps': datetime.now().strftime("%H:%M")}})

def find_qnt_track(date, barcode, wh_code_num):
    data = db.sell_speed.find()

    for data1 in data:
        if data1.get('barcode') == barcode and data1.get('date') == date:
            return data1.get(wh_code_num)

# add_all_old_reports_to_db()
# add_all_old_reports_to_db_new_format()

def find_qnt_doc_in_bd(date_start, date_finish, barcode, wh_code1):
    time_delta_param = 0

    new_time = date_start
    json_arr_to_return = []
    while datetime.strptime(date_finish, "%d-%m-%Y") != datetime.strptime(new_time, "%d-%m-%Y"):
        data = db.sell_speed.find({'barcode': barcode, "date": new_time, 'wh_code': wh_code1})

        start_json = {'barcode': barcode, "date": new_time, 'wh_code': wh_code1}
        try:
            for doc in data:
                qnt = doc.get('quantity')
                time_stamps = doc.get('time_stamps')
                for time_stamp in time_stamps:
                    start_json[time_stamp] = qnt[time_stamps.index(time_stamp)]
                if len(qnt) > 0:
                    json_arr_to_return.append(start_json)
        except:
            print('Запрашиваемая дата не существует')

        time_delta_param = 1
        data_some_days_ago = datetime.strptime(new_time, "%d-%m-%Y") - timedelta(days=time_delta_param)
        new_time = data_some_days_ago.strftime("%d-%m-%Y")
        if datetime.strptime(new_time, "%d-%m-%Y") < datetime.strptime(date_finish, "%d-%m-%Y"):
            break

    unique_els = []
    for dict_item in json_arr_to_return:
        if dict_item not in unique_els:
            unique_els.append(dict_item)
    return unique_els

# print(find_qnt_doc_in_bd('12-05-2023', '01-05-2023', 2037267708361, 507))

def insert_docs():
    db.sell_speed.delete_many({'date': "17-05-2023"})

    for date1 in ['17-05-2023']:
        data = db.sell_speed.find({"date": '15-05-2023'})
        for data1 in data:
            data1.pop('_id')
            data1['date'] = date1
            print(data1)
            db.sell_speed.insert_one(data1)

# insert_docs()

def get_data_for_day():
    wh_code_list = []

    for day in range(1, 8):
        date_day_ago = datetime.now() - timedelta(days=day)
        date_formatted = date_day_ago.strftime('%d-%m-%Y')
        data = db.sell_speed.find({"date": date_formatted})
        for data1 in data:
            wh_code_list.append(data1.get('wh_code'))

    return set(wh_code_list)

def get_qnt_arr_daily(date, wh_code2,  barcode):
    data = db.sell_speed.find_one({"date": date, 'wh_code': wh_code2, 'barcode': barcode})
    # for data1 in data:
    #     print(data1)
    return data.get("quantity")

# print(get_qnt_arr_daily('15-05-2023', 507, 2037280326849))

def add_to_db_sell_report(date, barcode, wh_code_num, reg_speed, losed_speed, sum_speed, article, size):
    db.sell_speed_report.insert_one({
        'upd_date': date,
        'barcode': barcode,
        'article': article,
        'size': size,
        'warehouse_code': wh_code_num,
        'regular_speed': reg_speed,
        'losed_speed': losed_speed,
        'summary_speed': sum_speed
    })

def get_data_sell_speed():
    json_list = []
    data = db.sell_speed_report.find({"upd_date": datetime.utcnow().strftime('%d-%m-%Y')})
    count_id = 1

    for data1 in data:
        json_el = {
            "id": count_id,
            "barcode": data1.get('barcode'),
            "warehouse_code": data1.get('warehouse_code'),
            "regular_speed": data1.get('regular_speed'),
            "losed_speed": data1.get('losed_speed'),
            "summary_speed": data1.get('summary_speed'),
            'size': data1.get('size'),
            'article': data1.get('article')
        }
        count_id += 1
        json_list.append(json_el)

    return json_list

# print(get_data_sell_speed())

def sell_data_by_period(date_start, date_finish):
    new_time = date_start
    json_arr_to_return = []
    while datetime.strptime(date_finish, "%d-%m-%Y") != datetime.strptime(new_time, "%d-%m-%Y"):
        data = db.sell_speed.find({"date": new_time})
        for doc in data:
            try:
                barcode = doc.get('barcode')
                wh_code = doc.get('wh_code')
                asked_date = datetime.strptime(new_time, "%d-%m-%Y")
                last_qnt = doc.get('quantity')[len(doc.get('quantity')) - 1]
                date = datetime.strptime(new_time, "%d-%m-%Y") + timedelta(days=1)
                date_str = date.strftime("%d-%m-%Y")
                day_summary = db.sell_speed_report.find_one({"barcode": barcode, "warehouse_code": wh_code, "upd_date": date_str})
                nice_day_summary = {
                    'barcode': barcode,
                    'warehouse_code': wh_code,
                    'regular_speed': day_summary.get('regular_speed'),
                    'losed_speed': day_summary.get('losed_speed'),
                    'summary_speed': day_summary.get('summary_speed'),
                    'asked_date': asked_date.strftime("%d-%m-%Y"),
                    'last_tracked_qnt': last_qnt
                }
                json_arr_to_return.append(nice_day_summary)
            except Exception as e:
                # print(e)
                pass

        data_some_days_ago = datetime.strptime(new_time, "%d-%m-%Y") - timedelta(days=1)
        new_time = data_some_days_ago.strftime("%d-%m-%Y")
        if datetime.strptime(new_time, "%d-%m-%Y") < datetime.strptime(date_finish, "%d-%m-%Y"):
            break

    return json_arr_to_return

def get_wb_sup_tokens(company_name):
    tokens_arr = db.companys.find_one({'company_name': company_name}).get('tokens')
    sup_token = tokens_arr[0].get('suplier_token')
    wb_token = tokens_arr[0].get('wb_token')
    return f'WBToken={wb_token}; x-supplier-id={sup_token};'

def add_doc_to_fin_rep(columns, data, date):
    item = {"Date": date}
    counter = 0
    for feature in columns:
        try:
            item[feature] = data[counter]
            counter += 1
        except Exception as e:
            print(e)
    db.sell_reports.insert_one(item)

def get_sell_speed_report_data():
    return db.sell_speed.find({"date": '03-08-2023'})

def insert_sell_speed_report_data(data):
    db.sell_speed.insert_one(data)

def add_percent_to_sales():
    data = db.sell_speed_report.find({"upd_date": "15-08-2023"})
    for doc in data:
        speed = int(doc.get('regular_speed')) * 1.2
        db.sell_speed_report.update_one({"upd_date": "15-08-2023", '_id': doc.get('_id')}, {"$set": {"regular_speed": speed}})

def delete_nums():
    data = db.sell_reports.delete_many({
    'Date': '25.08.23'
})

# delete_nums()
# add_percent_to_sales()


import numpy as np
import random
from collections import defaultdict
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, LSTM, Dense, Bidirectional, Lambda, dot, RepeatVector, Concatenate
import tensorflow as tf
import tensorflow.keras.backend as K

def generate_data(k):
    if k != 'all':
        k = int(k)
    K = 10
    random.seed(1234)
    #load data
    text = []
    for l in open('slavic_all_IPA.tsv','r'):
        text.append(l.strip('\n').split('\t'))
    text = [l for l in text if l[1] != 'macedonian']
    #group by language
    lang_list = defaultdict(list)
    for l in text:
        lang_list[l[1]].append(l)
    [random.shuffle(lang_list[k]) for k in lang_list.keys()]
    lang_batches = defaultdict(list)
    for key in lang_list.keys():
        breaks = list(range(0,len(lang_list[key]),int(len(lang_list[key])/K)+1))+[len(lang_list[key])]
        for i,b in enumerate(breaks[:-1]):
            lang_batches[key].append(lang_list[key][breaks[i]:breaks[i+1]])
    train = [l for v in lang_batches.values() for i in range(K) for l in v[i] if i != k]
    test = [l for v in lang_batches.values() for i in range(K) for l in v[i] if i == k]
    langs = list(lang_list.keys())
    input_segs = sorted(set([s for l in text for s in list(l[0])]))
    output_segs = sorted(set([s for l in text for s in ['[']+list(l[3])+[']']]))
    lang_raw = defaultdict(list)
    input_raw = defaultdict(list)
    output_raw = defaultdict(list)
    lang_raw['train'] = [l[1] for l in train]
    lang_raw['test'] = [l[1] for l in test]
    input_raw['train'] = [list(l[0]) for l in train]
    input_raw['test'] = [list(l[0]) for l in test]
    output_raw['train'] = [['[']+list(l[3])+[']'] for l in train]
    output_raw['test'] = [['[']+list(l[3])+[']'] for l in test]
    X = len(input_segs)
    Y = len(output_segs)
    T_x = max([len(l) for l in input_raw['train']+input_raw['test']])
    T_y = max([len(l) for l in output_raw['train']+output_raw['test']])
    L = len(langs)
    N = len(train)
    lang_id = np.zeros([N,L],dtype='float32')
    for i,l in enumerate(lang_raw['train']):
        lang_id[i,langs.index(l)] = 1.
    enc_in  = np.zeros([N,T_x,X],dtype='float32')
    for i,l in enumerate(input_raw['train']):
        for j,s in enumerate(l):
            enc_in[i,j,input_segs.index(s)] = 1.
    dec_in  = np.zeros([N,T_y,Y],dtype='float32')
    dec_out = np.zeros([N,T_y,Y],dtype='float32')
    for i,l in enumerate(output_raw['train']):
        for j,s in enumerate(l):
            dec_in[i,j,output_segs.index(s)] = 1.
            if j > 0:
                dec_out[i,j-1,output_segs.index(s)] = 1.
    return(lang_raw,input_raw,output_raw,langs,input_segs,output_segs,X,Y,T_x,T_y,L,N,lang_id,enc_in,dec_in,dec_out)

def monotonic_alignment(args):
    h_enc,h_dec,T_x,T_y,Y,hidden_dim = args
    struc_zeros = K.expand_dims(K.cast(np.triu(np.ones([T_x,T_x])),dtype='float32'),0)
    alignment_probs = K.softmax(dot([Dense(hidden_dim)(h_enc),h_dec],axes=-1,normalize=False),-2)
    h_enc_rep = K.tile(K.expand_dims(h_enc,-2),[1,1,T_y,1])
    h_dec_rep = K.tile(K.expand_dims(h_dec,-3),[1,T_x,1,1])
    h_rep = K.concatenate([h_enc_rep,h_dec_rep],-1)
    alignment_probs_ = []
    for i in range(T_y):
        if i == 0:
            align_prev_curr = tf.gather(alignment_probs,i,axis=-1)
        if i > 0:
            align_prev_curr = tf.einsum('nx,ny->nxy',tf.gather(alignment_probs,i,axis=-1),alignment_probs_[i-1])
            align_prev_curr *= struc_zeros
            align_prev_curr = K.sum(align_prev_curr,1)+1e-6
            align_prev_curr /= K.sum(align_prev_curr,-1,keepdims=True)
        alignment_probs_.append(align_prev_curr)
    alignment_probs_ = K.stack(alignment_probs_,-1)
    emission_probs = Dense(hidden_dim*3,activation='tanh')(h_rep)
    emission_probs = Dense(Y, activation='softmax')(emission_probs)
    #alphas = tf.expand_dims(alignment_probs_,-1)*emission_probs
    #return(tf.reduce_sum(alphas,-3))
    return(alignment_probs_,emission_probs)

def decode_sequence(input_seq,lang_id,langs,output_segs,input_segs,L,X,Y,T_x,T_y,model,temp=False):
    lang_id_ = np.zeros([1,L])
    input_seq_ = np.zeros([1,T_x,X])
    lang_id_[0,langs.index(lang_id)] = 1.
    for i,s in enumerate(input_seq):
        if s in input_segs:
            input_seq_[0,i,input_segs.index(s)] = 1.
    lang_id = lang_id_
    input_seq = input_seq_
    string = ['[']
    target_seq = np.zeros((1, T_y, Y))
    target_seq[0, 0, output_segs.index('[')] = 1.
#    attention_mat
    for t in range(T_y-1):
        if temp == False:
            output_tokens = model.predict([lang_id,input_seq,target_seq])
        else:
            output_tokens = model.predict([lang_id,input_seq,target_seq,np.ones(1,)*temp])
        curr_index = np.argmax(output_tokens[:,t,:])
        target_seq[0, t+1, curr_index] = 1.
        symbol = output_segs[curr_index]
        string.append(symbol)
        if symbol == ']':
            break
    return(string)