import numpy as np
##For matrix addition and multiplication

import itertools
##For cartesian products and such

import math
##For math stuff

from ast import literal_eval

# import time

#I'm keeping the next two as global variables since it is a pain to put them through multiple functions.
#######
## Probability configuration
## probabilities = [transitioning in specialty 1, transitioning in specialty 2]
trans_probs = np.array([[[0.3, 0.1, 0.6], [0.1, 0.2, 0.7], [0.0, 0.0, 1.0]], [[0.4, 0.1, 0.5], [0.1, 0.2, 0.7], [0.0, 0.0, 1.0]]])
##Entering probs = [entering in specialty 1, entering in specialty 2]
enter_probs = np.array([[0.3, 0.7, 0.0], [0.4, 0.6, 0.0]])
#######

#Resource class L
class Resources:
    def __init__(self,num_res, max_L, avg_ut, cap_L, cap_cost):
        ##How many resources are there
        self.amount = num_res
        ## How many units per resource available
        self.max = max_L
        ## What's the average usage per treatment pattern per period
        self.avgMatrix = avg_ut
        ## What's the desired amount of usage
        self.cap = cap_L
        ## What's the cost for going over this cap?
        self.cost = cap_cost

    def isOverUt(self, state):
        ##We have to group all the treatment patterns together
        ## len(self.avgMatrix[0]) = n
        n= len(self.avgMatrix[0])
        for res_ind in range(self.amount):
            som = 0
            for i in range(len(self.avgMatrix[0])):
                P=0
                for d in range((len(state)//(n))):
                    ##avg_ut = np.array([[2.2,2.6],[2.6,2.2]])
                    for l in range(len(self.avgMatrix[0])):
                        P += (state[l+d*n]*trans_probs[d][l][i])
                som += P*self.avgMatrix[res_ind][i]

            if som > self.max[res_ind]:
                return True
            else:
                pass
        return False

class Patterns:
    def __init__(self, num_patterns):
        ##How many treatment patterns are there
        self.amount = num_patterns
        self.transitions = dict()
        self.states = set()

    def addTransitions(self, specialty, treatmentPattern, size, transitions):
        self.transitions[(specialty, treatmentPattern, size)] = transitions

class Specialties:
    def __init__(self, num_sp, max_spec):
        ## number of specialties
        self.amount = num_sp
        ## Maximum admissions per period
        self.max = max_spec

        #Since self.max exists there is only a limited amount of actions possible
        self.actions = []
        self.actionDistributions = []
        self.__Actions(num_sp, max_spec)

    def Actions(self, amount, max):
        B=[]
        for i in range(len(max)):
            B.append([*range(max[i]+1)])
        A = itertools.product(*B)
        for action in A:
            self.actions.append(list(action))
    __Actions = Actions

    def addActionDistributions(self, actionDistributions):
        self.actionDistributions = actionDistributions

def outputFile(lijst, name):
    f = open(name+'.txt', "w+")
    for i in lijst:
        f.write(str(i)+"\n")
    f.close()

##ATTENTION: PARTITION IS AN AUXILIARY FUNCTION, IT DOESN'T ACTUALLY OUTPUT A PARTITION OF N IN D PARTS LIKE THIS:
##E.g. n=3 in d=3, [[3,0,0],[2,1,0],[2,0,1],[1,2,0],[1,1,1],[1,0,2],[0,3,0],[0,2,1],[0,1,2],[0,0,3]]

##Recursive algorithm for creating partitions of each integer UP TO n in d parts.
##E.g. n=3 in d=3: [0, 0, 0], [1, 0, 0], [2, 0, 0], [3, 0, 0], [0, 1, 0], [1, 1, 0], [2, 1, 0], [0, 2, 0], [1, 2, 0], [0, 3, 0], [0, 0, 1], [1, 0, 1], [2, 0, 1], [0, 1, 1], [1, 1, 1], [0, 2, 1], [0, 0, 2], [1, 0, 2], [0, 1, 2], [0, 0, 3]
def partition(n, d, depth=0):
    if d == depth:
        return [[]]
    return [
        item + [i]
        for i in range(n+1)
        for item in partition(n-i, d, depth=depth+1)
        ]

#makes lists unique and preserves order!
#I am not using set() since it doesn't keep the order I use
def f7(seq):
    seen = set()
    seen_add = seen.add
    return [x for x in seq if not (x in seen or seen_add(x))]

def EnterProb(admstate, specialty):
    P = math.factorial(sum(admstate))
    for i in range(len(admstate)-1):
        if i == len(admstate)-1:
            P = P*(enter_probs[specialty][i])**(sum(admstate)-sum(admstate[:len(admstate)-2]))/math.factorial(sum(admstate)-sum(admstate[:len(admstate)-2]))
        else:
            P = P*(enter_probs[specialty][i])**(admstate[i])/(math.factorial(admstate[i]))
    return P

##Calculates the transition probability given the PARTICULAR(!) transition tuple over the treatment patterns and the specialty
##E.g. Say we want to go to state_(t+1): [0,2,2] from state_t [3,1,1] with action 0, then we have a two-tuple ([0,2,1],[0,0,1])
##Where the first component of the tuple represents x_11 = 0, x_12 = 2, x_13=1 and the second tuple: x_21=0, x_22=0 and x_23=1
def TransProbs(comptuples, specialty):
    ## i will signify in which treatment pattern we're at on time period t
    P=1
    for i in range(len(comptuples)):
        P = P*math.factorial(sum(comptuples[i]))
        for j in range(len(comptuples[i])):
            P = P * (trans_probs[specialty][i][j]) ** (comptuples[i][j]) / (math.factorial(comptuples[i][j]))
    return P

##ATTENTION, IN CASE THERE ARE MORE THAN ONE SPECIALTY DO NOT ATTEMPT TO CALCULATE THE PROBABILITY OF AN ENTIRE STATE
##YOU NEED TO SPLIT IT UP IN PARTS FOR EACH SPECIALTY. E.G. CalcProb IN CASE OF:
##first state [1,0,1,0,2,3], next state [2,3,0,0,2,2], action (4,2), WITH E.amount = 3 AND S.amount = 2
##MUST BE CALCULATED LIKE: CalcProb([2,3,0], [1,0,1], 4, 0)*CalcProb([0,2,2], [0,2,3], 2, 1)

##Given state_(t+1) (state2), state_t (state1), action and specialty this will calculate the probability of going from one state to another
##It will obviously use the functions given above (EnterProb() and TransProbs())
def CalcProb(state2, state1, actionnr, specialty):
    ##If the patients in the next state do not match the patients in each effective treatment pattern + actionnr return probability 0
    if sum(state2) != sum(state1[:len(state1)-1])+actionnr:
        return 0

    ## Else continue
    else:

        ##If state2 = (8,11,3), then B = [[0,1,2,3,4,5,6,7,8],[0,1,2,3,4,5,6,7,8,9,10,11]]
        B=[]

        ##List of all possible action distributions given an action
        ##E.g. if the action is 2, then C = [[2,0],[1,1],[0,2]]
        C=[]

        ##Targetlist is a list for all targets I want to reach by applying only transitions and their respective entering probability.
        ##One target is defined as state2 - (minus) action distribution
        ##E.g. if state2 = [2,2,2] and action = 1, then the possible action distributions are:
        ##[1,0,0] and [0,1,0] and thus the possible targets are: [1,2,2] and [2,1,2]
        ##So targetlist = [[[1,2,2],P([1,0,0])], [[2,1,2],P([0,1,0])]]
        targetlist=[]

        ##Make B from description I gave above
        ##If state2 = (8,11,3), then B = [[0,1,2,3,4,5,6,7,8],[0,1,2,3,4,5,6,7,8,9,10,11]] and nothing for discharge pattern
        for i in range(len(state2)-1):
            B.append([*range(state2[i]+1)])
        ##A is a cartesian product of the sets in B
        ##E.g. B = [[1,2],[7,8]], then A = {(1,7),(1,8),(2,7),(2,8)}
        A = itertools.product(*B)

        ##this creates the list of action distributions C of above
        for action in A:
            ##We add the discharge pattern which is 0
            action = list(action)+[0]
            ##If the sum of the amount of patients equal the action then add the action distribution to C
            if sum(action)== actionnr:
                C.append(action)

        ##Note that we could have created C by means of the partition() function above, but then we would have to trim
        ##C by taking out all the action distributions where there are too many people being added.

        ##Let us now begin to
        for action in C:
            ##Target is the target we want to hit by doing only transitions
            target = np.array(state2)-np.array(action)
            ##Now we add the target and its action probability to targetlist
            targetlist.append([target.tolist(),EnterProb(action, specialty)])

        ##Above we got all the probabilities you could obtain by adding patients in the next period (entering prob).
        ##Now we calculate the probabilities you can get by moving patients around.
        transition_prob_sums = []
        ##Now we want to work for each target alone
        for targ in targetlist:
            ##Create a list for transitions
            trans = []
            ##Create a list for the sums of transitions
            transsums = []

            ##Let us iterate over the elements in target, except for the last element since that is the discharge
            for j in range(len(targ[0])-1):
                ##list of transitions created by going over the partition created by varying component j
                lst3=[]
                ## To partition sumlist in a component for every j, we must create a new list. sumlist = [[...], [...], ..., [...]]
                for i in range(targ[0][j]+1):
                    ##Since i stands for how many patients we keep in a treatment pattern we need to calculate how many we have to distribute
                    n = state1[j]-i
                    d = len(state1)-1

                    ##This will partition the number n in d parts
                    ##E.g. n= 4, d=3, then [[n - sum(p)] + p for p in partition(n, d - 1)] gives:
                    ##[4,0,0],[3,1,0],[3,0,1],[2,2,0],[2,1,1],[2,0,2],[1,3,0],[1,2,1],[1,1,2],[1,0,3],[0,4,0],[0,3,1],
                    ##[0,2,2],[0,1,3],[0,0,4].
                    lst = [[n - sum(p)] + p for p in partition(n, d - 1)]
                    ##What we have done up until this point is, given a target distribution and initial state: E.g. Targ = [2,3,4,5] and InitState = [10,4,0,1]
                    ##We have taken a single non-discharge component j in Targ and let i be iterated in the range of Targ[j]
                    ##So, take j=1, then Targ[j]=3 and thus i is iterated in the range [0,1,2,3].
                    ##Next, we took n = InitState[j]-i and d the number of patterns-1, ! THIS IS NOT BECAUSE OF THE DISCHARGE PATTERN, BUT RATHER BECAUSE WE ARE NOT USING COMPONENT j!
                    ##So in our example, let us say we are in the 3rd iteration, then i = 2 and thus
                    ##n = 4-2 and d = 3. (I realise that recalculating the same number is inefficient/sloppy, but I do not
                    ##think it is very expensive or time consuming.) Now we have created lst, which in our case is:
                    ##lst = [[2,0,0],[1,1,0],[1,0,1],[0,2,0],[0,1,1],[0,0,2]]
                    ##What will we do with lst? Well essentially we have distributed n people over the other treatment patterns,
                    ##While we kept i people in treatment pattern j, therefore we want to add component j in each list in lst.
                    ##lst2 will therefore be:
                    ##lst2 = [[2,2,0,0],[1,2,1,0],[1,2,0,1],[0,2,2,0],[0,2,1,1],[0,2,0,2]]
                    lst2=[]
                    for lijst in lst:
                        lijst = lijst[0:j] + [i] + lijst[j:]
                        lst2.append(lijst)

                    ##lst3 is a superlist of lst2 for all components. this means that it has all of the elements of lst2 for all components i.
                    ##We need this list so we can can make the following cartesian product:
                    ##[transitions by varying component 0]x[trans component 1]x...x[trans component E.amount-1]
                    ##This is equivalent with
                    ##[lst3, j=0]x[lst3, j=1]x...x[lst3, j=len(targ[0])-1]
                    lst3 = lst3 + [element for element in lst2]
                ##trans = [[lst3, j=0],[lst3, j=1],...,[lst3, j=len(targ[0])-1]]
                trans.append(lst3)
            ##transprods is exactly the cartesian product set I wanted, its class is not accessible by the usual operation
            ##transprods[k], but you can iterate over transprods like we do in our for-loop
            transprods = itertools.product(*trans)
            for prod in transprods:
                ##This is where the inefficiency of CalcProb() comes in. I am manually checking if the sum of the
                ##distributions equal the sum of the people in the first state (that are not in the discharge state).
                ##For example: take my above Targ = [2,3,4,5] and InitState [10,4,0,1].
                ##Then a prod in transprods looks like: ([0,1,5,2],[0,2,0,0],[0,0,0,0]), what I want is that
                ##[0,1,5,2]+[0,2,0,0]+[0,0,0,0] equals Targ = [2,3,4,5], but in this case it does not, because
                ##[0,1,5,2]+[0,2,0,0]+[0,0,0,0] = [0,3,5,2] != [2,3,4,5]

                #som in our example is [0,3,5,2]
                som = sum([np.array(list(prod)[u]) for u in range(len(state2)-1)])

                #[0,3,5,2] != [2,3,4,5] and therefore, pass.
                if som.tolist() == targ[0]:
                    #If it accepts, then add the probability we were able to calculate through transprobs.
                    transsums.append([prod, TransProbs(prod, specialty)])
            ##transsums is the list of all possible combinations of transitions ! NOT POSSIBLE ACTION DISTRIBUTIONS !
            ##with their respective transition probability

            ##([1, 3, 4, 2], [1, 0, 0, 3], [0, 0, 0, 0]) is a prod where the if-statement is TRUE, therefore
            ##transsums is definitely not empty.

            #Initial probability is 0
            kans=0

            #For v in the range of transsums
            for v in range(len(transsums)):
                ##P(transsums[v][0])=transsums[v][1], now add it to the total probability
                kans = kans + transsums[v][1]

            ##Now transition_prob_sums is the total probability to go from state1 to Targ
            transition_prob_sums.append(kans)
            #Iterate until the end of targetlist

        #Finalsum will be our final probability and we start it at 0
        finalProb = 0
        for i in range(len(transition_prob_sums)):
            ##distrProb is the probability of going from state2 to targ times the probability of going from Targ to state1.
            ##essentially, the probability given a distribution of the action.
            distrProb = transition_prob_sums[i]*targetlist[i][1]
            ##Since we add up all the above probabilities, finalsum will be the total probability of reaching a state given an action
            finalProb = finalProb+distrProb
        return finalProb

##Actionchecker: given a state, it will see if it's overutilized, and if it isn't then we return a tuple of all possible actions
##and a tuple of possible action distributions.
##E.g. suppose S.amount = 1 and E.amount = 3, S.max = 2
##If [1,2,3] is not overutilized, then actionChecker([1,2,3],L,E,S) = (((0,),(1,),(2,)),((0,0,0),(1,0,0),(0,1,0),(2,0,0),(1,1,0),(0,2,0)))
def actionChecker(state0, L, E, S):
    ##number of treatment patterns in a specialty
    n = E.amount
    ##All possible admission distributions given a state
    actionstatess = ()

    ##All possible actions
    allpossibleactions = ()
    ##If the initial state is overutilizing the resources, then do not add new people
    if L.isOverUt(state0) == True:
        allpossibleactions = ((0,) * S.amount,)
        actionstatess = ((0,) * n * S.amount,)
        return allpossibleactions, actionstatess
    else:
        if len(S.actionDistributions)==0:
            for action in S.actions:
                A = [0]*int(S.amount)
                for i in range(S.amount):
                    ##n-2 should actually be (n-1)-1 , that first n-1 because we do not want to add to the discharge pattern,
                    ##And the second because making a partition of the number k in n parts is calculated by
                    ##[[k - sum(p)] + p for p in partition(k, n - 1)]
                    A[i] = tuple([p +[0] for p in partition(action[i], n - 1)])

                # ##Suppose action = (2,3), and n = E.amount= 3 then A will equal
                # ##[([0,0,0],[1,0,0],[0,1,0],[2,0,0],[1,1,0],[0,2,0]),([0,0,0],[1,0,0],[0,1,0],[2,0,0],[1,1,0],[0,2,0],[3,0,0],[2,1,0],[1,2,0],[0,3,0])]
                # ##A will be a list of tuples of lists like above
                # A = [0]*int(S.amount)
                # actionstates=()
                # for i in range(S.amount):
                #     ##n-2 should actually be (n-1)-1 , that first n-1 because we do not want to add to the discharge pattern,
                #     ##And the second because making a partition of the number k in n parts is calculated by
                #     ##[[k - sum(p)] + p for p in partition(k, n - 1)]
                #     A[i] = tuple([[action[i] - sum(p)] + p +[0] for p in partition(action[i], n - 2)])
                #     print(i, action, action[i], A[i])
                # # ##B is a cartesian product of the tuples in A
                # # ##so A[0]xA[1]x...xA[S.amount]
                # # B = itertools.product(*A)
                # #
                # # ##statecouple could look like this: ([0,1], [1,2]) where [0,1] comes from A[0] and [1,2] comes from A[1]
                # # for statecouple in B:
                # #     ##Given a statecouple we are going to put them in one entire state, called state[]
                # #     state=[]
                # #     ##Let us add the discharge pattern (we add 0)
                # #     for statenr in range(S.amount):
                # #         state=state+statecouple[statenr]+[0]
                # #     ##We add state[] in the tuple actionstates as a tuple
                # #     actionstates = actionstates + (tuple(state),)
                # #
                # # action = tuple(action)
                # #
                # # #Tuple of possible states we can get to given an action
                # # actionstatess = actionstatess + actionstates
                actionstatess = A
                #
                # #Tuple of actions we can take
                # allpossibleactions = allpossibleactions + (action,)

            S.addActionDistributions(actionstatess)
    return tuple(S.actions), tuple(S.actionDistributions)

##Given a state, transitioner will give all possible next states by only transitioning fron one treatment pattern to another,
##So we do not add patients. NO ACTION USED.
def transitioner(state, L, E, S):
    #n is amount of treatment patterns
    n = E.amount

    #d is amount of specialties
    d = S.amount

    # print(11111, state)
    possibletransitions = []
    for specialty in range(d):
        #state_specialty takes the treatment patterns from one specialty
        state_specialty = state[n*specialty:n*(specialty+1)]

        ##This will be a list(lists obtained by varying component from 0 to n-1)
        trans_per_trans_i = []
        #for treatment pattern that is not the discharge pattern
        if (specialty, state_specialty, -1) in E.transitions.keys():
            poss_combs_of_transitions = E.transitions[(specialty,state_specialty, -1)]
        else:
            for treatment in range(n-1):
                trans_i = []
                if (specialty, treatment, state_specialty[treatment]) in E.transitions.keys():
                    trans_i = E.transitions[(specialty, treatment, state_specialty[treatment])]
                else:
                    ##i stands for how many patients we leave in a treatment pattern
                    ##And thus trans_i is the possible transitions we get if we vary i from 0 to state_specialty[treatment]
                    for i in range(state_specialty[treatment] + 1):
                        ##if i stands for how many people we leave, then state_specialty[treatment]-i stands for how many people we redistribute
                        lst = [[state_specialty[treatment]-i-sum(p)] + p for p in partition(state_specialty[treatment]-i, n - 2)]
                        ##suppose state_specialty = [2,50,1], treatment = 0, i=1, then lst = [[51,1],[50,2]]
                        lst2=[]
                        ##Take the same example, lst2 would be: [[1,51,1],[1,50,2]]
                        for lijst in lst:
                            lijst = lijst[0:treatment] + [i] + lijst[treatment:]
                            lst2.append(lijst)
                        trans_i = trans_i+lst2
                    E.addTransitions(specialty, treatment, state_specialty[treatment], trans_i)
                trans_per_trans_i.append(trans_i)

            ##All the possible combinations of redistributions from all possible components
            ##Cartesian product
            poss_combs_of_transitions_tuples = itertools.product(*trans_per_trans_i)

            ##The difference between this and poss_combs_of_transitions_tuples, is that this one will have the states added up to each other
            poss_combs_of_transitions = []

            for comb in poss_combs_of_transitions_tuples:
                #np.array() + np.array() returns a single np.array() by componentwise addition
                sumarray = np.array([0]*n)
                for treatment in range(n-1):
                    sumarray = sumarray + np.array(comb[treatment])
                    sumarray = sumarray.tolist()
                poss_combs_of_transitions.append(sumarray)
            E.addTransitions(specialty, state_specialty, -1, poss_combs_of_transitions)
        ##Start gluing the specialties together by putting all the combinations in a list
        possibletransitions.append(tuple(poss_combs_of_transitions))

    # ##Since each specialty has a different list for combinations, we will make a cartesian product of all the specialties
    # possibletransition_comb_tuples = itertools.product(*possibletransitions)
    #
    # ##Let us start putting all the different combinations in one entire state of dimension n*d
    # semiposs_trans = []
    # for comb in possibletransition_comb_tuples:
    #     sumlist = ()
    #     for i in range(len(possibletransitions)):
    #         sumlist = sumlist+tuple(comb[i])
    #     semiposs_trans.append(sumlist)
    return possibletransitions

##Since transitioner only transitions and actionChecker only adds them lets combine those two
def posStates(state0, L, E, S):
    ##Remember that the second result in actionChecker is all the distributions of the action. so actions() here is a misnomer
    ##and does not mean the amount of people we add in each specialty, but rather the amount of people we add in each treatment pattern.
    ##Or in other words, actions() here actually means action distributions
    actions = actionChecker(state0, L, E, S)[1]
    ##len(actions) == 1 if and only if the only action distribution possible is (0,)*E.amount and thus we only need transitioner(state)
    if len(actions) == 1:
        possibletransitions = tuple(transitioner(state0, L, E, S))
        ##Since each specialty has a different list for combinations, we will make a cartesian product of all the specialties
        possibletransition_comb_tuples = itertools.product(*possibletransitions)

        ##Let us start putting all the different combinations in one entire state of dimension n*d
        semiposs_trans = []
        for comb in possibletransition_comb_tuples:
            sumlist = ()
            for i in range(len(possibletransitions)):
                sumlist = sumlist+tuple(comb[i])
            semiposs_trans.append(sumlist)
        everyposstate = semiposs_trans

    ##in the other case there exist non-zero action distributions
    else:
        #first we calculate all the possible states you can get by transitioning
        transitionstates = transitioner(state0, L, E, S)
        # print(444444)
        everyposstate_combs = []
        for specialty in range(len(transitionstates)):
            pos_states_specialty = []

            #This is the cartesian product of the set of transitions with the set of admissions for a specific specialty
            trans_and_act_per_specialty = itertools.product(transitionstates[specialty],actions[specialty])
            #now we add the two together component-wise
            for comb_prod in trans_and_act_per_specialty:
                # add transition up with an action distribution
                combination = np.array(comb_prod[0])+np.array(comb_prod[1])
                combination = combination.tolist()
                combination = tuple(combination)
                pos_states_specialty.append(combination)
            everyposstate_combs.append(pos_states_specialty)

        everyposstate_prod = itertools.product(*everyposstate_combs)
        everyposstate = ()
        for posstate_comb in everyposstate_prod:
            if posstate_comb not in E.states:
                E.states.add(posstate_comb)
                posstate = itertools.chain(*posstate_comb)
                everyposstate = everyposstate + (tuple(posstate),)
    everyposstate = set(everyposstate)
    # print(555555, everyposstate)
    return everyposstate

##We are also interested in what the possible states are if we are given the action, I will not go into full detail here
##since all the methods were already used once
def posStatesGivenAction(state0, action, L, E, S):
    possTrans = tuple(transitioner(state0, L, E, S))
    n = E.amount
    A = [0] * int(S.amount)
    possActionDistrs = []
    for i in range(S.amount):
        A[i] = [[action[i]-sum(p)] + p for p in partition(action[i], n-2)]
    B = itertools.product(*A)
    for distr in B:
        distrib = []
        for d in range(S.amount):
            distrib = distrib + distr[d] + [0]
        possActionDistrs.append(tuple(distrib))
    possStates = []
    for trans in possTrans:
        nptrans = np.array(trans)
        for act in possActionDistrs:
            npact = np.array(act)
            som = nptrans + npact
            som2 = tuple(som)
            possStates.append(som2)
    return possStates

def stateSpace(state0, L, E, S):
    statelist = list(posStates(state0, L, E, S))
    nextstates = []
    for state in statelist:
        nextstates = nextstates + list(posStates(state, L, E, S))
    nextstates = statelist + nextstates
    nextstates = f7(tuple(nextstates))
    print(nextstates)

    while len(nextstates) > len(statelist):
        length = len(statelist)
        uniquestates = nextstates[len(statelist):]
        statelist = nextstates
        nextstates = []
        # i = 0
        for uniquestate in uniquestates:
            # i += 1
            nextstates = nextstates + list(posStates(uniquestate, L, E, S))
        nextstates = statelist + nextstates
        nextstates = f7(tuple(nextstates))
        print(nextstates)
    return nextstates

def costFunction(state, action, L, E, S):
    ##We don't need to find all the states reachable with the action, since we're only looking for the worst case scenario
    allPossStates = posStatesGivenAction(state, action, L, E, S)
    ##And now for the probabilities:
    totaalsom = 0
    for nextstate in allPossStates:
        n = E.amount
        ##We need to calculate how many people use resource Lj in nextstate
        total_avgusage_per_resource = []
        som=0
        for res_numbr in range(L.amount):
            total_avgusage=0
            for specialty in range(len(action)):
                for tr_pat in range(n-1):
                    ##avg_ut = [[avg util. of res. 1 by E_1,avg ut of res. 1 by E_2], [avg ut of res. 2 by E_1,avg ut of res. 2 by E_2]]
                    ##avg_ut = np.array([[2.2,2.6],[2.6,2.2]])
                    total_avgusage += nextstate[tr_pat+(specialty*n)]*L.avgMatrix[res_numbr][tr_pat]
            Oj = L.cost[0][res_numbr]*max(0, L.cap[res_numbr]-total_avgusage)
            Bj = L.cost[1][res_numbr]*max(0, total_avgusage-L.cap[res_numbr])
            Cj = L.cost[2][res_numbr]*max(0, total_avgusage-L.max[res_numbr])
            som += Oj+Bj+Cj
        P=1
        for specialty in range(len(action)):
             P = P*CalcProb(nextstate[n*specialty:n*(specialty+1)], state[n*specialty:n*(specialty+1)], action[specialty], specialty)
        totaalsom+=P*som
    return totaalsom

def main():
    ##Number of specialties d
    d= 2
    ## maximum admission per period max_S = [max in specialty 1, max in specialty 2]
    max_S= np.array([2,3])

    ## NUMBER OF RESOURCES
    num_res = 2
    ## max(L_j)
    max_L = np.array([6,5])

    ## Number of treatment patterns
    n=3
    ## avg resource utilization per period
    ## avg_ut = [[avg util. of res. 1 by E_1,avg ut of res. 1 by E_2], [avg ut of res. 2 by E_1,avg ut of res. 2 by E_2]]
    avg_ut = np.array([[1.2,3.0,0],[3.6,2.8,0]])
    ## Utilization cap
    cap_L = np.array([4,5])

    ##Cost for resource deviation idleness, excess and over
    cap_cost = np.array([[1.0,1.6],[1.5,1.0],[2.0,2.0]])

    ## We can put this in our resource, specialty and treatment pattern class
    L = Resources(num_res, max_L, avg_ut, cap_L, cap_cost)
    E = Patterns(n)
    S = Specialties(d, max_S)

    #Creates state space
    # start = time.time()
    A = stateSpace((0,0,0,0,0,0),L,E,S)
    # end = time.time()
    # print(end - start)
    # print(len(A))
    print(len(A), A)
    # outputFile(A, "statenspatie5")

    ##Since we do not want to recalculate the state space all the time we just save it externally and call it up
    # statenspatie = open("statenspatie5.txt", 'r')
    # statespace = []
    # for state in statenspatie:
    #     listContent = state.rstrip()
    #     tupel = literal_eval(listContent)
    #     statespace.append(tupel)
    # statenspatie.close()

    ##Time for action space
    # statewithactions = []
    # for state in statespace:
    #     actions = actionChecker(state, L, E, S)[0]
    #     statewithactions.append((state, actions))
    # outputFile(statewithactions, "actionspace")

    # print(costFunction((1,2,5,0,0,0),(2,0), L, E, S))
    # print(costFunction((0,0,0,1,2,5),(0,2),L,E,S))
    # som = 0
    # alreadydone = []
    # for state in statespace:
    #     if state[0:3] not in alreadydone:
    #         B=CalcProb(state[0:3], (1, 0, 0), 1, 0)
    #         print(state, B)
    #         som += B
    #         alreadydone.append(state[0:3])
    #
    # print(som)
main()


#!/usr/bin/env python3
# coding: utf-8
# Copyright 2019 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""CCE configuration constants"""
from __future__ import absolute_import as _abs
import akg.tvm

# def the buffer var
scope_cbuf = "local.L1"
scope_ubuf = "local.UB"
scope_ca = "local.L0A"
scope_cb = "local.L0B"
scope_cc = "local.L0C"
scope_reg = "local.REG"
scope_aicpu = "local_aicpu"

dma_copy = "dma_copy"
dma_copy_global = "global"

f = akg.tvm.get_global_func("cce_util.GetCceAxis")

# def the cce thread axis for sync
CCE_AXIS = f()

# def the gemm const
WGT_WIDTH = 16
INP_WIDTH = 16
OUT_WIDTH = 16
BLOCK_IN = 16
BLOCK_OUT = 16
BLOCK_REDUCE = 16

INP_ELEM_BYTES = (BLOCK_IN * BLOCK_REDUCE * INP_WIDTH // 8)
WGT_ELEM_BYTES = (BLOCK_OUT * BLOCK_REDUCE * WGT_WIDTH // 8)
OUT_ELEM_BYTES = (BLOCK_IN * BLOCK_OUT * OUT_WIDTH // 8)
GLB_ELEM_BYTES = (16 * OUT_WIDTH // 8)


import numpy
import theano
import theano.tensor as T

class NeuralNet():

    '''
    This class creates a neural network object capable of multiple hidden
    layers. The gradient calculation uses theano's symbolic differentiation and
    can take advantage of GPU computation.

    There is a theano MultiLayer Perception (MLP) available at:
    http://deeplearning.net/tutorial/mlp.html

    Parameters
    ----------
    Layers: list of integers specifying the number of nodes in each layer
    '''

    def __init__(self, layers):
        # This method initializes the network object weights and bias nodes

        self.iter = 1000  #number of iterations for training

        self.weights = []
        self.mask = []

        # Setting the seed allows repeatable weight initialization
        rng = numpy.random.RandomState(7)

        # Create weights for each hidden layer
        for index in range(len(layers[:-1])):
            weights, masks = self.createLayer(rng, layers[index],
                                       layers[index + 1], '%d' % index)
            self.weights.append(weights)
            self.mask.append(masks)

        self.params = self.weights

    def createLayer(self, rng, n_in, n_out, suffix):
        # I think of network layers as the activation nodes. Activation nodes
        # are generated by feeding forward through the network.
        # This method creates weights with optimal magnitude for sigmoid
        # activation and stores them as theano tensor variables.

        # n_in & _out: are the number of connections into/out of current layer
        # suffix: designates the current layer in the network

        n_in = n_in + 1 #adding weight for bias nodes

        # Generate weights as numpy matrix.
        W_values = numpy.asarray(rng.uniform(
            low=-numpy.sqrt(6. / (n_in + n_out)),
            high=numpy.sqrt(6. / (n_in + n_out)),
            size=(n_in, n_out)), dtype=theano.config.floatX)
        W_values *= 4

        # Create mask matrix for sparse connectivity
        mask = numpy.ones((n_in, n_out), dtype=theano.config.floatX)

        # Store weighs as shared variable
        w = theano.shared(value=W_values, name='W_{}'.format(suffix))

        return w, mask

    def cost(self, x, y, L2=0.00001):
        # This method calculates the logistic cost with a  correction, L2, for
        # large/biased weight values.

        # x: network input
        # y: expected network result
        # L2: correction factor for large/biased weights

        # Update network out put by feeding input forward with current weights
        self.y = T.dot(x, (self.weights[0] * self.mask[0]))
        self.y = T.nnet.sigmoid(self.y)
        for index in range(len(self.weights[1:])):
            bias = T.ones((T.shape(self.y)[0], 1))
            self.y = T.concatenate((bias, self.y), axis=1)  # Add bias node
            self.y = T.dot(self.y, (self.weights[index + 1] * self.mask[index + 1]))
            self.y = T.nnet.sigmoid(self.y)

         # Calculate logistic error
        logErr = y * T.log(self.y) + (1 - y) * T.log(1 - self.y)
        cost = -1. / y.shape[0] * logErr.sum()

        # Add L2 cost correction
        cost = cost + L2 * sum([(w ** 2).sum() for w in self.weights])

        return cost

    def train(self, data_in, data_out, learning_rate=0.0007, momentum=0.9, L2=0.00001):
        # This method trains the neural network using theano's symbolic gradient
        # calculation. YAY didn't have to write out back propagation.

        # data_in: data input
        # data_out: expected result for data input
        # learning_rate: step factor for gradient move
        # L2: correction factor for large/bias weights

        x = T.matrix('x')
        y = T.matrix('y')

        # Calculate the cost gradient with respect to params (list of weights)
        paramGrad = []
        for param in self.params:
            gradient = T.grad(self.cost(data_in, data_out, L2), wrt=param)
            paramGrad.append(gradient)

        # Update params (weights) by paramGrad
        updates = []
        for param, paramGrad in zip(self.params, paramGrad):
            updates.append((param, momentum * param + (1. - momentum) *
                                          (param - learning_rate * paramGrad)))

        # Create a theano function `trainNet` that returns the cost given the
        # data input and expected result while updating the network weights in
        # `updates`
        self.trainNet = theano.function(inputs=[x, y],
                                        outputs=self.cost(x, y),
                                        updates=updates)

        # Make sure the dtype will work with the theano configuration
        data_in = numpy.array(data_in, dtype=theano.config.floatX)
        data_out = numpy.array(data_out, dtype=theano.config.floatX)

        # Run the train function for n iterations (1000)
        self.icost = []
        for i in range(self.iter):
            self.icost.append(self.trainNet(data_in, data_out))

    def predict(self, x):
        # This method is for a trained network. It feeds the input data, x,
        # through the network and returns the network prediction

        # Make sure the dtype will work with the theano configuration
        x = numpy.array(x, dtype=theano.config.floatX)

        y = T.dot(x, self.weights[0])
        y = self.y = T.nnet.sigmoid(y)
        for index in range(len(self.weights[1:])):
            bias = T.ones((T.shape(self.y)[0], 1))
            self.y = T.concatenate((bias, self.y), axis=1) # Add bias node
            y = T.dot(y, self.weights[index + 1])
            self.y = T.nnet.sigmoid(y)

        return y


from rest_framework import serializers

from .models import UserCollect, UserRead, UserForward, ExportTask, UserMark
from django_server.apps.user.models import Branch
from django_server.apps.manage.models import MedOrgPrincipal, MedOrgType
from django_server.utils.translate import MEDICAL_CATEGORY_LST, MEDICAL_LST
from django_server.utils.utils import list_item_same
# from django_server.apps.account.models import Module

class CollectListSerializer(serializers.ModelSerializer):
    name = serializers.SerializerMethodField()
    marks = serializers.SerializerMethodField()
    related_orgs = serializers.SerializerMethodField()
    last_status = serializers.SerializerMethodField()
    product_tags = serializers.SerializerMethodField()
    is_self_product = serializers.SerializerMethodField()

    class Meta:
        model = UserCollect
        fields = ('id', 'uuid', 'title', 'branch', 'released_at', 'created_at', 'name', 'marks',
                  'state', 'extra', 'last_status', 'update_at', 'info_type', 'related_orgs',
                  'is_self_product', 'product_tags')

    def get_name(self, obj):
        try:
            return Branch.objects.get(ename=obj.branch).name
            # return Module.objects.get(ename=obj.module).name
        # except Module.DoesNotExist:
        except Branch.DoesNotExist:
            return ''

    def get_marks(self, obj):
        return {'collect': obj.uuid}
        # marks = {'collect': obj.uuid}
        # try:
        #     user = self.context['request'].user.user_extra
        # except:
        #     return marks
        # if UserRead.objects.filter(user=user, uuid=obj.uuid).exists():
        #     marks['read'] = obj.uuid
        # return marks

    def get_crm_code(self, obj):
        try:
            user = self.context['request'].user.user_extra
        except:
            return ''
        try:
            return UserMark.objects.filter(user=user, uuid=obj.uuid, module=obj.module)[0].crm_code_number
        except:
            return ''

    # todo
    def get_related_orgs(self, obj):
        payload = []
        if obj.extra.get('related_orgs'):
            related_orgs = obj.extra.get('related_orgs')
            user_id = self.context['request'].user.id
            for item in related_orgs:
                if item['org_role']['value'] in ('ER0001', 'ER0002'):
                    org_uuid = item['org_uuid']
                    if MedOrgPrincipal.objects.filter(user_id=user_id, org_uuid=org_uuid).exists():
                        item.update({'state':  '我负责的'})
                    elif MedOrgType.objects.filter(user_id=user_id, org_uuid=org_uuid).exists():
                        item.update({'state': '我关注的'})
                    else:
                        item.update({'state': None})
                    payload.append(item)
        return payload

    def get_last_status(self, obj):
        if obj.last_status == '0':
            return '我：收藏成功'
        elif obj.last_status == '1':
            status = '我：更新状态为' + ('新收藏' if obj.state == '0' else ('跟进中' if obj.state == '1' else ('已签约' if obj.state == '2' else ('储备库' if obj.state == '3' else ()))))
            return status
        elif obj.last_status == '2':
            try:
                contents = UserMark.objects.get(uuid=obj.uuid, user=self.context['request'].user.user_extra).contents
                status = '我：编辑标注为' + contents[0]['content']
                return status
            except:
                return '我：编辑标注'
        else:
            return '中标公告'

    def get_product_tags(self, obj):
        product_tags = []
        product_tags2 = []
        # 获取departments
        departments = self.context['request'].user.user_extra.departments.values('base_range_product',
                                                                                'info_range_product', )
        products_lst = []
        for department in departments:
            products = department['info_range_product']
            products = department['base_range_product'] if not products else products
            if list_item_same(products, MEDICAL_LST):
                products_lst = []
            else:
                products_lst.extend(products)

        for tag in obj.extra['custom_tags']:
            if tag not in MEDICAL_CATEGORY_LST + MEDICAL_LST:
                continue
            elif tag in products_lst or tag[:4] in products_lst:
                product_tags.append({"product_tag": tag, "related": True})
            else:
                product_tags2.append({"product_tag": tag, "related": False})
        # 排序
        product_tags.extend(product_tags2)
        return product_tags

    def get_is_self_product(self, obj):
        try:
            self_products = self.context['request'].user.tenant.products_categories[0]['keywords']
            departments = self.context['request'].user.user_extra.departments.values('base_range_product',
                                                                                'info_range_product', )
            products_lst = []
            for department in departments:
                products = department['info_range_product']
                products = department['base_range_product'] if not products else products
                if list_item_same(products, MEDICAL_LST):
                    products_lst = []
                else:
                    products_lst.extend(products)
            self_products = list(set(self_products).intersection(set(products_lst)))
            custom_tags = obj.extra['custom_tags']
            union = set(self_products).intersection(set(custom_tags))
            if union:
                return True
            return False
        except Exception as e:
            return False

class MarkInfoSerializer(serializers.Serializer):
    contacts = serializers.JSONField()
    contents = serializers.JSONField()

    class Meta:
        fields = ('contacts', 'contents')

class ExportTaskListSerializer(serializers.ModelSerializer):
    class Meta:
        model = ExportTask
        fields = ('id', 'name', 'download_url', 'state', 'completed', 'created')

class ForwardListSerializer(serializers.ModelSerializer):
    name = serializers.SerializerMethodField()
    readed_count = serializers.SerializerMethodField()

    # location = serializers.SerializerMethodField()
    # custom_tags = serializers.SerializerMethodField()

    class Meta:
        model = UserForward
        fields = ('branch', 'module', 'uuid', 'title', 'released_at',
                  'created_at', 'name', 'readed_count', 'id', 'industry_tags', 'extra')

    def get_name(self, obj):
        try:
            return Branch.objects.get(ename=obj.branch).name
        except:
            return ''

    def get_readed_count(self, obj):
        readed_count = 0
        for user in obj.to_users:
            if UserRead.objects.filter(user_id=user, uuid=obj.uuid).exists():
                readed_count += 1
        return readed_count

        # def get_location(self, obj):
        #     resource = BulletinResource()
        #     fetch = resource.fetch()
        #     fetch.params.update({
        #         'uuid__in': obj.uuid
        #     })
        #     for result in fetch:
        #         return getattr(result, 'location')

        # def get_custom_tags(self, obj):
        #     resource = BulletinResource()
        #     fetch = resource.fetch()
        #     fetch.params.update({
        #         'uuid__in': obj.uuid
        #     })
        #     for result in fetch:
        #         return getattr(result, 'custom_tags')


"""Open ports in your router for Home Assistant and provide statistics."""
import asyncio
from ipaddress import ip_address
from operator import itemgetter

import voluptuous as vol

from homeassistant import config_entries
from homeassistant.config_entries import ConfigEntry
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import config_validation as cv, device_registry as dr
from homeassistant.helpers.typing import ConfigType, HomeAssistantType
from homeassistant.util import get_local_ip

from .const import (
    CONF_LOCAL_IP,
    CONFIG_ENTRY_ST,
    CONFIG_ENTRY_UDN,
    DISCOVERY_LOCATION,
    DISCOVERY_ST,
    DISCOVERY_UDN,
    DISCOVERY_USN,
    DOMAIN,
    DOMAIN_CONFIG,
    DOMAIN_COORDINATORS,
    DOMAIN_DEVICES,
    DOMAIN_LOCAL_IP,
    LOGGER as _LOGGER,
)
from .device import Device

NOTIFICATION_ID = "upnp_notification"
NOTIFICATION_TITLE = "UPnP/IGD Setup"

CONFIG_SCHEMA = vol.Schema(
    {DOMAIN: vol.Schema({vol.Optional(CONF_LOCAL_IP): vol.All(ip_address, cv.string)})},
    extra=vol.ALLOW_EXTRA,
)

async def async_discover_and_construct(
    hass: HomeAssistantType, udn: str = None, st: str = None
) -> Device:
    """Discovery devices and construct a Device for one."""
    # pylint: disable=invalid-name
    discovery_infos = await Device.async_discover(hass)
    _LOGGER.debug("Discovered devices: %s", discovery_infos)
    if not discovery_infos:
        _LOGGER.info("No UPnP/IGD devices discovered")
        return None

    if udn:
        # Get the discovery info with specified UDN/ST.
        filtered = [di for di in discovery_infos if di[DISCOVERY_UDN] == udn]
        if st:
            filtered = [di for di in discovery_infos if di[DISCOVERY_ST] == st]
        if not filtered:
            _LOGGER.warning(
                'Wanted UPnP/IGD device with UDN "%s" not found, aborting', udn
            )
            return None

        # Ensure we're always taking the latest, if we filtered only on UDN.
        filtered = sorted(filtered, key=itemgetter(DISCOVERY_ST), reverse=True)
        discovery_info = filtered[0]
    else:
        # Get the first/any.
        discovery_info = discovery_infos[0]
        if len(discovery_infos) > 1:
            device_name = discovery_info.get(
                DISCOVERY_USN, discovery_info.get(DISCOVERY_LOCATION, "")
            )
            _LOGGER.info("Detected multiple UPnP/IGD devices, using: %s", device_name)

    location = discovery_info[DISCOVERY_LOCATION]
    return await Device.async_create_device(hass, location)

async def async_setup(hass: HomeAssistantType, config: ConfigType):
    """Set up UPnP component."""
    _LOGGER.debug("async_setup, config: %s", config)
    conf_default = CONFIG_SCHEMA({DOMAIN: {}})[DOMAIN]
    conf = config.get(DOMAIN, conf_default)
    local_ip = await hass.async_add_executor_job(get_local_ip)
    hass.data[DOMAIN] = {
        DOMAIN_CONFIG: conf,
        DOMAIN_COORDINATORS: {},
        DOMAIN_DEVICES: {},
        DOMAIN_LOCAL_IP: conf.get(CONF_LOCAL_IP, local_ip),
    }

    # Only start if set up via configuration.yaml.
    if DOMAIN in config:
        hass.async_create_task(
            hass.config_entries.flow.async_init(
                DOMAIN, context={"source": config_entries.SOURCE_IMPORT}
            )
        )

    return True

async def async_setup_entry(hass: HomeAssistantType, config_entry: ConfigEntry) -> bool:
    """Set up UPnP/IGD device from a config entry."""
    _LOGGER.debug("async_setup_entry, config_entry: %s", config_entry.data)

    # discover and construct
    udn = config_entry.data.get(CONFIG_ENTRY_UDN)
    st = config_entry.data.get(CONFIG_ENTRY_ST)  # pylint: disable=invalid-name
    try:
        device = await async_discover_and_construct(hass, udn, st)
    except asyncio.TimeoutError as err:
        raise ConfigEntryNotReady from err

    if not device:
        _LOGGER.info("Unable to create UPnP/IGD, aborting")
        raise ConfigEntryNotReady

    # Save device
    hass.data[DOMAIN][DOMAIN_DEVICES][device.udn] = device

    # Ensure entry has proper unique_id.
    if config_entry.unique_id != device.unique_id:
        hass.config_entries.async_update_entry(
            entry=config_entry,
            unique_id=device.unique_id,
        )

    # Create device registry entry.
    device_registry = await dr.async_get_registry(hass)
    device_registry.async_get_or_create(
        config_entry_id=config_entry.entry_id,
        connections={(dr.CONNECTION_UPNP, device.udn)},
        identifiers={(DOMAIN, device.udn)},
        name=device.name,
        manufacturer=device.manufacturer,
        model=device.model_name,
    )

    # Create sensors.
    _LOGGER.debug("Enabling sensors")
    hass.async_create_task(
        hass.config_entries.async_forward_entry_setup(config_entry, "sensor")
    )

    return True

async def async_unload_entry(
    hass: HomeAssistantType, config_entry: ConfigEntry
) -> bool:
    """Unload a UPnP/IGD device from a config entry."""
    udn = config_entry.data.get(CONFIG_ENTRY_UDN)
    if udn in hass.data[DOMAIN][DOMAIN_DEVICES]:
        del hass.data[DOMAIN][DOMAIN_DEVICES][udn]
    if udn in hass.data[DOMAIN][DOMAIN_COORDINATORS]:
        del hass.data[DOMAIN][DOMAIN_COORDINATORS][udn]

    _LOGGER.debug("Deleting sensors")
    return await hass.config_entries.async_forward_entry_unload(config_entry, "sensor")


import json
import numpy as np
import requests
from zh.model.utils import MNISTLoader

data_loader = MNISTLoader()
data = json.dumps({
    "instances": data_loader.test_data[0:3].tolist()
    })
headers = {"content-type": "application/json"}
json_response = requests.post(
    'http://localhost:8501/v1/models/MLP:predict',
    data=data, headers=headers)
predictions = np.array(json.loads(json_response.text)['predictions'])
print(np.argmax(predictions, axis=-1))
print(data_loader.test_label[0:10])


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2020-09-30 17:45
# @Author  : liukang
# @Site    :
# @File    : 删除链表的节点.py
# @Software: PyCharm

"""
给定单向链表的头指针和一个要删除的节点的值，定义一个函数删除该节点。

返回删除后的链表的头节点。

注意：此题对比原题有改动

示例 1:

输入: head = [4,5,1,9], val = 5
输出: [4,1,9]
解释: 给定你链表中值为5的第二个节点，那么在调用了你的函数之后，该链表应变为 4 -> 1 -> 9.
示例 2:

输入: head = [4,5,1,9], val = 1
输出: [4,5,9]
解释: 给定你链表中值为1的第三个节点，那么在调用了你的函数之后，该链表应变为 4 -> 5 -> 9.

说明：

题目保证链表中节点的值互不相同
若使用 C 或 C++ 语言，你不需要 free 或 delete 被删除的节点

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。

"""

# Definition for singly-linked list.
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    def deleteNode(self, head: ListNode, val: int) -> ListNode:
        p = head
        while p:
            # 对于 初始节点的 特说逻辑判断
            if p.val == val:
                p.val = p.next.val
                p.next = p.next.next
                break

            # 如果是末尾节点需要判断
            if p.next.val == val:
                if p.next.next:
                    p.next = p.next.next
                else:
                    p.next = None
                break

            p = p.next

        return head

    def deleteNodeMethod1(self, head, val):
        # 大佬的链接
        # https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof/solution/shan-chu-lian-biao-de-jie-dian-shuang-zhi-zhen-100/

        # 初始节点，保证根节点一定 不是 val
        root = ListNode(-val)
        root.next = head

        pre = root  # 前指针
        tmp = root.next  # 后指针

        # 判断是否存在该节点
        flag = False

        # 判断 下一个节点是否正常
        while tmp:
            if tmp.val == val:
                flag = True
                break

            # 依次进行遍历查询
            pre = pre.next
            tmp = tmp.next

        # 标志是否发现该节点的 val 数值
        if flag:
            pre.next = tmp.next if tmp.next else None

        return root.next

算法分析和归类/链表/移除框架总结/删除链表的节点.py


"""query.start_running_time

Revision ID: a6c18f869a4e
Revises: 979c03af3341
Create Date: 2017-03-28 11:28:41.387182

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = 'a6c18f869a4e'
down_revision = '979c03af3341'

def upgrade():
    op.add_column(
        'query',
        sa.Column(
            'start_running_time',
            sa.Numeric(precision=20, scale=6),
            nullable=True,
        ),
    )

def downgrade():
    op.drop_column('query', 'start_running_time')


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

# Submitted By :
#   Navpreet Singh
#   ns4767@nyu.edu

# define the class of states for both terminal and non terminal

class state:

    top = 0
    bottom = 10**6

    def __init__(self,t,n,r):
        self.terminal = t
        self.reward = r
        self.state_no = n
        self.actions = 0
        self.t_p = []

        if t:
            if r<state.bottom:
                state.bottom=r
            if r>state.top:
                state.top=r

    def add_action(self):
        self.actions+=1
        self.t_p.append({})

    def add_tp(self,a,s,p):
        self.t_p[s][a]=p

# choosing an action randomly factoring M for explore/exploit tradeoff

def chooseAction(s,count,total,M):
    n = s.actions
    for i in range(0,n):
        if count[s.state_no][i]==0:
            return i
    avg = []
    for i in range(0,n):
        avg.append(total[s.state_no][i]/count[s.state_no][i])
    bottom = state.bottom
    top = state.top
    savg = []
    for i in range(0,n):
        savg.append(0.25 + 0.75*(avg[i]-bottom)/(top-bottom))
    c = 0
    for i in range(0,n):
        c += count[s.state_no][i]
    up = []
    for i in range(0,n):
        up.append(savg[i]**(c/M))
    norm = 0
    for i in range(0,n):
        norm += up[i]
    p = []
    for i in range(0,n):
        p.append(up[i]/norm)

    choice = random.choices(p,weights=p)
    return p.index(choice[0])

# play 1 round given the state and choosing a random action and saving its performance result to exploit later.

def play_round(states,s,count,total,M):
    pairs = []
    while not s.terminal:
        a = chooseAction(s,count,total,M)
        pairs.append((s.state_no,a))
        s1 = random.choices(list(s.t_p[a].keys()),weights=list(s.t_p[a].values()))
        s = states[s1[0]]
    for k in pairs:
        i,j=k
        count[i][j]+=1
        total[i][j]+=s.reward

# print the output in the given format as described in the problem statement

def print_output(count,total,rn):
    if rn==0:
        return
    print("After {} rounds\n".format(rn))
    print("Count:")
    for i in range(len(count)):
        for j in range(len(count[i])):
            print("[{},{}]={}. ".format(i,j,count[i][j]),end="")
        print("")
    print("\nTotal:")
    for i in range(len(count)):
        for j in range(len(count[i])):
            print("[{},{}]={}. ".format(i,j,total[i][j]),end="")
        print("")
    print("\nBest Action :  ",end="")
    for i in range(len(count)):
        if 0 in count[i]:
            print("{}:U. ".format(i),end="")
        else:
            print("{}:{}. ".format(i,count[i].index(max(count[i]))),end="")
    print("\n")

# main function for using reinforcement learning to solve mdp playing r rounds.

def rl_mdp(states,count,total,M,v,r):

    for i in range(r):
        play_round(states,random.choices(states[:n])[0],count,total,M)
        if v != 0 and i%v == 0 :
            print_output(count,total,i)
            print("")
    print_output(count,total,r)

import random

if __name__ == "__main__":

    # take inputs

    with open('input.txt', 'r') as file:
        inputs = file.readlines()

    n,t,r,v,M = list(map(int,inputs[0].split()))
    states = []

    for s in range(n):
        states.append(state(False,s,0))

    inp = list(map(int,inputs[1].split()))
    i=0
    while i < len(inp):
        states.append(state(True,inp[i],inp[i+1]))
        i+=2

    for i in range(2,len(inputs)):
        inp = list(inputs[i].split())
        s1 = int(inp[0][0])
        a = int(inp[0][2])
        states[s1].add_action()
        j=1
        while(j<len(inp)):
            s2=int(inp[j])
            tp=float(inp[j+1])
            j+=2
            states[s1].add_tp(s2,a,tp)

    # define data structure to keep track of learning process

    count = []
    total = []

    for s in range(n):
        count.append([])
        total.append([])
        for _ in range(states[s].actions):
            count[s].append(0)
            total[s].append(0)

    # start the reinforcement learning for n rounds and according to M parameter

    rl_mdp(states,count,total,M,v,r)


from .util import BASE_URL, get_paginated_results, validate_keywords
import requests

def jurisdictions(max_pages=1, **kwargs):
    if max_pages < 1:
        raise ValueError('max_pages must be an integer greater than 1')

    expected_keywords = {'id', 'name', 'name_long', 'whitelisted', 'slug', 'cursor'}
    validate_keywords(expected_keywords, kwargs)

    api_call = BASE_URL + 'jurisdictions/'
    return get_paginated_results(max_pages, api_call)


#checks enriched tf's for differential gene expression from RNA-seq data
import argparse
def parse_args():
    parser=argparse.ArgumentParser(description="check enriched tf's for differential gene expression from RNA-seq data")
    parser.add_argument("--motif_hits_h3k27me3")
    parser.add_argument("--earlyG1_df")
    parser.add_argument("--lateG1_df")
    parser.add_argument("--SG2M_df")
    parser.add_argument("--outf")
    return parser.parse_args()

def main():
    args=parse_args()
    earlyg1=open(args.earlyG1_df,'r').read().strip().split('\n')
    lateg1=open(args.lateG1_df,'r').read().strip().split('\n')
    sg2m=open(args.SG2M_df,'r').read().strip().split('\n')
    #create a dictionary of genes w/ differential expression values in given timepoints
    data_dict=dict()
    data_dict['earlyG1']=earlyg1
    data_dict['lateG1']=lateg1
    data_dict['sg2m']=sg2m
    diff_dict=dict()
    all_genes=dict()

    for timepoint in data_dict:
        for line in data_dict[timepoint][1::]:
            tokens=line.split('\t')
            gene=tokens[0]
            fc=float(tokens[1])
            adj_pval=float(tokens[-1])
            #check for significance
            if ((abs(fc)>=1) and (adj_pval<=0.05)):
                if gene not in diff_dict:
                    diff_dict[gene]=dict()
                else:
                    diff_dict[gene][timepoint]=[fc,adj_pval]
            if gene not in all_genes:
                all_genes[gene]=dict()
            else:
                all_genes[gene][timepoint]=[fc,adj_pval]

    print("generated differential dict")
    motif_hits=open(args.motif_hits_h3k27me3,'r').read().strip().split('\n')

    #write differential TF's to output file
    outf=open(args.outf,'w')
    outf.write(motif_hits[0]+'\t'+'earlyG1_fc'+'\t'+'earlyG1_pval'+'\t'+'lateG1_fc'+'\t'+'lateG1_pval'+'\t'+'SG2M_fc'+'\t'+'SG2M_pval'+'\n')
    outf_missing=open(args.outf+'.missing','w')
    outf_missing.write(motif_hits[0]+'\n')

    for line in motif_hits[1::]:
        tokens=line.split('\t')
        motif=tokens[0].upper()
        if motif in diff_dict:
            outf.write('\t'.join(tokens))
            earlyG1_fc='NA'
            earlyG1_pval='NA'
            if 'earlyG1' in diff_dict[motif]:
                earlyG1_fc=str(diff_dict[motif]['earlyG1'][0])
                earlyG1_pval=str(diff_dict[motif]['earlyG1'][1])
            outf.write('\t'+earlyG1_fc+'\t'+earlyG1_pval)

            lateG1_fc='NA'
            lateG1_pval='NA'
            if 'lateG1' in diff_dict[motif]:
                lateG1_fc=str(diff_dict[motif]['lateG1'][0])
                lateG1_pval=str(diff_dict[motif]['lateG1'][1])
            outf.write('\t'+lateG1_fc+'\t'+lateG1_pval)

            SG2M_fc='NA'
            SG2M_pval='NA'
            if 'SG2M' in diff_dict[motif]:
                SG2M_fc=str(diff_dict[motif]['SG2M'][0])
                SG2M_pval=str(diff_dict[motif]['SG2M'][1])
            outf.write('\t'+SG2M_fc+'\t'+SG2M_pval)
            outf.write('\n')
        elif (motif not in all_genes) :
            outf_missing.write(line+'\n')

if __name__=="__main__":
    main()


import numpy as np
from scipy import stats
from scipy.stats.tests.common_tests import (
    check_normalization, check_moment, check_mean_expect, check_var_expect,
    check_skew_expect, check_kurt_expect, check_edge_support,
    check_random_state_property, check_pickling)

from skypy.galaxy.redshift import smail, herbel_redshift, herbel_pdf
from unittest.mock import patch
import scipy.stats
import scipy.integrate

def test_smail():
    # freeze a distribution with parameters
    args = (1.3, 2.0, 1.5)
    dist = smail(*args)

    # check that PDF is normalised
    check_normalization(smail, args, 'smail')

    # check CDF and SF
    assert np.isclose(dist.cdf(3.) + dist.sf(3.), 1.)

    # check inverse CDF and SF
    assert np.isclose(dist.ppf(dist.cdf(4.)), 4.)
    assert np.isclose(dist.isf(dist.sf(5.)), 5.)

    # check median matches parameter
    zm = np.random.rand(10)
    assert np.allclose(smail.median(zm, 2.0, 1.5), zm)

    # check moments
    m, v, s, k = dist.stats(moments='mvsk')
    check_mean_expect(smail, args, m, 'smail')
    check_var_expect(smail, args, m, v, 'smail')
    check_skew_expect(smail, args, m, v, s, 'smail')
    check_kurt_expect(smail, args, m, v, k, 'smail')
    check_moment(smail, args, m, v, 'smail')

    # check other properties
    check_edge_support(smail, args)
    check_random_state_property(smail, args)
    check_pickling(smail, args)

    # sample a single redshift
    rvs = dist.rvs()
    assert np.isscalar(rvs)

    # sample 10 reshifts
    rvs = dist.rvs(size=10)
    assert rvs.shape == (10,)

    # sample with implicit sizes
    zm, a, b = np.ones(5), np.ones((7, 5)), np.ones((13, 7, 5))
    rvs = smail.rvs(z_median=zm, alpha=a, beta=b)
    assert rvs.shape == np.broadcast(zm, a, b).shape

    # check sampling against own CDF
    D, p = stats.kstest(smail.rvs, smail.cdf, args=args, N=1000)
    assert p > 0.01, 'D = {}, p = {}'.format(D, p)

    # check sampling, for alpha=0, beta=1, the distribution is exponential
    D, p = stats.kstest(smail.rvs(0.69315, 1e-100, 1., size=1000), 'expon')
    assert p > 0.01, 'D = {}, p = {}'.format(D, p)

    # check sampling, for beta=1, the distribution matches a gamma distribution
    D, p = stats.kstest(smail.rvs(2.674, 2, 1, size=1000), 'gamma', args=(3,))
    assert p > 0.01, 'D = {}, p = {}'.format(D, p)

    # check sampling, the distribution is a generalised gamma distribution
    D, p = stats.kstest(smail.rvs(0.832555, 1, 2, size=1000),
                        'gengamma', args=(1, 2))
    assert p > 0.01, 'D = {}, p = {}'.format(D, p)

def test_herbel_pdf():
    from astropy.cosmology import FlatLambdaCDM
    cosmology = FlatLambdaCDM(H0=70, Om0=0.3, Tcmb0=2.725)
    pdf = herbel_pdf(np.array([0.01, 0.5, 1, 2]),
                     -0.5, -0.70596888,
                     0.0035097, -0.70798041,
                     -20.37196157, cosmology, np.power(10, -0.4 * -16.0))
    result = np.array(
        [4.09063927e+04, 4.45083420e+07, 7.26629445e+07, 5.40766813e+07])
    np.testing.assert_allclose(pdf, result)

# Test whether principle of the interpolation works. Let PDF return the PDF
# of a Gaussian and sample from the corresponding CDF. Then compare the
# first three moment of the returned sample with the Gaussian one.
@patch('skypy.galaxy.redshift.herbel_pdf')
def test_herbel_redshift_gauss(herbel_pdf):
    from astropy.cosmology import FlatLambdaCDM
    cosmology = FlatLambdaCDM(H0=70, Om0=0.3, Tcmb0=2.725)
    resolution = 100
    x = np.linspace(-5, 5, resolution)
    herbel_pdf.side_effect = [scipy.stats.norm.pdf(x)]
    sample = herbel_redshift(alpha=-1.3, a_phi=-0.10268436,
                             a_m=-0.9408582, b_phi=0.00370253,
                             b_m=-20.40492365, cosmology=cosmology,
                             low=-5., high=5.0, size=1000000,
                             resolution=resolution)
    p_value = scipy.stats.kstest(sample, 'norm')[1]
    assert p_value >= 0.01

# Test that the sampling follows the pdf of Schechter function.
def test_herbel_redshift_sampling():
    from astropy.cosmology import FlatLambdaCDM
    cosmology = FlatLambdaCDM(H0=70, Om0=0.3, Tcmb0=2.725)
    sample = herbel_redshift(alpha=-1.3, a_phi=-0.10268436,
                             a_m=-0.9408582, b_phi=0.00370253,
                             b_m=-20.40492365, cosmology=cosmology,
                             size=1000)

    def calc_cdf(z):
        pdf = herbel_pdf(z, alpha=-1.3,
                         a_phi=-0.10268436,
                         a_m=-0.9408582,
                         b_phi=0.00370253,
                         b_m=-20.40492365,
                         cosmology=cosmology,
                         luminosity_min=2511886.4315095823)
        cdf = scipy.integrate.cumtrapz(pdf, z, initial=0)
        cdf = cdf / cdf[-1]
        return cdf

    p_value = scipy.stats.kstest(sample, calc_cdf)[1]
    assert p_value >= 0.01


from flask import Flask, render_template, Response
from datetime import datetime
import io
import cbpro
# import matplotlib.pyplot as plt
# import matplotlib
import pandas as pd
import yaml
import math
import os
import time
# from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
# from matplotlib.backends.backend_svg import FigureCanvasSVG
# from matplotlib.figure import Figure
from apscheduler.schedulers.background import BackgroundScheduler

import plotly
import plotly.graph_objs as go
import plotly.express as px
import json

BUY_LOCK = False
PLT_LOCK = True

product = []
STATE_P = []

def main():

    with open('app/state.yaml') as f:
        STATE = yaml.load(f,Loader=yaml.FullLoader)

    # STATE['bought'] = not STATE['bought']

    #print(auth_client.get_accounts())
    balance = float(auth_client.get_account("c7e286f1-e04f-46fb-ace5-34a27245c95f")['available'])
    balance = math.floor(balance*100)/100.0

    bitcoin = float(auth_client.get_account("e02112f4-5daf-4970-9ce1-563e5460e523")['available'])

    #print(balance)

    ##print(auth_client.get_product_order_book('BTC-USD'))

    #print(auth_client.get_product_ticker(product_id='BTC-USD'))

    ##print(auth_client.get_product_historic_rates('BTC-USD',granularity=60))

    #print(auth_client.get_product_24hr_stats('BTC-USD'))

    #this should be done with web socket instead if polling frequently?
    items = auth_client.get_product_historic_rates('BTC-USD',granularity=300)

    x = []
    y = []
    for item in items[::-1]:
        #plt.plot(item[0],item[4],'.')
        x.append(item[0])
        y.append(item[4])
    # plt.plot(x,y,'-g')
    price = pd.Series(y)

    #sma1 = ta.volatility.bollinger_mavg(price, n=n1, fillna=False)
    # for i in range(len(x)):
    #     plt.plot(x[i],sma1[i],'.')

    global product
    product = pd.DataFrame({'time' : x, 'price': y})

    # n1 = 8
    # n2 = 20
    # n1 = 20
    # n2 = 45
    n1 = 25
    n2 = 50
    product['SMA1'] = product['price'].rolling(n1).mean()
    product['SMA2'] = product['price'].rolling(n2).mean()

    stance = STATE['bought']
    money = balance
    btc = bitcoin
    numbuy = STATE['numbuy']
    numsell = STATE['numsell']
    #print(money)
    #.5% == *.005
    # for t,s1,s2,p in zip(product['time'][n2:],product['SMA1'][n2:],product['SMA2'][n2:],product['price'][n2:]):
    #     if not stance and (s1>s2):
    #         stance = True
    #         plt.plot(t,p,'.g')
    #         btc += (money*.995)/p #only 99.5% goes in
    #         money -= money ##fix this
    #         print(str(money) + '    ' + str(btc))
    #     elif stance and (s2>s1):
    #         stance = False
    #         plt.plot(t,p,'.r')
    #         money += btc*p*.995 #only 99.5% comes back out
    #         btc -= btc
    #         print(str(money) + '    ' + str(btc))

    s1 = product['SMA1'].iloc[-1]
    s2 = product['SMA2'].iloc[-1]
    #t = product['time'].iloc[-1]
    # print(stance)
    # print(s1)
    # print(s2)

    if not stance and (s1 > s2):

        print('Buying BTC with funds: ' + str(money))
        if not BUY_LOCK:
            auth_client.place_market_order(product_id='BTC-USD',side='buy',funds = money)
            stance = True
            numbuy+=1
            STATE['buylocs']['locs'].append(float(product['time'].iloc[-1]))
            STATE['buylocs']['vals'].append(float(product['price'].iloc[-1]))
    elif stance and (s2>s1):

        print('Selling BTC with size: ' + str(btc))
        if not BUY_LOCK:
            auth_client.place_market_order(product_id='BTC-USD',side='sell',size = btc)
            stance = False
            numsell+=1
            STATE['selllocs']['locs'].append(float(product['time'].iloc[-1]))
            STATE['selllocs']['vals'].append(float(product['price'].iloc[-1]))

    #update STATE

    # print('---')
    # print(money)
    # print(btc)
    # print(stance)
    if not PLT_LOCK:
        plt.show()

    #time.sleep(5)
    date = datetime.now()
    mpldate = matplotlib.dates.date2num(date)
    #print(date.isoformat())

    balance = float(auth_client.get_account("c7e286f1-e04f-46fb-ace5-34a27245c95f")['available'])
    bitcoin = float(auth_client.get_account("e02112f4-5daf-4970-9ce1-563e5460e523")['available'])

    STATE['bought'] = stance
    STATE['money'] = balance
    STATE['BTC'] = bitcoin
    STATE['last'] = date.isoformat()
    STATE['numbuy'] = numbuy
    STATE['numsell'] = numsell
    STATE['moneyOT'].append(balance)
    STATE['BTCOT'].append(bitcoin)
    STATE['timeOT'].append(mpldate)
    with open('app/state.yaml', 'w') as f:
        yaml.dump(STATE, f)
        print('Updated YAML')

    global STATE_P
    STATE_P = STATE
    # return STATE

def create_plot_p():
    # fig = px.line(product,x='time',y=['price','SMA1','SMA2'])
    #
    # color_discrete_map = {'vals': 'rgb(255,0,0)'}
    # fig2 = go.Scatter(x=STATE_P['buylocs']['locs'],y=STATE_P['buylocs']['vals'],mode='markers',marker_color='rgba(0, 255, 0, .8)')
    # fig3 = go.Scatter(x=STATE_P['selllocs']['locs'],y=STATE_P['selllocs']['vals'],mode='markers',marker_color='rgba(255, 0, 0, .8)')
    # data = [
    #     fig.data[0],fig.data[1],fig.data[2],fig2,fig3
    # ]

    fig = go.Figure()
    strstamps = []
    for elem in product['time']:
        strstamps.append(datetime.fromtimestamp(elem).strftime('%Y-%m-%d %H:%M:%S'))
    fig.add_trace(go.Scatter(x=strstamps,y=product['price'],mode='lines',name='price',marker_color='rgba(0,135,0,.6)'))
    fig.add_trace(go.Scatter(x=strstamps,y=product['SMA1'],mode='lines',name='SMA1',marker_color='rgba(255,0,0,.6)'))
    fig.add_trace(go.Scatter(x=strstamps,y=product['SMA2'],mode='lines',name='SMA2',marker_color='rgba(0,0,255,.6)'))

    strstamps = []
    for elem in STATE_P['buylocs']['locs']:
        strstamps.append(datetime.fromtimestamp(elem).strftime('%Y-%m-%d %H:%M:%S'))
    fig.add_trace(go.Scatter(x=strstamps,y=STATE_P['buylocs']['vals'],name='buy',mode='markers',marker_color='rgba(0, 245, 95, 1)'))
    strstamps = []
    for elem in STATE_P['selllocs']['locs']:
        strstamps.append(datetime.fromtimestamp(elem).strftime('%Y-%m-%d %H:%M:%S'))
    fig.add_trace(go.Scatter(x=strstamps,y=STATE_P['selllocs']['vals'],name='sell',mode='markers',marker_color='rgba(255, 0, 0, .9)'))
    fig.update_layout(autosize=True,hovermode='x unified',title='Overview')
    data = fig
    graphJSON = json.dumps(data, cls=plotly.utils.PlotlyJSONEncoder)

    return graphJSON

def create_plot_m():
    # fig = px.line(product,x='time',y=['price','SMA1','SMA2'])
    #
    # color_discrete_map = {'vals': 'rgb(255,0,0)'}
    # fig2 = go.Scatter(x=STATE_P['buylocs']['locs'],y=STATE_P['buylocs']['vals'],mode='markers',marker_color='rgba(0, 255, 0, .8)')
    # fig3 = go.Scatter(x=STATE_P['selllocs']['locs'],y=STATE_P['selllocs']['vals'],mode='markers',marker_color='rgba(255, 0, 0, .8)')
    # data = [
    #     fig.data[0],fig.data[1],fig.data[2],fig2,fig3
    # ]

    fig = go.Figure()

    newdict = {'timeOT' : [], 'moneyOT': []}
    for time,money in zip(STATE_P['timeOT'],STATE_P['moneyOT']):
        if money > .1:
            newdict['timeOT'].append(time)
            newdict['moneyOT'].append(money)

    strstamps = []
    for elem in newdict['timeOT']:
        strstamps.append(matplotlib.dates.num2date(elem))

    fig.add_trace(go.Scatter(x=strstamps,y=newdict['moneyOT'],mode='lines',name='money',marker_color='rgba(0,155,0,.6)'))
    fig.update_layout(hovermode='x unified',title='Money')

    data = fig
    graphJSON = json.dumps(data, cls=plotly.utils.PlotlyJSONEncoder)

    return graphJSON

def create_plot_b():
    # fig = px.line(product,x='time',y=['price','SMA1','SMA2'])
    #
    # color_discrete_map = {'vals': 'rgb(255,0,0)'}
    # fig2 = go.Scatter(x=STATE_P['buylocs']['locs'],y=STATE_P['buylocs']['vals'],mode='markers',marker_color='rgba(0, 255, 0, .8)')
    # fig3 = go.Scatter(x=STATE_P['selllocs']['locs'],y=STATE_P['selllocs']['vals'],mode='markers',marker_color='rgba(255, 0, 0, .8)')
    # data = [
    #     fig.data[0],fig.data[1],fig.data[2],fig2,fig3
    # ]

    fig = go.Figure()
    newdict = {'timeOT' : [], 'BTCOT': []}
    for time,money in zip(STATE_P['timeOT'],STATE_P['BTCOT']):
        if money != 0.0:
            newdict['timeOT'].append(time)
            newdict['BTCOT'].append(money)

    strstamps = []
    for elem in newdict['timeOT']:
        strstamps.append(matplotlib.dates.num2date(elem))
    fig.add_trace(go.Scatter(x=strstamps,y=newdict['BTCOT'],mode='lines',name='money',marker_color='rgba(0,155,0,.6)'))
    fig.update_layout(hovermode='x unified',title='BTC')

    data = fig
    graphJSON = json.dumps(data, cls=plotly.utils.PlotlyJSONEncoder)

    return graphJSON

sched = BackgroundScheduler(daemon=True)
sched.add_job(main,'interval',minutes=5)
sched.start()

app = Flask(__name__,template_folder='templates')

@app.route("/")
def home_view():
    # global STATE_P
    # STATE_P = main()
    # return "
Welcome to " + str(stance) + "Geeks for Geeks
"
    main()
    plot_p = create_plot_p()
    plot_m = create_plot_m()
    plot_b = create_plot_b()
    return render_template('index.html',plot_p=plot_p, plot_m=plot_m, plot_b=plot_b)

@app.route('/prices.png')
def plot_prices():
    fig = Figure()
    axis = fig.add_subplot(1,1,1)
    axis.plot(product['time'],product['price'],'-g')
    axis.plot(product['time'],product['SMA1'],'-r')
    axis.plot(product['time'],product['SMA2'],'-b')
    axis.plot(STATE_P['buylocs']['locs'],STATE_P['buylocs']['vals'],'.y')
    axis.plot(STATE_P['selllocs']['locs'],STATE_P['selllocs']['vals'],'.r')
    output = io.BytesIO()
    FigureCanvasSVG(fig).print_svg(output)
    return Response(output.getvalue(), mimetype='image/svg+xml')

@app.route('/money.png')
def plot_money():
    fig = Figure()
    axis = fig.add_subplot(1,1,1)
    axis.plot_date(STATE_P['timeOT'],STATE_P['moneyOT'],'-')
    output = io.BytesIO()
    FigureCanvasSVG(fig).print_svg(output)
    return Response(output.getvalue(), mimetype='image/svg+xml')

@app.route('/btc.png')
def plot_btc():
    fig = Figure()
    axis = fig.add_subplot(1,1,1)
    axis.plot_date(STATE_P['timeOT'],STATE_P['BTCOT'],'-')
    output = io.BytesIO()
    FigureCanvasSVG(fig).print_svg(output)
    return Response(output.getvalue(), mimetype='image/svg+xml')


class TVector:
    def __init__(self, *args):
        self.matrix = list(map(float, args))

    @property
    def len(self):
        return len(self.matrix)

    def parallel(self, other):
        k = self.matrix[0] / other.matrix[0]
        for i in range(1, self.len):
            if self.matrix[i] / other.matrix[i] != k:
                return False
        return True

    def perpendicularity(self, other):
        d = 0
        for i in range(self.len):
            d += self.matrix[i] * other.matrix[i]
        return True if d == 0 else False

    def length(self):
        return (sum([el**2 for el in self.matrix]))**0.5

    def __iadd__(self, other):
        return self.length() + other

class TVector2(TVector):
    def __init__(self, x, y):
        super().__init__(x, y)

class TVector3(TVector):
    def __init__(self, x, y, z):
        super().__init__(x, y, z)

f = [TVector3(1, 2, 3), TVector2(1, 2), TVector3(2, 4, 6), TVector2(2, 4), TVector2(0, 23), TVector3(14, 14, 1),
     TVector3(4, 4, 1)]

for i in range(7):
    if type(f[i]) == TVector2:
        f_k_2 = f[i]
        break

for i in range(7):
    if type(f[i]) == TVector3:
        f_k_3 = f[i]
        break

f2 = sum([el.length() for el in f if type(el) == TVector2 and el.parallel(f_k_2)])
f3 = sum([el.length() for el in f if type(el) == TVector3 and el.parallel(f_k_3)])
print('sum vector 2 = {0}\nsum vector 3 = {1}'.format(f2, f3))


PC_items = {
    "HP":20,
    "DELL":50,
    "MACBOOK":12,
    "ASUS":30,
    "ACER":"unknown",
    "TOSHIBA":10,
    "FUJITSU":15,
    "ALIENWARE":5
}

PC_prices = {
    "HP":600,
    "DELL":650,
    "MACBOOK":12000,
    "ASUS":400,
    "ACER":350,
    "TOSHIBA":600,
    "FUJITSU":900,
    "ALIENWARE":1000
}

# In ra gia tien ten hang
a = input("ten hang: ")
print(PC_prices[a])

# In ra so tien khach hang can tra
a = input("ten hang: ")
b = int(input("so luong: "))
print(PC_prices[a]*b)

#tru di so luong hang da ban
PC_items[a] -= b
print(PC_items)


#DO WE NEED SHEEBANG????
import tkinter as tk
from tkinter import *
from tkinter import ttk

config_path = '/usr/etc/scada/config'
sys.path.append(config_path)

database_path = '/usr/etc/scada/utils'
sys.path.append(database_path)
#import config
import yaml
import collections
import sys, os
import datetime

import ctypes  # for screen size
from CheapSummary_GUI import CheapGUI
from ExpensiveSummary_GUI import ExpensiveGUI

LARGE_FONT = ("Times New Roman", 12)

class Main(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        self.cheapSummaryVars = {
            "filterBy" : " ",
            "session" : " "
        }

        # self.screenWidth = self.winfo_screenwidth() # Get current width of canvas
        # self.screenHeight = self.winfo_screenheight() # Get current height of canvas

        self.screenWidth = 700
        self.screenHeight = 700

        # set screen to full size
        self.container = tk.Frame(self, width = self.screenWidth, height = self.screenHeight)
        self.container.grid_propagate(False)
        self.container.pack(side="top", fill="both", expand=True)

        self.container.grid_rowconfigure(0, weight=1)
        self.container.grid_columnconfigure(0, weight=1)

        self.frames = {}

        # for F in (CheapGUI, ExpensiveGUI):
        # frame = F(self.container, self)
        frame = CheapGUI(self.container, self)
        self.frames[CheapGUI] = frame
        frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(CheapGUI)

    def show_frame(self, page_name):
        frame = self.frames[page_name]
        frame.tkraise()

    # create a new window for Expensive GUI
    def new_window(self):
        self.newWindow = tk.Toplevel(self)
        frame = ExpensiveGUI(self.newWindow, self)
        self.frames[ExpensiveGUI] = frame
        frame.grid(row=0, column=0, sticky="nsew")

app = Main()
app.mainloop()


# coding: utf-8

# NOTE! The code below is not-ready! It is based on https://github.com/ottokart/punctuator2

import sys,os
#import pdb

os.environ['LD_LIBRARY_PATH'] = '/usr/local/cuda-9.0/lib64/'
os.environ["CUDA_VISIBLE_DEVICES"]="0" # NOTE! But what if I want to use any available one?

#print('LD_LIBRARY_PATH: ', os.environ['LD_LIBRARY_PATH'])
import numpy as np
import math
import keras
from keras.layers import Input, Masking, Embedding, GRU, Dense, Activation, Permute, RepeatVector, Bidirectional, Add, Multiply, TimeDistributed, merge, Lambda, Reshape, Dropout
from keras.models import Model
from keras.utils.np_utils import to_categorical
from keras.preprocessing.sequence import pad_sequences
from keras.callbacks import TensorBoard, EarlyStopping, ModelCheckpoint, TerminateOnNaN
from keras import backend as K
from keras import optimizers
sys.path.insert(0, 'local/punctuation')
import data

EMBEDDING_DIM = 256 # OK? For English vocabulary it is often lower. For my rnnlm it is 1024
MINIBATCH_SIZE = 128
DROP_RATE = 0.25
TIME_STEPS = data.MAX_SEQUENCE_LEN
LABEL_DIM = len(data.PUNCTUATION_VOCABULARY)
PADDING_VALUE = len(data.read_vocabulary(data.WORD_VOCAB_FILE)) +10
EPOCHS = 10
#pdb.set_trace

def get_data(file_name,shuffle):
    '''Get training and evaluation data'''
    dataset = data.load(file_name)
    if shuffle:
        np.random.shuffle(dataset)
    x=[seq[0] for seq in dataset]
    y=[seq[1] for seq in dataset]
    #tokenizedLabels = to_categorical(np.asarray(y),num_classes=LABEL_DIM)
    #return np.asarray(x).reshape((len(x),data.MAX_SEQUENCE_LEN,1)), to_categorical(np.asarray(y),num_classes=LABEL_DIM) #np.asarray(y)
    return np.asarray(x), to_categorical(np.asarray(y),num_classes=LABEL_DIM) #np.asarray(y)

def perplexity(y_true, y_pred):
    """
    The perplexity metric. From: https://github.com/keras-team/keras/issues/8267
    """
    cross_entropy = K.categorical_crossentropy(y_true, y_pred)
    perplexity = K.exp(cross_entropy)
    return perplexity

def createModel(num_hidden):
    '''Almost entirely from https://github.com/vackosar/keras-punctuator/blob/master/punctuator.py'''
    sys.stderr.write('Creating model.' + "\n")

    inputs = Input(shape=(data.MAX_SEQUENCE_LEN,))
    masked_inputs = Masking(mask_value=PADDING_VALUE)(inputs) # Masks a sequence by using a mask value to skip timesteps. Needed to predict variable length sequences
    #inputs = Input(shape=(data.MAX_SEQUENCE_LEN,1))
    e = Embedding(1 + data.MAX_WORD_VOCABULARY_SIZE, EMBEDDING_DIM, input_length=data.MAX_SEQUENCE_LEN)(masked_inputs)

    #context = GRU(num_hidden, activation='tanh', recurrent_activation='hard_sigmoid', use_bias=True, kernel_initializer='glorot_uniform', return_sequences=True)(e)
    context = Bidirectional(GRU(num_hidden, activation='tanh', recurrent_activation='hard_sigmoid', use_bias=True, kernel_initializer='glorot_uniform', return_sequences=True))(e)
    context = Dropout(DROP_RATE)(context)
    context = GRU(num_hidden, return_sequences=True)(context)
    context = Dropout(DROP_RATE)(context)
    y = TimeDistributed(Dense(LABEL_DIM, activation='softmax'))(context)

    model = Model(inputs=inputs, outputs=y)

    rmsprop = optimizers.RMSprop(lr=0.02,clipnorm=2.)
    model.compile(optimizer=rmsprop, loss='categorical_crossentropy', metrics=['categorical_accuracy',perplexity]) # , 'f1score', 'precision', 'recall'
    norm = math.sqrt(sum(numpy.sum(K.get_value(w)) for w in model.optimizer.weights))
    print("The gradient norm: ", norm)
    print(model.summary())
    return model

def trainModel(model, xTrain, yTrain, xVal, yVal, model_file, callbacks=None, verbose=False):
    sys.stderr.write("Training" + "\n")

    #From https://github.com/flomlo/ntm_keras/blob/master/testing_utils.py
    tensorboard = TensorBoard(log_dir=model_path + '/logs', batch_size=MINIBATCH_SIZE, histogram_freq=1, write_grads=True, write_images=True) #, embeddings_freq=1, embeddings_layer_names='embedding', embeddings_metadata=model_path + '/logs' + 'metadata.tsv', embeddings_data=xTrain)
    checkpoint = ModelCheckpoint(model_path + "/logs/model.ckpt.{epoch:04d}.hdf5", monitor='val_loss', verbose=1, save_best_only=True, period=1)
    early_stopping = EarlyStopping(monitor='val_loss', min_delta=0, patience=0, verbose=1)
    cbs = [tensorboard, early_stopping, checkpoint] # TerminateOnNaN,
    if verbose:
        for i in range(0, EPOCHS):
            model.fit(xTrain, yTrain, validation_data=(xVal, yVal), epochs=i+1, batch_size=MINIBATCH_SIZE, callbacks=cbs, initial_epoch=i)
            print("currently at epoch {0}".format(i+1))
            # Some test function
            model.save(model_file + '{epoch:02d}.hdf5')
    else:
        model.fit(xTrain, yTrain, validation_data=(xVal, yVal), epochs=EPOCHS, batch_size=MINIBATCH_SIZE, callbacks=cbs)
        model.save(model_file + '.hdf5')
    return model

if __name__ == "__main__":

    if len(sys.argv) > 1:
        model_path = os.path.abspath(sys.argv[1])
    else:
        sys.exit("'Model path' argument missing!")

    if len(sys.argv) > 2:
        model_name = sys.argv[2]
    else:
        sys.exit("'Model name' argument missing!")

    if len(sys.argv) > 3:
        num_hidden = int(sys.argv[3])
    else:
        sys.exit("'Hidden layer size' argument missing!")

    if len(sys.argv) > 4:
        initial_learning_rate = float(sys.argv[4])
    else:
        sys.exit("'Learning rate' argument missing!")

    model_file_name = "Model_%s_h%d_lr%s" % (model_name, num_hidden, initial_learning_rate)
    model_file = model_path + "/" + model_file_name

    print(num_hidden, initial_learning_rate, model_file)

    word_vocabulary = data.read_vocabulary(data.WORD_VOCAB_FILE)
    punctuation_vocabulary = data.iterable_to_dict(data.PUNCTUATION_VOCABULARY)
    #print(punctuation_vocabulary)

    continue_with_previous = False
    if os.path.isfile(model_file):

        print("Found an existing model with the name %s" % model_file)
        sys.exit()

    #print("train file: ",data.TRAIN_FILE)
    xTrain, yTrain = get_data(data.TRAIN_FILE,True)
    xVal, yVal = get_data(data.DEV_FILE,False)

    #print('Shape of data tensor:', xTrain.shape)
    #print('Shape of label tensor:', yTrain.shape)
    #print('xTrain.shape[0]: ', xTrain.shape[0])
    # with open('xTrain.tmp','w',encoding='utf-8') as fout:
    #     print(xTrain, file=fout)
    # with open('yTrain.tmp','w',encoding='utf-8') as fout2:
    #     print(yTrain, file=fout2)
    # print('xTrain: ', xTrain[:5])
    # print('yTrain: ', yTrain[:5])
    # print('xVal: ', xVal[:5])
    # print('yVal: ', yVal[:5])

    model = createModel(num_hidden)
    trainModel(model, xTrain, yTrain, xVal, yVal, model_file)