import math
import numpy as np
from grooming.Algorithm.NodeStructure import Nodestructureservices
from pydantic import BaseModel
from grooming.schemas import LowRateGrooming, GroomingLightPath, GroomingOutput, RemaningServices, GroomOutType, RoutingType, NodeStructure
from pulp import LpProblem, LpMinimize, LpVariable, lpSum, LpStatus, PULP_CBC_CMD
from pydantic import BaseModel

def MP2X(Services_lower10):
    """
        This function packs the MP2X input services to 10G service.

        Advantages:
            - Optimum packing by means of ILP

        :param <Services_lower10>: <input>
        :type <list>: <each memeber of list is a tuple included service id and the capacity of service>

        :param <prob>: <LP problem>
        :type <class>: <ILP is solved by means of this class>

        :param <max_number_device>: <maximum number of device>
        :type <integer>: <>

        :param <NO_service_lower10>: <number of services in input parameter>
        :type <integer>: <length of Services_lower10>

        :param <Output>: <maximum number of device>
        :type <list>: <list of list which is included  tuples with  service id and the capacity of service>

    """
    prob = LpProblem("grooming", LpMinimize )
    B=10                    #u
    max_port=16
    y=[]
    min_number_of_service=3

        #Services_lower10=[0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 2.5, 2.5, 0.62, 0.62, 0.62, 0.62, 0.62]
        #Services_lower10=[2.5,2.5,2.5,2.5,2.5,2.5,2.5,2.5,2.5,0.62]

    NO_service_lower10 = len(Services_lower10)
    #print(sum([pair[1] for pair in Services_lower10]))
    #print(math.ceil(sum([pair[1] for pair in Services_lower10])/20))
    NO_Lineport_MP2x=max(math.ceil(NO_service_lower10/8),math.ceil(sum([pair[1] for pair in Services_lower10])/10))    #number of line ports
    max_number_device=math.ceil(NO_Lineport_MP2x/2)
    max_number_device=max_number_device*2
    #    max_number_device=NO_Lineport_MP2x
    #    if NO_service_lower10 ==81:
    #        print("max=",max_number_device)
    #        print("**",max_number_device)
    for i in range(1,max_number_device+1):
        #y[i]=LpVariable(name='y[i]', cat='Binary')
        y.append(LpVariable(name='y%s'%i, cat='Binary'))

    x = {}
    for j in range(1,max_number_device+1):
        for i in range(1,NO_service_lower10+1):
           #x ={ (i, j): LpVariable("x",  cat='Binary')}
           x[(i,j)] = LpVariable("x%s_%s"%(i,j),  cat='Binary')

    #    prob += lpSum([x[(i,j)] for j in range(1,NO_service_lower10+1) for i in range(1,max_number_device+1)])
    prob += lpSum([y[i-1] for i in range(1,max_number_device+1)])
    #    prob += lpSum([y[i-1] for i in range(1,max_number_device+1)])
    #     for j in range(1,max_number_device+1):
    #        prob +=lpSum(Services_lower10[i-1][1]*x[(i,j)] for i in range(1,NO_service_lower10+1))

    for i in range(1,NO_service_lower10+1):
        prob +=lpSum(x[(i,j)] for j in range(1,max_number_device+1) ) ==1,""

    for j in range(1,max_number_device+1):
        prob +=lpSum(Services_lower10[i-1][1]*x[(i,j)] for i in range(1,NO_service_lower10+1)) <= B*y[j-1],""

    for j in range(1,max_number_device+1):
        for  i in range(1,NO_service_lower10+1):
            prob +=lpSum(x[(i,j)]) <= y[j-1],""

    for j in range(1,max_number_device+1):
        prob +=lpSum(x[(i,j)] for i in range(1,NO_service_lower10+1) ) <=max_port,""

    #prob.writeLP("grooming.lp")
    prob.solve(PULP_CBC_CMD(msg=False))

    #print("Status:", LpStatus[prob.status])

    #for j in range(1,max_number_device+1):

    '''for v in prob.variables():
        print (v.name, "=", v.varValue)'''
    '''for j in range(1,max_number_device+1):
        print("******   ",y[j-1],"=",y[j-1].value(),"     *********    ")
        for i in range(1,NO_service_lower10+1):
            print(x[(i,j)],"=",x.get(i,j))'''
    ans = prob.variables()
    Result = {}
    for j in range(max_number_device):
        Result[ans[-1 - j].name] = {}
    #    yy={}
    for i in range( len(ans) - max_number_device ):
        itemName = ans[i].name
        itemValue = ans[i].varValue

        find_underscore = itemName.index("_")
        ServiceNum = itemName[1:find_underscore]
        PanelNum = itemName[(find_underscore+1):]

        key_panel = 'y' + PanelNum
        if itemValue:
            namee=Services_lower10[int(ServiceNum) - 1][0]
        else:
            namee=0
        Result[key_panel][itemName] = (namee ,itemValue * Services_lower10[int(ServiceNum) - 1][1])
    #print(Result)

    #for j in range(1,max_number_device+1):
    #    if y[j-1].value()==1:
    #        h=0
    #        for i in range(1,NO_service_lower10+1):
    ##            print('**',x[(i,j)].value())
    #            if x[(i,j)].value()==1:
    #                h=h+1
    ##                print('h=',h)
    #        if h>= min_number_of_service:
    #            print(j,y[j-1])                        #????

    Output=[]

    for key, value in Result.items():
        y=[]
        for inner_key,inner_value in value.items():
            if inner_value[1] != 0:
                y.append(( inner_value[0],inner_value[1]))
        if y:
            Output.append(y)
    #    dele=[]
    #    for i in range(0, len(Output)):
    #        if (len(Output[i])==0):
    #            dele.append(i)
    #
    #    print('dsdsss')
    #    print(Output)
    #    print('dsdsss')
    return Output

def PS6X(Services_lower10_i):
    """
        This function packs the PS6X input services to 10G service.

        Advantages:
            - Optimum packing by means of ILP

        :param <Services_lower10>: <input>
        :type <list>: <each memeber of list is a tuple included service id and the capacity of service>

        :param <prob>: <LP problem>
        :type <class>: <ILP is solved by means of this class>

        :param <max_number_device>: <maximum number of device>
        :type <integer>: <>

        :param <NO_service_lower10>: <number of services in input parameter>
        :type <integer>: <length of Services_lower10>

        :param <Output>: <maximum number of device>
        :type <list>: <list of list which is included  tuples with  service id and the capacity of service>

    """
    prob = LpProblem("grooming", LpMinimize )
    B=10                    #u
    max_port=16
    y=[]
    min_number_of_service=3
    Services_lower10=[]
    no_fe=0

        #Services_lower10=[0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 2.5, 2.5, 0.62, 0.62, 0.62, 0.62, 0.62]
        #Services_lower10=[2.5,2.5,2.5,2.5,2.5,2.5,2.5,2.5,2.5,0.62]

    for i in range(0,len(Services_lower10_i)):
        if(Services_lower10_i[i][1]==0.1):
            Services_lower10.append(Services_lower10_i[i])
            no_fe=no_fe+1
    for i in range(0,len(Services_lower10_i)):
        if(Services_lower10_i[i][1]==1):
            Services_lower10.append(Services_lower10_i[i])
    NO_service_lower10 = len(Services_lower10)
    #print(sum([pair[1] for pair in Services_lower10]))
    #print(math.ceil(sum([pair[1] for pair in Services_lower10])/20))
    NO_Lineport=max(math.ceil(NO_service_lower10/10),math.ceil(sum([pair[1] for pair in Services_lower10])/10))    #number of line ports
    max_number_device=math.ceil(NO_Lineport/2)
    max_number_device=max_number_device*2
    #    max_number_device=NO_Lineport_MP2x
    #    if NO_service_lower10 ==81:
    #        print("max=",max_number_device)
    #        print("**",max_number_device)`
    for i in range(1,max_number_device+1):
        #y[i]=LpVariable(name='y[i]', cat='Binary')
        y.append(LpVariable(name='y%s'%i, cat='Binary'))

    x = {}
    for j in range(1,max_number_device+1):
        for i in range(1,NO_service_lower10+1):
           #x ={ (i, j): LpVariable("x",  cat='Binary')}
           x[(i,j)] = LpVariable("x%s_%s"%(i,j),  cat='Binary')

    #    prob += lpSum([x[(i,j)] for j in range(1,NO_service_lower10+1) for i in range(1,max_number_device+1)])
    prob += lpSum([y[i-1] for i in range(1,max_number_device+1)])
    #    prob += lpSum([y[i-1] for i in range(1,max_number_device+1)])
    #     for j in range(1,max_number_device+1):
    #        prob +=lpSum(Services_lower10[i-1][1]*x[(i,j)] for i in range(1,NO_service_lower10+1))

    for i in range(1,NO_service_lower10+1):
        prob +=lpSum(x[(i,j)] for j in range(1,max_number_device+1) ) ==1,""

    for j in range(1,max_number_device+1):
        prob +=lpSum(Services_lower10[i-1][1]*x[(i,j)] for i in range(1,NO_service_lower10+1)) <= B*y[j-1],""

    for j in range(1,max_number_device+1):
        for  i in range(1,NO_service_lower10+1):
            prob +=lpSum(x[(i,j)]) <= y[j-1],""

    for j in range(1,max_number_device+1):
        prob +=lpSum(x[(i,j)] for i in range(1,no_fe+1) ) <=14,""

    for j in range(1,max_number_device+1):
        prob +=lpSum(x[(i,j)] for i in range(1,NO_service_lower10+1) ) <=16,""
    #    for j in range(1,max_number_device+1):
    #        prob +=lpSum((x[(i,j)] for i in range(no_fe+1,NO_service_lower10+1)) + (x[(k,j)] for k in range(1,no_fe+1)) ) <=16,""

    #prob.writeLP("grooming.lp")
    prob.solve()

    #print("Status:", LpStatus[prob.status])

    #for j in range(1,max_number_device+1):

    '''for v in prob.variables():
        print (v.name, "=", v.varValue)
    for j in range(1,max_number_device+1):
        print("******   ",y[j-1],"=",y[j-1].value(),"     *********    ")
        for i in range(1,NO_service_lower10+1):
            print(x[(i,j)],"=",x.get(i,j))'''
    ans = prob.variables()
    #    print(ans)
    Result = {}
    for j in range(max_number_device):
        Result[ans[-1 - j].name] = {}
    #    yy={}
    for i in range( len(ans) - max_number_device ):
        itemName = ans[i].name
        itemValue = ans[i].varValue

        find_underscore = itemName.index("_")
        ServiceNum = itemName[1:find_underscore]
        PanelNum = itemName[(find_underscore+1):]

        key_panel = 'y' + PanelNum
        Result[key_panel][itemName] = (itemValue * Services_lower10[int(ServiceNum) - 1][0],itemValue * Services_lower10[int(ServiceNum) - 1][1])
    #print(Result)

    #for j in range(1,max_number_device+1):
    #    if y[j-1].value()==1:
    #        h=0
    #        for i in range(1,NO_service_lower10+1):
    ##            print('**',x[(i,j)].value())
    #            if x[(i,j)].value()==1:
    #                h=h+1
    ##                print('h=',h)
    #        if h>= min_number_of_service:
    #            print(j,y[j-1])                        #????

    Output=[]

    for key, value in Result.items():
        y=[]
        for inner_key,inner_value in value.items():
            if inner_value[1] != 0:
                y.append((int (inner_value[0]),inner_value[1]))
        if y:
            Output.append(y)
    #    dele=[]
    #    for i in range(0, len(Output)):
    #        if (len(Output[i])==0):
    #            dele.append(i)
    #
    #    print('dsdsss')
    #    print(Output)
    #    print('dsdsss')
    #    print(Output)
    #    print(Services_lower10)
    return Output

    #def PS6X(Services_lower10):
    #    prob = LpProblem("grooming", LpMinimize )
    #    B=10                    #u
    #    max_port=16
    #    y=[]
    #    min_number_of_service=3
    #
    #
    #        #Services_lower10=[0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 2.5, 2.5, 0.62, 0.62, 0.62, 0.62, 0.62]
    #        #Services_lower10=[2.5,2.5,2.5,2.5,2.5,2.5,2.5,2.5,2.5,0.62]
    #
    #    NO_service_lower10 = len(Services_lower10)
    #    NO_service_lower10_fe=[]
    #    NO_service_lower10_ge=[]
    #    for i in range(0,len(NO_service_lower10)):
    #        if(NO_service_lower10[i][1]==0.1):
    #            NO_service_lower10_fe.append(NO_service_lower10[i])
    #        elif(NO_service_lower10[i][1]==1):
    #            NO_service_lower10_ge.append(NO_service_lower10[i])
    #    NO_service_fe=len(NO_service_lower10_fe)
    #    NO_service_ge=len(NO_service_lower10_ge)
    #    #print(sum([pair[1] for pair in Services_lower10]))
    #    #print(math.ceil(sum([pair[1] for pair in Services_lower10])/20))
    #    NO_Lineport=max(math.ceil(NO_service_lower10/10),math.ceil(sum([pair[1] for pair in Services_lower10])/10))    #number of line ports
    #    max_number_device=math.ceil(NO_Lineport/2)
    #    max_number_device=max_number_device*2
    ##    max_number_device=NO_Lineport_MP2x
    ##    if NO_service_lower10 ==81:
    ##        print("max=",max_number_device)
    ##        print("**",max_number_device)
    #    for i in range(1,max_number_device+1):
    #        #y[i]=LpVariable(name='y[i]', cat='Binary')
    #        y.append(LpVariable(name='y%s'%i, cat='Binary'))
    #
    #    x = {}
    #    for j in range(1,max_number_device+1):
    #        for i in range(1,NO_service_fe+1):
    #            for k in range(1,NO_service_ge+1):
    #           #x ={ (i, j): LpVariable("x",  cat='Binary')}
    #               x[(i,k,j)] = LpVariable("x%s_%s"%(i,k,j),  cat='Binary')
    #
    #
    #
    ##    prob += lpSum([x[(i,j)] for j in range(1,NO_service_lower10+1) for i in range(1,max_number_device+1)])
    #    prob += lpSum([y[i-1] for i in range(1,max_number_device+1)])
    ##    prob += lpSum([y[i-1] for i in range(1,max_number_device+1)])
    ##     for j in range(1,max_number_device+1):
    ##        prob +=lpSum(Services_lower10[i-1][1]*x[(i,j)] for i in range(1,NO_service_lower10+1))
    #
    #
    #    for i in range(1,NO_service_fe+1):
    #        prob +=lpSum(x[(i,k,j)] for j in range(1,max_number_device+1) ) ==1,""
    #
    #    for k in range(1,NO_service_ge+1):
    #        prob +=lpSum(x[(i,k,j)] for j in range(1,max_number_device+1) ) ==1,""
    #
    #
    #    for j in range(1,max_number_device+1):
    #        prob +=lpSum(Services_lower10[i-1][1]*x[(i,j)] for i in range(1,NO_service_lower10+1)) <= B*y[j-1],""
    #
    #
    #    for j in range(1,max_number_device+1):
    #        for  i in range(1,NO_service_lower10+1):
    #            prob +=lpSum(x[(i,k,j)]) <= y[j-1],""
    #
    #    for j in range(1,max_number_device+1):
    #        prob +=lpSum(x[(i,j)] for i in range(1,NO_service_lower10+1) ) <=max_port,""
    #
    #
    #
    #
    #    #prob.writeLP("grooming.lp")
    #    prob.solve()
    #
    #    #print("Status:", LpStatus[prob.status])
    #
    #    #for j in range(1,max_number_device+1):
    #
    #    '''for v in prob.variables():
    #        print (v.name, "=", v.varValue)'''
    #    '''for j in range(1,max_number_device+1):
    #        print("******   ",y[j-1],"=",y[j-1].value(),"     *********    ")
    #        for i in range(1,NO_service_lower10+1):
    #            print(x[(i,j)],"=",x.get(i,j))'''
    #    ans = prob.variables()
    #    Result = {}
    #    for j in range(max_number_device):
    #        Result[ans[-1 - j].name] = {}
    #    #    yy={}
    #    for i in range( len(ans) - max_number_device ):
    #        itemName = ans[i].name
    #        itemValue = ans[i].varValue
    #
    #        find_underscore = itemName.index("_")
    #        ServiceNum = itemName[1:find_underscore]
    #        PanelNum = itemName[(find_underscore+1):]
    #
    #        key_panel = 'y' + PanelNum
    #        Result[key_panel][itemName] = (itemValue * Services_lower10[int(ServiceNum) - 1][0],itemValue * Services_lower10[int(ServiceNum) - 1][1])
    #    #print(Result)
    #
    #    #for j in range(1,max_number_device+1):
    #    #    if y[j-1].value()==1:
    #    #        h=0
    #    #        for i in range(1,NO_service_lower10+1):
    #    ##            print('**',x[(i,j)].value())
    #    #            if x[(i,j)].value()==1:
    #    #                h=h+1
    #    ##                print('h=',h)
    #    #        if h>= min_number_of_service:
    #    #            print(j,y[j-1])                        #????
    #
    #    Output=[]
    #
    #    for key, value in Result.items():
    #        y=[]
    #        for inner_key,inner_value in value.items():
    #            if inner_value[1] != 0:
    #                y.append((int (inner_value[0]),inner_value[1]))
    #        if y:
    #            Output.append(y)
    ##    dele=[]
    ##    for i in range(0, len(Output)):
    ##        if (len(Output[i])==0):
    ##            dele.append(i)
    ##
    ##    print('dsdsss')
    ##    print(Output)
    ##    print('dsdsss')
    #    return Output

        #  remain_lower100            (the services which are not assigned to lightpath)  (DemandId,[ServiceId])
        #  MP2x_list                  (MP2X with 2 output)                               (DemandId,[ServiceId(groomout10),ServiceId(groomout10)])
        #  remaining_service_lower10  (MP2X with 1 output)                               (DemandId,ServiceId(groomout10))

def grooming_fun( TM, MP1H_Threshold,  tmId, percentage, uuid, MP2X_Threshold = None, state=None):
        """
            This function grooms the services and produces lightpaths, groomouts, devices and remaining services.

            :param <service_lower10_SDH>: <list of SDH services>
            :type <list>: <each memeber of list is a tuple included demand is and a list of tuples included service id and the capacity of service>

            :param <service_lower10_E>: <list of Ethernet services>
            :type <list>: <each memeber of list is a tuple included demand is and a list of tuples included service id and the capacity of service>

            :param <service_lower100>: <list of services that capacity of them is lower than 100>
            :type <List>: <each memeber of list is a tuple included demand is and a list of tuples included service id and the capacity of service >

            :param <remaining_service_lower10>: <list of remaining services that capacity of them is lower than 10>
            :type <List>: <each memeber of list is a tuple included demand is and a list of tuples included service id and the capacity of service >

            :param <device_dict>: <list of devices>
            :type <dictionary>: <keys are the nodes names and values are dictionary which keys of them are device name and values are the list of dedicated devices>

            :param <remaining_service_lower10_dict>: <list of remaining services that capacity of them is lower than 10>
            :type <dictionary>: <keys are the demands id and values are list of tuples included service ids and capacity of them>

            :param <groom_out10_list>: <list of grooming of services that capacity of them is lower than 10>
            :type <List>: <each memeber of list is a tuple included demand is and a list of tuples included groomout10 (output of MP2X) id and the capacity of that >

            :param <Groomout10>: <list of grooming of services that capacity of them is lower than 10>
            :type <dictionary>: <keys are the id of demands and values are the demand Specifications and the list of groomouts>

            :param <FinalLightPath>: <list of 100G Lightpaths>
            :type <dictionary>: <keys are lightpath id and values are the lightpaths>

            :param <groomingresult>: <output>
            :type <dictionary>: <keys are lightpath, low_rate_grooming_result, and remaining_services and values are the dictionary of that corresponding keys that mentioned previously>

            :param <percentage>: <input>
            :type <integer>: < initiate value of progress percentage>

            :param <state>: <input>
            :type <object>: <working object >

            :param <TM>: <input>
            :type <dictionary>: <traffic matrix >

            :param <tmId>: <input>
            :type <string>: <traffic matrix id>

            :param <uuid>: <input>
            :type <function>: <generate a unique id>

            :param <MP1H_Threshold>: <input>
            :type <integer>: <capacity threshold of generating lightpath>

            :param <MP2X_Threshold>: <input>
            :type <integer>: <capacity threshold of generating groom out>

        """
        service_lower10_SDH=[]
        service_lower10_E=[]
        service_lower100=[]
        remain_lower100_2=[]
        remaining_service_lower10=[]
        MP2x_list=[]
        MP2x_Dict={}                                 #(DemandId,Service)
        output_100=[]
        remain_lower100_dict={}
        remaining_service_lower10_dict={}
        groom_out10_list=[]
        remain_lower100=[]
        GRO10Id=0
        Groomout10={"demands":{}}
        remaningnservices={"demands":{}}
        FinalLightPath={}
        FinalLightPath.update({'LightPaths':{}})
        FinalLightPath.update({"id":uuid()})
        remaining_services= {"demands":{}}
        remaining_groomouts= {"demands":{}}
        def addlightpath(source,destination,capacity,service_id_list,demand_id,Routing_type,groomout10_id_list, protection_type, restoration_type, sdict):
            """
            This function create a lightpath and add it to FinalLightPath dictionary .

            :param <lst>: <list of services and type of them>
            :type <list>: <for groomout 10 value of type is "groomout" and for 10G services the value of type is "normal">

            :param <lightpathId>: <dedicated unique id for each lightpath>
            :type <string>: <id is generate by the uuid() function>
            """

            lst=[]
            for u in service_id_list:
                lst.append({"id":u,
                            "type":"normal",
                            "normal_service_type": sdict[str (demand_id)][u]})
            if groomout10_id_list != "None":
                for u in groomout10_id_list:
                    lst.append({"id":u,
                                "type":"groomout",
                                "normal_service_type": None,
                                "mp2x_panel_address": {"source":{   "rack_id": "None",
                                                                    "shelf_id": "None",
                                                                    "slot_id_list":["None"]},
                                                        "destination":{ "rack_id": "None",
                                                                        "shelf_id": "None",
                                                                        "slot_id_list":["None"]}}})
            lightpathId = uuid()
            lp1={

                "id": lightpathId,
                "source": source,
                "destination": destination,
                "service_id_list": lst,
                "routing_type":  Routing_type,
                "demand_id": str (demand_id),
                "protection_type":  protection_type,
                "restoration_type":  restoration_type,
                "capacity": capacity
            }
            FinalLightPath['LightPaths'].update({lightpathId:lp1})
            return lightpathId
        MP2x_dict={}
        TP1H_dict={}
        MP1H_dict={}
        device_dict={}
        lightpathId=1
        nume=1
        sdict={}
        for i in TM['demands'].keys():
            sdict.update({i:{}})
            remaining_groomouts["demands"].update({i:[]})
            remaining_services["demands"].update({i:{   "E1": { "count":  0,
                                                                "service_id_list": [],
                                                                "type": "E1"},
                                                        "stm1_e":{ "count":  0,
                                                                    "service_id_list": [],
                                                                    "type": "STM1 Electrical"} ,
                                                        "stm1_o": { "count":  0,
                                                                    "service_id_list": [],
                                                                    "type": "STM1 Optical"} ,
                                                        "stm4": {   "count":  0,
                                                                    "service_id_list": [],
                                                                    "type": "STM4"} ,
                                                        "stm16": {    "count":  0,
                                                                    "service_id_list": [],
                                                                    "type": "STM16"} ,
                                                        "stm64": {    "count":  0,
                                                                    "service_id_list": [],
                                                                    "type": "STM64"},
                                                        "FE": {    "count":  0,
                                                                    "service_id_list": [],
                                                                    "type": "STM64"},
                                                        "GE1": {    "count":  0,
                                                                    "service_id_list": [],
                                                                    "type": "GE"},
                                                        "GE10": {    "count":  0,
                                                                    "service_id_list": [],
                                                                    "type": "10GE"},
                                                        "GE100": {    "count":  0,
                                                                    "service_id_list": [],
                                                                    "type": "100GE"}}})
            per = math.ceil(percentage[0] + (nume/len(TM['demands'].keys())) * (percentage[1] - percentage[0]))

            if state is not None:
                state.update_state(state='PROGRESS', meta={'current': per, 'total': 100, 'status': 'Starting Grooming Algorithm!'})

            nume = nume + 1
            if TM['demands'][i]["source"] not in device_dict.keys():
                        device_dict.update({TM['demands'][i]["source"]:{
                                    "TP1H": [],
                                    "MP1H": [],
                                    "MP2X": []
                                    }})
            if TM['demands'][i]["destination"] not in device_dict.keys():
                device_dict.update({TM['demands'][i]["destination"]:{
                                    "TP1H": [],
                                    "MP1H": [],
                                    "MP2X": []
                                    }})
            y=[]
            z=[]
            x=[]
            output_10=[]
            for j in range(0,len(TM["demands"][i]["services"])):
                if TM["demands"][i]["services"][j]["type"] == "100GE":
                    for k in TM["demands"][i]["services"][j]["service_id_list"]:
                        sdict[i].update({k:TM["demands"][i]["services"][j]["type"]})
                        LPId=addlightpath(source=TM["demands"][i]["source"],
                        destination=TM["demands"][i]["destination"],
                        capacity=100,
                        service_id_list=[k],
                        groomout10_id_list="None",
                        demand_id=TM["demands"][i]["id"],
                        Routing_type=RoutingType.GE100,
                        protection_type=TM["demands"][i]["protection_type"],
                        restoration_type=TM["demands"][i]["restoration_type"],
                        sdict=sdict
                        )
                        if i in TP1H_dict.keys():
                            TP1H_dict[i].append((LPId,k))
                            device_dict[TM['demands'][i]["source"]]["TP1H"].append(
                                        {
                                            "panel" : "TP1H",
                                            "sub_tm_id": tmId,
                                            "lightpath_id": LPId,
                                            "id": uuid() })
                            device_dict[TM['demands'][i]["destination"]]["TP1H"].append(
                                        {
                                            "panel" : "TP1H",
                                            "sub_tm_id": tmId,
                                            "lightpath_id": LPId,
                                            "id": uuid()}
                            )
                        else:
                            TP1H_dict.update({TM["demands"][i]["id"]:[(LPId,k)]})
                            device_dict[TM['demands'][i]["source"]]["TP1H"].append(
                                        {
                                            "panel" : "TP1H",
                                            "sub_tm_id": tmId,
                                            "lightpath_id": LPId,
                                            "id": uuid()
                                    })
                            device_dict[TM['demands'][i]["destination"]]["TP1H"].append(
                                        {
                                            "panel" : "TP1H",
                                            "sub_tm_id": tmId,
                                            "lightpath_id": LPId,
                                            "id": uuid()}
                            )
                elif ((TM["demands"][i]["services"][j]["type"] == "STM64") or (TM["demands"][i]["services"][j]["type"] == "10GE")):
                    for k in TM["demands"][i]["services"][j]["service_id_list"]:
                        z.append((k,10))
                        sdict[i].update({k:TM["demands"][i]["services"][j]["type"]})
                elif TM["demands"][i]["services"][j]["type"] == "GE":
                    for k in TM["demands"][i]["services"][j]["service_id_list"]:
                        y.append((k,1.25))
                        sdict[i].update({k:TM["demands"][i]["services"][j]["type"]})
                elif TM["demands"][i]["services"][j]["type"] == "FE":
                    for k in TM["demands"][i]["services"][j]["service_id_list"]:
                        y.append((k,0.1))
                        sdict[i].update({k:TM["demands"][i]["services"][j]["type"]})
                elif TM["demands"][i]["services"][j]["type"] == "STM16":
                    for k in TM["demands"][i]["services"][j]["service_id_list"]:
                        y.append((k,2.5))
                        sdict[i].update({k:TM["demands"][i]["services"][j]["type"]})
                elif TM["demands"][i]["services"][j]["type"] in ["STM1 Optical", "STM1 Electrical"]:
                    for k in TM["demands"][i]["services"][j]["service_id_list"]:
                        y.append((k,0.15552))
                        sdict[i].update({k:TM["demands"][i]["services"][j]["type"]})
            if y:
                service_lower10_SDH.append((i,y))
                if len(y)>100:
                    yy=[]
                    res10=[]
                    for iii in range(0,math.ceil(len(y)/50)):
                        yy.append(y[iii*50:(iii+1)*50])
                    for y2 in yy:
                        res10.append(MP2X(y2))
                    finalres10=[]
                    for y2 in res10:
                        for y3 in y2:
                           finalres10.append(y3)
                    output_10.append((i,finalres10))
                else:
                    output_10.append((i,MP2X(y)))
                listofs=[]
                cap=0
                hhhh=[]
                service_id_list_of_gro10=[]
                Groomout10["demands"].update({i:{
                    "source":TM["demands"][i]["source"],
                    "destination":TM["demands"][i]["destination"],
                    "id":TM["demands"][i]["id"],
                    "protection_type" : TM["demands"][i]["protection_type"],
                    "RestorationType":TM["demands"][i]["protection_type"],
                    "groomouts":{}}})
                for num in range(0,len(output_10[0][1])):
                    listofs=[]
                    cap=0
                    for nu in range(0,len(output_10[0][1][num])):
                        listofs.append({    "id":str (output_10[0][1][num][nu][0]),
                                            "type":sdict[i][str (output_10[0][1][num][nu][0])]})
                        cap = cap + output_10[0][1][num][nu][1]
                    GroomOutId = uuid()
                    LastId = GroomOutId
                    Groomout10["demands"][i]["groomouts"].update({ GroomOutId:
                    {"quantity": 1,
                    "id": GroomOutId,
                    "service_id_list": listofs,
                    "type": GroomOutType.mp2x,
                    "sla":"None",
                    "capacity":cap}})
                    ffff=[(LastId,10)]
                    hhhh.append((LastId,cap,len(listofs),listofs))
                    z.append((LastId,cap))
                 #                    service_lower100.append((i,ffff))
                groom_out10_list.append((i,hhhh))
            if x:
                service_lower10_E.append((i,x))

            if z:
                service_lower100.append((i,z))

        for i in range(0,len(groom_out10_list)):
            nooo=[]
            for j in range(0,len(groom_out10_list[i][1])):
                for k in range(0,len(groom_out10_list[i][1])):
                    if ((k not in nooo) and (j not in nooo) and (j!=k) and (groom_out10_list[i][1][j][2] + groom_out10_list[i][1][k][2]) <=16):
                        MP2x_list.append((groom_out10_list[i][0],(groom_out10_list[i][1][j][0],groom_out10_list[i][1][k][0])))
                        if groom_out10_list[i][0] in MP2x_Dict.keys():
                            MP2x_Dict[groom_out10_list[i][0]].append((groom_out10_list[i][1][j][0],groom_out10_list[i][1][k][0]))
                        else:
                            MP2x_Dict.update({groom_out10_list[i][0]:[(groom_out10_list[i][1][j][0],groom_out10_list[i][1][k][0])]})
                        device_dict[TM['demands'][groom_out10_list[i][0]]["source"]]["MP2X"].append({
                                        "line1":{
                                                "demand_id": groom_out10_list[i][0],
                                                "groomout_id": groom_out10_list[i][1][k][0]
                                                    },
                                        "line2":{
                                                "demand_id": groom_out10_list[i][0],
                                                "groomout_id": groom_out10_list[i][1][j][0]
                                                    },
                                        "panel" : "MP2X",
                                        "sub_tm_id": tmId,
                                        "id": uuid()
                            })

                        device_dict[TM['demands'][groom_out10_list[i][0]]["destination"]]["MP2X"].append({
                                        "line1":{
                                                "demand_id": groom_out10_list[i][0],
                                                "groomout_id": groom_out10_list[i][1][k][0]
                                                    },
                                        "line2":{
                                                "demand_id": groom_out10_list[i][0],
                                                "groomout_id": groom_out10_list[i][1][j][0]
                                                    },
                                        "panel" : "MP2X",
                                        "sub_tm_id": tmId,
                                        "id": uuid()

                            }

                            )

                        nooo.append(j)
                        nooo.append(k)
            for m in range(0,len(groom_out10_list[i][1])):
                if m not in nooo:
                    remaining_service_lower10.append((groom_out10_list[i][0],groom_out10_list[i][1][m][0]))
                    if groom_out10_list[i][0] in remaining_service_lower10_dict.keys():
                        remaining_service_lower10_dict[groom_out10_list[i][0]].append(groom_out10_list[i][1][m][0])
                    else:
                        remaining_service_lower10_dict.update({groom_out10_list[i][0]:[groom_out10_list[i][1][m][0]]})
                    device_dict[TM['demands'][groom_out10_list[i][0]]["source"]]["MP2X"].append({
                                    "line1":{
                                            "demand_id": groom_out10_list[i][0],
                                            "groomout_id": groom_out10_list[i][1][m][0]
                                                },
                                    "panel" : "MP2X",
                                    "sub_tm_id": tmId,
                                    "id": uuid()
                        })

                    device_dict[TM['demands'][groom_out10_list[i][0]]["destination"]]["MP2X"].append({
                                    "line1":{
                                            "demand_id": groom_out10_list[i][0],
                                            "groomout_id": groom_out10_list[i][1][m][0]
                                            },
                                    "panel" : "MP2X",
                                    "sub_tm_id": tmId,
                                    "id": uuid()
                        }

                        )

        for i in range(0,len(service_lower100)):
            NO_LP= math.ceil(len(service_lower100[i][1])/10)
            orsr=TM["demands"][service_lower100[i][0]]["source"]
            ords=TM["demands"][service_lower100[i][0]]["destination"]
            for j in range(0,NO_LP):
                list_of_service=[]
                list_of_service2=[]
                cap=0
                for k in range(j*10,(j+1)*10):
                    if (k < len(service_lower100[i][1])):
                        list_of_service.append(service_lower100[i][1][k][0])
                        list_of_service2.append((service_lower100[i][1][k][0],service_lower100[i][1][k][1]))
                        cap=cap+service_lower100[i][1][k][1]
                if cap >= MP1H_Threshold:
                    typee="100GE"
                else:
                    typee="NonCoherent"

                if cap < MP1H_Threshold:
                    remain_lower100.append((service_lower100[i][0],list_of_service))
                    remain_lower100_2.append((service_lower100[i][0],list_of_service2))
                    remain_lower100_dict.update({service_lower100[i][0]:list_of_service})
                    for idd in list_of_service:
                        if idd in sdict[service_lower100[i][0]]:
                            fg="none"
                            if sdict[service_lower100[i][0]][idd] == "10GE":
                                fg="GE10"
                            else:
                                fg="stm64"
                            remaining_services["demands"][service_lower100[i][0]][fg]["count"] = remaining_services["demands"][service_lower100[i][0]][fg]["count"] + 1
                            remaining_services["demands"][service_lower100[i][0]][fg]["service_id_list"].append(idd)
                        else:
                            remaining_groomouts["demands"][service_lower100[i][0]].append(idd)
                    if service_lower100[i][0] in remaningnservices['demands'].keys():
                        remaningnservices['demands'][service_lower100[i][0]].append(list_of_service)
                    else:
                        remaningnservices['demands'].update({service_lower100[i][0]:list_of_service})
                else:
                    los1=[]
                    los2=[]
                    for ii in list_of_service:
                        if (service_lower100[i][0] in Groomout10["demands"]) and (ii in  Groomout10["demands"][service_lower100[i][0]]["groomouts"]):
                            los2.append(ii)
                        else:
                            los1.append(ii)
                    LPId=addlightpath(
                        source=TM["demands"][service_lower100[i][0]]["source"],
                        destination=TM["demands"][service_lower100[i][0]]["destination"],
                        capacity=cap,
                        service_id_list=los1,
                        groomout10_id_list= los2,
                        demand_id=TM["demands"][service_lower100[i][0]]["id"],
                        Routing_type=RoutingType.GE100,
                        protection_type=TM["demands"][service_lower100[i][0]]["protection_type"],
                        restoration_type=TM["demands"][service_lower100[i][0]]["restoration_type"],
                        sdict=sdict
                        )
                    device_dict[TM['demands'][service_lower100[i][0]]["source"]]["MP1H"].append({
                                    "panel" : "MP1H",
                                    "sub_tm_id": tmId,
                                    "lightpath_id": LPId,
                                    "id": uuid()
                    })
                    device_dict[TM['demands'][service_lower100[i][0]]["destination"]]["MP1H"].append({
                                    "panel" : "MP1H",
                                    "sub_tm_id": tmId,
                                    "lightpath_id": LPId,
                                    "id": uuid()
                    })

        devicedict={}
        groomingresult={}
        groomingresult.update({'low_rate_grooming_result':Groomout10})
        groomingresult.update({'lightpaths':FinalLightPath['LightPaths']})
        groomingresult.update({'remaining_services':remaining_services})
        groomingresult.update({'remaining_groomouts':remaining_groomouts})
        # groomingresult.update({'cluster_id':TM1[0]['id']})
        # devicedict.update({'service_devices': Nodestructureservices(device_dict)})
        return groomingresult,device_dict


#!/usr/bin/env python3
'''
Written by Justus Languell, 2020-2021, jus@gtsbr.org
See info.txt
'''

# Imports
import motors

import cv2
import numpy as np
import time
import wx
import pyautogui
import os
import argparse

# Define Constants

# Main Function, taking arg inputs
def main(color,flip,vid):

    cap = cv2.VideoCapture(vid) # Load Video Stream

    I=0
    while True:  # Main Loop
        I+=1
        #i = I // 4
        i = int(color)
        print(i,end='\r')
        ret, frame = cap.read() # Get Frame
        if flip:
            frame = cv2.flip(frame,1) # Process Flip if Asked

        height, width, channels = frame.shape # Define Shape

        hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

        lower_red = np.array([0,0,0])
        upper_red = np.array([i,i,i])

        mask = cv2.inRange(hsv, lower_red, upper_red)
        res = cv2.bitwise_and(frame,frame, mask= mask)

        #cv2.imshow('frame',frame)
        cv2.imshow('mask',mask)
        #cv2.imshow('res',res)

        #cv2.imshow('Happy New Year!', frame)  # Display Frame

        if cv2.waitKey(1) == ord('q'):  # Exit Condition
            break

    cv2.destroyAllWindows()
    pass

if __name__ == '__main__':
    # Setup Printout
    print(f'''
    Computer Vision Pipeline
    By Justus Languell 2020-2021
    ''')

    parser = argparse.ArgumentParser() # Process Args
    parser.add_argument('-f','--flip',help='Flip Video Stream',required=False,const=True,nargs='?')
    parser.add_argument('-c','--color',help='Color To Follow',required=False,default = '')
    parser.add_argument('-v', '--vid', help = 'Run Test on Video File', required = False, default = '')
    argument = parser.parse_args()

    flip = True if argument.flip else False
    vid = argument.vid if argument.vid else 0
    color = argument.color if argument.color else 'red'

    main(color,flip,vid) # Init Main Function
    print(color,flip,vid)


import toml
import wandb
import torch
import numpy as np
import pandas as pd
from torch.utils.data import DataLoader
from torch import nn, optim
from src.training import train_model
from src.data_utils import CellDataset
from src.model import ResUNet
from src.losses import FocalLoss, ExponentialLogarithmicLoss, MixedLoss

import albumentations as albu
from albumentations.pytorch import ToTensorV2
from src.transfroms import Normalize, RandomCrop, HardCutout

from src.utils import set_seed

torch.cuda.empty_cache()

wandb.init(project="sartorius")
cfg = toml.load("./config/cfg.toml")
wandb.config = cfg
set_seed(cfg["seed"])

train_transforms = albu.Compose(
    [
        albu.RandomScale((0.7, 1.3), p=0.2),
        albu.Rotate(limit=30, p=0.2),
        RandomCrop((224, 224)),
        albu.Flip(p=0.2),
        albu.RandomRotate90(p=0.2),
        albu.OneOf(
            [
                albu.RandomBrightnessContrast(
                    brightness_limit=0.2,
                    contrast_limit=0.2,
                ),
                albu.HueSaturationValue(
                    hue_shift_limit=20, sat_shift_limit=50, val_shift_limit=50
                ),
            ],
            p=0.2,
        ),
        albu.Cutout(
            max_h_size=int(224 * 0.1), max_w_size=int(224 * 0.1), num_holes=5, p=0.05
        ),
        HardCutout((122, 122), p=0.02),
        Normalize(),
        ToTensorV2(),
    ]
)

val_transforms = albu.Compose([Normalize(), RandomCrop((224, 224)), ToTensorV2()])

IMG_FOLDER = "./data/train"
train_df = pd.read_csv("./data/train.csv")
train_ids = np.load("./data/data_split/train_idxs.npy", allow_pickle=True)
val_ids = np.load("./data/data_split/val_idxs.npy", allow_pickle=True)

train_dataset = CellDataset(IMG_FOLDER, train_df, train_ids, train_transforms)
val_dataset = CellDataset(IMG_FOLDER, train_df, val_ids, val_transforms)

dataloader_train = DataLoader(
    train_dataset, batch_size=cfg["train"]["bs"], shuffle=True
)
dataloader_val = DataLoader(val_dataset, batch_size=cfg["train"]["bs"], shuffle=False)

print("Train size: ", len(dataloader_train))
print("Val size: ", len(dataloader_val))

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(f"Device: {device}")

resunet = ResUNet(cfg["model"]).to(device)

optimizer = optim.Adam(resunet.parameters(), lr=cfg["train"]["lr"])
scheduler = optim.lr_scheduler.StepLR(
    optimizer, step_size=1000, gamma=0.9, verbose=True
)

criterion = MixedLoss(1, 1, 0.5)

if __name__ == "__main__":
    train_model(
        resunet,
        dataloader_train,
        dataloader_val,
        device,
        optimizer,
        criterion,
        scheduler,
        cfg,
    )


import paho.mqtt.client as mqtt
import time
import ast
import requests
from PIL import Image, ImageDraw
from ST7789 import ST7789

#setup display
SPI_SPEED_MHZ = 80
base_path = "/home/harmony/bt.p3.raspberry"
sleeping_gif_file = "/home/harmony/bt.p3.raspberry/assets/images/sleeping_dog.gif"
harmony_screen_file = "/home/harmony/bt.p3.raspberry/assets/images/harmony_screen.png"

disp = ST7789(
    height=240,
    width=240,
    rotation=90,  # Needed to display the right way up on Pirate Audio
    port=0,       # SPI port
    cs=1,         # SPI port Chip-select channel
    dc=9,         # BCM pin used for data/command
    backlight=13,
    spi_speed_hz=SPI_SPEED_MHZ * 1000 * 1000
)
disp.begin()
sleeping_gif = Image.open(sleeping_gif_file)
harmony_screen = Image.open(harmony_screen_file)

gif_frame = 0

#mopidy settings
mopidy_url = "http://localhost:6680/mopidy/rpc"

#gemeral settings
currently_playing = False
currently_paused = False

def start_playback(sound, thumbnail_location):
    global gif_frame, currently_playing, currently_paused
    currently_paused = False
    currently_playing = True

    thumbnail_screen = Image.open(base_path+"/assets/images/"+ thumbnail_location)
    disp.display(thumbnail_screen.resize((disp.width, disp.height)))

    payload = {
        "jsonrpc": "2.0",
        "id": 1,
        "method": "core.tracklist.clear"
    }
    response = requests.post(mopidy_url, json=payload).json()
    print("Cleared tracklist")

    payload = {
        "jsonrpc": "2.0",
        "id": 1,
        "method": "core.tracklist.add",
        "params": {
                "uris": [f'local:track:{sound}']
        }
    }
    response = requests.post(mopidy_url, json=payload).json()
    print("Added track to tracklist")

    payload = {
        "jsonrpc": "2.0",
        "id": 1,
        "method": "core.mixer.set_volume",
        "params": {
                "volume": 100
        }
    }
    response = requests.post(mopidy_url, json=payload).json()
    print("Set volume")

    payload = {
        "jsonrpc": "2.0",
        "id": 1,
        "method": "core.playback.play"
    }
    response = requests.post(mopidy_url, json=payload).json()

    time.sleep(0.05)

    print("Started playing")

def pause_playback():
    global gif_frame, currently_playing, currently_paused
    currently_playing = False
    currently_paused = True
    payload = {
        "jsonrpc": "2.0",
        "id": 1,
        "method": "core.playback.pause"
    }
    response = requests.post(mopidy_url, json=payload).json()

    disp.display(harmony_screen.resize((disp.width, disp.height)))
    gif_frame = 0

    print("Paused playing")

def resume_playback(thumbnail_location):
    global gif_frame, currently_playing, currently_paused
    currently_paused = False
    currently_playing = True

    thumbnail_screen = Image.open(base_path+"/assets/images/"+ thumbnail_location)
    disp.display(thumbnail_screen.resize((disp.width, disp.height)))

    payload = {
        "jsonrpc": "2.0",
        "id": 1,
        "method": "core.playback.resume"
    }
    response = requests.post(mopidy_url, json=payload).json()

    print("Resumed playing")

def stop_playback():
    global gif_frame, currently_playing, currently_paused
    currently_paused = False
    currently_playing = False
    payload = {
        "jsonrpc": "2.0",
        "id": 1,
        "method": "core.playback.stop"
    }
    response = requests.post(mopidy_url, json=payload).json()

    disp.display(harmony_screen.resize((disp.width, disp.height)))
    gif_frame = 0
    print("Stopped playing")

def on_connect(client, userdata, flags, rc):
    print(f"Connected with result code {rc}")
    client.subscribe("raspberry/topic")

def on_message(client, userdata, msg):
    print(f"{msg.topic} {msg.payload}")

    message_payload = ast.literal_eval(msg.payload.decode("utf-8"))
    action = message_payload["action"]
    if action == "play":
        if not currently_paused:
            start_playback(message_payload["payload"]["sound_name"], message_payload["payload"]["thumbnail_name"])
        else:
            resume_playback(message_payload["payload"]["thumbnail_name"])
    elif action == "pause":
        pause_playback()
    elif action == "stop":
        stop_playback()

#connect to mqtt
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.username_pw_set("raspberrypi", "changemepls")
client.connect("3.78.96.233", 1883, 60)

client.loop_start()

#display logo
disp.display(harmony_screen.resize((disp.width, disp.height)))

#start loop
while True:
    # if currently_playing == True:
    #     print("Currently playing")
    #     time.sleep(1)
    # else:
    #     print("Waiting for messages")
    #     time.sleep(1)
    pass


import cocotb
import pyuvm.utility_classes as utility_classes
from pyuvm import *
import pytest
import inspect
from cocotb.utils import get_sim_time

@cocotb.test()
async def test_01_uvm_transaction_accept_time(dut):
    """
    Test uvm_transaction accept time
    """
    tr0 = uvm_transaction()
    tr1 = uvm_transaction()
    tr0.accept_tr(None)
    await cocotb.triggers.Timer(100, "ns")
    tr1.accept_tr(None)
    assert(tr1.get_accept_time() > tr0.get_accept_time())
    assert(tr1.get_accept_time() > 0)

@cocotb.test()
async def test_01_uvm_transaction_begin_time(dut):
    """
    Test uvm_transaction begin time
    """
    tr0 = uvm_transaction()
    tr1 = uvm_transaction()
    tr0.accept_tr(1)
    assert(tr0.get_accept_time() == 1)
    await cocotb.triggers.Timer(100, "ns")
    tr1.accept_tr(2)
    assert(tr1.get_accept_time() == 2)
    with pytest.raises(error_classes.UVMFatalError):
        tr1.begin_tr(1)
    tr1.begin_tr(None, None)
    await cocotb.triggers.Timer(100, "ns")
    tr0.begin_tr()
    # Check time values
    # Check begin time between transactions
    assert(tr0.get_begin_time() > tr1.get_begin_time())
    assert(tr1.get_begin_time() > 0)
    assert(tr0.get_begin_time() > tr1.get_begin_time())

@cocotb.test()
async def test_01_uvm_transaction_end_time(dut):
    """
    Test uvm_transaction begin time
    """
    tr0 = uvm_transaction()
    tr1 = uvm_transaction()
    tr0.accept_tr(None)
    tr0.begin_tr(None, None)
    tr0.end_tr(None, None)
    await cocotb.triggers.Timer(100, "ns")
    tr1.accept_tr(None)
    assert(tr1.get_accept_time() > tr0.get_accept_time())
    await cocotb.triggers.Timer(50, "ns")
    tr1.begin_tr(None, None)
    await cocotb.triggers.Timer(100, "ns")
    tr1.end_tr(None, None)
    assert(tr1.get_accept_time() < tr1.get_end_time())
    assert(tr1.get_accept_time() < tr1.get_begin_time())
    assert(tr1.get_end_time() > tr0.get_end_time())


# Assignment 10

# Contact Tracing App
#	- Create a python program that will read QRCode using your webcam
#	- You may use any online QRCode generator to create QRCode
#	- All personal data are in QRCode
#	- You may decide which personal data to include
#	- All data read from QRCode should be stored in a text file including the date and time it was read

# Note:
#	- Search how to generate QRCode
#	- Search how to read QRCode using webcam
#	- Search how to create and write to text file
#	- Your source code should be in github before Feb 19
#	- Create a demo of your program (1-2 min) and send it directly to my messenger.

# Supplemented pyzbar on the program for the apparent decoding of the data inside the Details Variable.
# Datetime Import for Updated Time Registry.
from pyzbar import pyzbar; from datetime import *; import time
# CV2 as the program interface for Live Webcam on User Default.
import cv2
"""
DEF FUNCTION FOR THE CALENDAR OF UPDATED REGISTRY - TO BE IMPORTED ON THE CONTACT TRACING INFORMATION TEXT FILE
"""
def record_scan(icon):
    BCHScan = pyzbar.decode(icon)
    for info in BCHScan:
        a, b, c, d = info.rect                                                                  # Settling up global parameters for the Font Layout on the Live Webcam.
        TxtBCHFile = info.data.decode('utf-8')                                                  # ASCII Standard Unicode Character
        cv2.rectangle(icon, (a, b),(a+c, b+d), (0, 0, 150), 3)                                  # ASCII Font Density
        cv2.rectangle(icon, (a, b),(a+c, b+d), (0, 150, 0), 3)                                  # ASCII Font Density
        TxtFont = cv2.FONT_HERSHEY_COMPLEX_SMALL                                                # Modifying Font Type
        cv2.putText(icon, TxtBCHFile, (a + 10, b - 10), TxtFont, 1.0, (150, 150, 150), 2)       # Layout and Text Color for the Font Presets.
        cv2.putText(icon, TxtBCHFile, (a + 10, b - 10), TxtFont, 1.0, (150, 0, 0), 2)           # Layout and Text Color for the Font Presets.
        """
        TEXT FILE WITHIN THE SAME FOLDER HAS THE AUTHORIZATION TO GET OVERWRITTEN.
        """
        local_time = datetime.now()                                                             # REAL-TIME GMT+8 / UTC+9 PHILIPPINES
        datezone = local_time.strftime("%B %d, %Y")                                             # MONTH, DAY, AND YEAR (e.g. January 1, 2022)
        current_time = time.localtime()                                                         # The Localtime will be Detected - MANILA, PHL
        timezone = time.strftime("%H:%M", current_time)                                         # HOURS AND MINUTES (e.g. 09:45) with regards to AM and PM
        timezoneNUM = int(time.strftime("%H", current_time))                                    # Disregarding the 24 Hour Clock
        timezoneDate = time.strftime("%M", current_time)                                        # A Full-Hour Minute (60 Minutes)
        hour_clock = 12
        with open(details, "w", encoding="utf-8") as update:
            if timezoneNUM >= 0 and timezoneNUM < hour_clock:
                update.write(TxtBCHFile + (f"\n\n--- RECORD OF SCANS --- \nDate Tracking Record: {datezone}\nTime Tracking Record: {timezone} AM"))
            else:
                timeCurrent = (timezoneNUM) - hour_clock
                update.write(TxtBCHFile + (f"\n\n--- RECORD OF SCANS --- \nDate Tracking Record: {datezone}\nTime Tracking Record: {timeCurrent}:{timezoneDate} PM"))
    return icon;                                                                                # Brings back the variable upon the Font Layout - illustration on the Live Webcam.
details = "record of scans.txt"
"""
DEF FUNCTION FOR A LIVE QRC SCANNER THROUGH WEBCAM DEVICE
"""
def webcamExtract():
    aperture = cv2.VideoCapture(0)                                                              # Acts as an Intermediary Between the Python Progam and the Operating System.
    unveil = cv2.QRCodeDetector()                                                               # Reads a specific context of data patterns alongside of its pixels.
    while True:                                                                                # Loop is used to prevent the unnecesarry closing of Webcam before QR Code is detected and decoded.
        _, icon = aperture.read()                                                               # Loop is iterated to refresh the command system.
        data, vrcam, _ = unveil.detectAndDecode(icon)
        icon = record_scan(cv2.resize(icon, None, fx=1.5, fy=1.5, interpolation = cv2.INTER_LINEAR_EXACT)) # Programmed Font will be displayed between the Live Webcam.
        cv2.imshow("DAN CHRISTIAN QRC SCANNER", icon)                                           # The Live Webcam Shall Run Together with a Detected QR Code Scanner with its Presented Font Layout alongside of the Stored Input Data.
        if cv2.waitKey(1) == ord('q'):                                                          # 43 Characters are Present within the first code-block of dictionary line: THE COVID-19 HEALTH MONITOR - CONTACT TRACING FORM
            break                                                                               # comman that will end the loop
    aperture.release()                                                                          # Operating System will then be informed - Allocated Memory shall despise at any moment.
    cv2.destroyAllWindows()                                                                     # will automatically close after scanning.
webcamExtract()                                                                                # Initializing the overall Python Program.


import datetime

counter = 0

for i in range(1901, 2001):
    for j in range(1, 13):
        d = datetime.datetime(i, j, 1)
        if d.weekday() == 6:
            counter += 1

print(counter)


from torch.nn.utils.rnn import pack_padded_sequence, pad_packed_sequence
from torch.autograd import Variable
import torch.optim as optim
import torch.nn.functional as F
import torch.nn as nn
import torch
import numpy as np
import conllu

# Parse the data using the CoNLL-U format parser
train_data = conllu.parse(
    open("./Dataset/en_atis-ud-train.conllu", "r", encoding="utf-8").read())
valid_data = conllu.parse(
    open("./Dataset/en_atis-ud-dev.conllu", "r", encoding="utf-8").read())
test_data = conllu.parse(
    open("./Dataset/en_atis-ud-test.conllu", "r", encoding="utf-8").read())

train_data = [[(word['form'], word['upostag'])
               for word in sentence] for sentence in train_data]
valid_data = [[(word['form'], word['upostag'])
               for word in sentence] for sentence in valid_data]
test_data = [[(word['form'], word['upostag'])
              for word in sentence] for sentence in test_data]

# Glove Embedding

def load_glove_embeddings(file_path):
    with open(file_path, 'r') as f:
        embeddings = {}
        for line in f:
            values = line.split()
            word = values[0]
            vector = np.array(values[1:], dtype='float32')
            embeddings[word] = vector
    return embeddings

# embeddings = load_glove_embeddings('./glove.6B/glove.6B.100d.txt')
# embeddings_list = [embeddings[word] for word in embeddings]
# embeddings_matrix = np.array(embeddings_list)
# add for PAD
# embeddings_matrix = np.vstack(
    # (np.zeros(100).astype(np.float32), embeddings_matrix))
# add for UNK
# embeddins_matrix = np.vstack(
    # (embeddings_matrix, np.random.rand(100).astype(np.float32)))

# np.save('embeddings_matrix.npy', embeddings_matrix)

# Create a dictionary of words and their corresponding indices
def dictWCT(data):
    wordCount = {}
    tagCount = {}
    wordFreq = {}
    for sentence in data:
        for word in sentence:
            if word[0] not in wordCount:
                wordCount[word[0]] = len(wordCount)+1
                wordFreq[word[0]] = 1
            else:
                wordFreq[word[0]] += 1
            if word[1] not in tagCount:
                tagCount[word[1]] = len(tagCount)+1
    return wordCount, tagCount, wordFreq

wordToIdx, tagToIdx, wordFreq = dictWCT(train_data)

wordToIdx['<PAD>'] = 0
wordFreq = {k: v for k, v in wordFreq.items() if v > 2}
wordToIdx['<UNK>'] = len(wordFreq)+1
tagToIdx['<UNK>'] = len(tagToIdx)+1
numUniqueWords = len(wordFreq)
numUniqueTags = len(tagToIdx)+1
idxToWord = {v: k for k, v in wordToIdx.items()}
idxToTag = {v: k for k, v in tagToIdx.items()}

# print("Number of unique words: ", numUniqueWords)
# print("Number of unique tags: ", numUniqueTags)

def getIndices(data, wordToIdx, tagToIdx, wordFreq, min_freq=2):
    wordIndices = []
    tagIndices = []
    mxTagForUnk = {}
    for sentence in data:
        wordIdx = []
        tagIdx = []
        for word in sentence:
            if word[0] not in wordFreq:
                wordIdx.append(wordToIdx['<UNK>'])
                tagIdx.append(tagToIdx['<UNK>'])
                if word[1] not in mxTagForUnk:
                    mxTagForUnk[word[1]] = 1
                else:
                    mxTagForUnk[word[1]] += 1
            else:
                wordIdx.append(wordToIdx[word[0]])
                tagIdx.append(tagToIdx[word[1]])
        wordIndices.append(wordIdx)
        tagIndices.append(tagIdx)

    mxTagForUnk = max(mxTagForUnk, key=mxTagForUnk.get)
    # tagIndices = [[tagToIdx[mxTagForUnk] if word == wordToIdx['<UNK>'] else tag for word, tag in zip(
    #     wordIndices[i], tagIndices[i])] for i in range(len(wordIndices))]
    return wordIndices, tagIndices

wordIndices, tagIndices = getIndices(train_data, wordToIdx, tagToIdx, wordFreq)
wordIndicesValid, tagIndicesValid = getIndices(
    valid_data, wordToIdx, tagToIdx, wordFreq)
wordIndicesTest, tagIndicesTest = getIndices(
    test_data, wordToIdx, tagToIdx, wordFreq)

def padWCT(wordIndices, tagIndices):
    max_len = 0
    for i in range(len(wordIndices)):
        if len(wordIndices[i]) > max_len:
            max_len = len(wordIndices[i])

    wordIndices = np.array([np.pad(wordIndices[i], (0, max_len -
                           len(wordIndices[i])), 'constant') for i in range(len(wordIndices))])
    tagIndices = np.array([np.pad(tagIndices[i], (0, max_len -
                          len(tagIndices[i])), 'constant') for i in range(len(tagIndices))])

    return wordIndices, tagIndices

wordIndices, tagIndices = padWCT(wordIndices, tagIndices)
wordIndicesValid, tagIndicesValid = padWCT(wordIndicesValid, tagIndicesValid)
wordIndicesTest, tagIndicesTest = padWCT(wordIndicesTest, tagIndicesTest)

# GLOBAL VARIABLES
WORD_EMBEDDING_DIM = 100
LSTM_HIDDEN_DIM_WORD = 256
DROPOUT_RATE = 0.5
BATCH_SIZE = 128
NUM_EPOCHS = 10

use_cuda = torch.cuda.is_available()
device = torch.device("cuda:0" if use_cuda else "cpu")
# print(device)

# Create the model

class BiLSTM(nn.Module):
    def __init__(self, numUniqueWords, numUniqueTags, wordEmbeddingDim, lstmHiddenDimWord, dropoutRate, embedding):
        super(BiLSTM, self).__init__()
        self.wordEmbedding = nn.Embedding.from_pretrained(
            torch.from_numpy(embedding).float(), freeze=False, padding_idx=0)
        self.lstmWord = nn.LSTM(wordEmbeddingDim,
                                lstmHiddenDimWord, bidirectional=True, batch_first=True)
        self.dropout = nn.Dropout(dropoutRate)
        self.linear = nn.Linear(2*lstmHiddenDimWord, numUniqueTags)

    def forward(self, word_indices):
        word_embeddings = self.wordEmbedding(word_indices)
        lstm_word_out = self.lstmWord(word_embeddings)[0]
        lstm_word_out = self.dropout(lstm_word_out)
        linear_out = self.linear(lstm_word_out)
        tag_scores = F.log_softmax(linear_out, dim=2)

        return tag_scores

embeddings_matrix = np.load('embeddings_matrix.npy')
model = BiLSTM(numUniqueWords, numUniqueTags, WORD_EMBEDDING_DIM,
               LSTM_HIDDEN_DIM_WORD, DROPOUT_RATE, embeddings_matrix)
if torch.cuda.is_available():
    model.cuda()

# create tensors
def convertToTensors(wordIndices, tagIndices):
    wordTensor = [torch.LongTensor(word) for word in wordIndices]
    tagTensor = [torch.LongTensor(tag) for tag in tagIndices]
    return wordTensor, tagTensor

wordTensor, tagTensor = convertToTensors(wordIndices, tagIndices)
wordTensorValid, tagTensorValid = convertToTensors(
    wordIndicesValid, tagIndicesValid)
wordTensorTest, tagTensorTest = convertToTensors(
    wordIndicesTest, tagIndicesTest)

# training model
optimizer = optim.Adam(model.parameters(), lr=0.01)
criterion = nn.NLLLoss(ignore_index=0)
torch.autograd.set_detect_anomaly(True)

def train(model, optimizer, criterion, wordTensor, tagTensor):
    model.train()
    total_loss = 0
    tot_correct = 0
    total_pad = 0
    for i in range(0, len(wordIndices), BATCH_SIZE):
        optimizer.zero_grad()
        word_tensor = wordTensor[i:i+BATCH_SIZE]
        tag_tensor = tagTensor[i:i+BATCH_SIZE]
        word_tensor = torch.stack(word_tensor).to(device)
        tag_tensor = torch.stack(tag_tensor).to(device)
        tag_tensor = tag_tensor.view(-1)
        output = model(word_tensor)
        output = output.view(-1, output.shape[2])
        loss = criterion(output, tag_tensor)
        loss.backward()
        optimizer.step()
        total_loss += loss.item()
        pred = torch.argmax(output, dim=1)
        tot_correct += torch.sum((tag_tensor != 0) &
                                 (tag_tensor == pred)).item()

        total_pad += torch.sum(tag_tensor == 0).item()

    return total_loss, tot_correct/(len(wordIndices)*len(wordIndices[0]) - total_pad)

def evaluate(model, wordTensor, tagTensor):
    model.eval()
    total_loss = 0
    tot_correct = 0
    total_pad = 0
    wordTagList = []
    with torch.no_grad():
        for i in range(0, len(wordTensor), BATCH_SIZE):
            word_tensor = wordTensor[i:i+BATCH_SIZE]
            tag_tensor = tagTensor[i:i+BATCH_SIZE]
            word_tensor = torch.stack(word_tensor).to(device)
            tag_tensor = torch.stack(tag_tensor).to(device)
            tag_tensor = tag_tensor.view(-1)
            output = model(word_tensor)
            output = output.view(-1, output.shape[2])
            loss = criterion(output, tag_tensor)
            total_loss += loss.item()
            pred = torch.argmax(output, dim=1)
            tot_correct += torch.sum((tag_tensor != 0) &
                                     (tag_tensor == pred)).item()
            total_pad += torch.sum(tag_tensor == 0).item()
            # take those only which are not padded
            wordTagList.extend(
                list(zip(word_tensor.view(-1).tolist(), pred.view(-1).tolist())))
    return total_loss, tot_correct/(len(wordTensor)*len(wordTensor[0]) - total_pad), wordTagList

def EpochRun(model, optimizer, criterion, wordTensor, tagTensor, wordTensorValid, tagTensorValid):
    loss_list = []
    accuracy_list = []
    validaton_loss_list = []
    validaton_accuracy_list = []
    for epoch in range(NUM_EPOCHS):
        loss, totalCorrect = train(
            model, optimizer, criterion, wordTensor, tagTensor)
        lossValid, totalCorrectValid, _ = evaluate(
            model, wordTensorValid, tagTensorValid)
        print("Epoch: {0} \t Training Loss: {1} \t Training Accuracy: {2} \t Validation Loss: {3} \t Validation Accuracy: {4}".format(
            epoch+1, loss, totalCorrect, lossValid, totalCorrectValid))
        loss_list.append(loss)
        accuracy_list.append(totalCorrect)
        validaton_loss_list.append(lossValid)
        validaton_accuracy_list.append(totalCorrectValid)
    return loss_list, accuracy_list, validaton_loss_list, validaton_accuracy_list

# loss_list, accuracy_list, validaton_loss_list, validaton_accuracy_list = EpochRun(
#     model, optimizer, criterion, wordTensor, tagTensor, wordTensorValid, tagTensorValid)

def genSentence(model, wordFreq, sentence):
    sentence = sentence.lower()
    print(sentence)
    sentence = sentence.split(" ")
    word_indice = []
    for s in sentence:
        if s not in wordFreq or wordFreq[s] <= 2:
            word_indice.append(wordToIdx['<UNK>'])
        else:
            word_indice.append(wordToIdx[s])
    wordTen = torch.LongTensor(word_indice).to(device)
    wordTen = wordTen.view(1, -1)
    # predict the tag
    with torch.no_grad():
        model.eval()
        output = model(wordTen)
        _, predicted = torch.max(output, 2)
        # print(predicted.shape)
        for i in range(len(predicted[0])):
            print(sentence[i],"\t", idxToTag[predicted[0][i].item()])

# input sentence
import sys

input_sentence = input("Enter a sentence: ")

# load the model

model.load_state_dict(torch.load('modelFinal.pt'))
genSentence(model, wordFreq, input_sentence)


from django.http import HttpResponse
from django.shortcuts import render,reverse,redirect
from django.contrib.auth import authenticate, login, logout #user django already has auth
from model.scitc_login import login
import json
import os
from model.scitc_login import sql

mysql = sql()
def user_logout(request):
    logout(request)
    return redirect('/')

def user_info(request):
    try:
        is_login = request.session['username']
    except:
        return redirect('/')
    content = {}
    sql_order = "select * from user where account={account}".format(account=request.session['username'])
    query_flag = mysql.cursor.execute(sql_order)
    if query_flag:
        ret = mysql.cursor.fetchone()
        # print(ret)
        key = ('account', 'password', 'email', 'name', 'temperature', 'address', 'building', 'room', 'longitude', 'latitude')
        for i,j in zip(key,ret):
            content[i] = j
        # print(content)
    return render(request,'user.html',content)

def user_update(request):
    if request.method == 'POST':
        print('update')
        account = request.session['username']
        name = request.POST.get('name','')
        email = request.POST.get('email','')
        temperature = request.POST.get('temperature','')
        address = request.POST.get('address','')
        building = request.POST.get('building','')
        room = request.POST.get('room','')
        longitude = request.POST.get('longitude','')
        latitude = request.POST.get('latitude','')
        print([name, email, temperature, address, building, room, longitude, latitude, account])
        sql_order = "UPDATE user SET name=(%s), email=(%s), temperature=(%s), address=(%s), building=(%s), room=(%s), longitude=(%s), latitude=(%s) WHERE account=(%s);"
        mysql.cursor.execute(sql_order,[name, email, temperature, address, building, room, longitude, latitude, account])
        mysql.db.commit()
        return HttpResponse(json.dumps("更新成功"), content_type="application/json,charset=utf-8")
        # except:
        #     return HttpResponse(json.dumps("更新失败"), content_type="application/json,charset=utf-8")

    else:
        return HttpResponse(json.dumps("违规请求"), content_type="application/json,charset=utf-8")

def user_img_upload(request):
    print("uploading running")
    if request.method == 'POST':
        obj = request.FILES.get('myimg')  # 获取对象
        if not obj:
            return render(request, 'user.html')
        filepath = 'static/img/' + request.session['username'] + '/'
        print(obj.name)
        if not os.path.exists(filepath):
            os.makedirs(filepath)
        obname = filepath + obj.name  # 保存路径加上传文件的文件名
        with open(obname, 'wb+') as f:
            for chunk in obj.chunks():
                f.write(chunk)
        return HttpResponse(json.dumps("上传成功"), content_type="application/json,charset=utf-8")
    return render(request, 'user.html')


import enum
import os
import random
from functools import reduce
from itertools import zip_longest

import cocotb
from cocolight import DUT, ValidReadyTb, cocotest, concat_bv
from cocotb.binary import BinaryValue

NUM_TV = int(os.environ.get("NUM_TV", 100))

class Incomplete(enum.Enum):
    Ignore = enum.auto()
    Fill = enum.auto()
    Strict = enum.auto()

def grouper(iterable, n, *, incomplete: Incomplete = Incomplete.Ignore, fillvalue=None):
    "Collect data into non-overlapping fixed-length chunks or blocks"
    args = [iter(iterable)] * n
    if incomplete == Incomplete.Fill:
        return zip_longest(*args, fillvalue=fillvalue)
    # if incomplete == 'strict':
    #     return zip(*args, strict=True)
    if incomplete == Incomplete.Ignore:
        return zip(*args)
    else:
        raise ValueError("Expected fill, strict, or ignore")

def random_bits(n: int) -> BinaryValue:
    # by default bigEndian=True
    return BinaryValue(value=random.getrandbits(n), n_bits=n)

@cocotest
async def test_piso(dut: DUT, num_tests: int = NUM_TV, debug=False):
    tb = ValidReadyTb(dut, debug=debug)
    sin_driver = tb.driver("p_in", data_suffix=["data", "keep", "last"])
    pout_monitor = tb.monitor("s_out", data_suffix=["data", "keep", "last"])
    await tb.reset()
    # get bound parameters/generics from the simulator
    G_OUT_W = tb.get_value("G_OUT_W", int)
    G_N = tb.get_value("G_N", int)
    G_CHANNELS = tb.get_value("G_CHANNELS", int)
    G_ASYNC_RSTN = tb.get_value("G_ASYNC_RSTN", bool)
    G_BIGENDIAN = tb.get_value("G_BIGENDIAN", bool)
    G_SUBWORD = tb.get_value("G_SUBWORD", bool)

    def concat_words(g):
        return reduce(concat_bv, g if G_BIGENDIAN else reversed(g))

    tb.log.info(
        "[%s] G_OUT_W:%d G_N:%d G_CHANNELS:%d G_ASYNC_RSTN:%s G_BIGENDIAN:%s G_SUBWORD:%s num_tests:%d",
        str(dut),
        G_OUT_W,
        G_N,
        G_CHANNELS,
        G_ASYNC_RSTN,
        G_BIGENDIAN,
        G_SUBWORD,
        num_tests,
    )
    IN_WIDTH = G_OUT_W * G_N

    assert G_OUT_W % 8 == 0, "G_OUT_W should be multiple of bytes"

    M = 10  # max num parallel (input) words

    def div_ceil(n: int, m: int) -> int:
        return (n + m - 1) // m

    def valid_bytes(total_bytes, w, last=False) -> str:
        num_bytes = w // 8
        if last:
            r = total_bytes % num_bytes
            num_ones = num_bytes if r == 0 else r
        else:
            num_ones = num_bytes
        vb = ("0" * (num_bytes - num_ones)) + ("1" * num_ones)
        if G_BIGENDIAN:
            return vb[::-1]
        return vb

    for _test in range(num_tests):
        if G_SUBWORD:
            num_data_bytes = random.randint(1, M * IN_WIDTH // 8)
        else:
            # multiple of input number of bytes
            num_data_bytes = random.randint(1, M) * IN_WIDTH // 8

        num_in_words = div_ceil(num_data_bytes, IN_WIDTH // 8)
        num_out_words = div_ceil(num_data_bytes, G_OUT_W // 8)

        data_byte_channels = [
            [random_bits(8) for _ in range(num_data_bytes)] for _ in range(G_CHANNELS)
        ]
        expected_outputs_channels = [
            [
                concat_words(g)
                for g in grouper(
                    data_bytes,
                    G_OUT_W // 8,
                    incomplete=Incomplete.Fill,
                    fillvalue=BinaryValue(0, n_bits=8),
                )
            ]
            for data_bytes in data_byte_channels
        ]
        expected_outputs = [
            {
                "data": concat_words(per_channel),
                "keep": "1" * (G_OUT_W // 8),
                "last": 0,
            }  #
            for per_channel in zip(*expected_outputs_channels)
        ]

        in_data_channels = [
            [
                concat_words(g)
                for g in grouper(
                    data_byte,
                    IN_WIDTH // 8,
                    incomplete=Incomplete.Fill,
                    fillvalue=BinaryValue(
                        0,
                        n_bits=data_byte[0].n_bits if data_byte else None,
                    ),
                )
            ]
            for data_byte in data_byte_channels
        ]

        in_data = [
            {
                "data": concat_words(per_channel),
                "keep": "1" * (IN_WIDTH // 8),
                "last": 0,
            }
            for per_channel in zip(*in_data_channels)
        ]

        in_data[-1]["last"] = 1
        in_data[-1]["keep"] = valid_bytes(num_data_bytes, IN_WIDTH, last=True)
        expected_outputs[-1]["last"] = 1
        expected_outputs[-1]["keep"] = valid_bytes(num_data_bytes, G_OUT_W, last=True)

        stimulus = cocotb.start_soon(sin_driver.enqueue_seq(in_data))

        await pout_monitor.expect_seq(expected_outputs)

        await stimulus  # join stimulus thread


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

import cPickle
from utils import read_probes, read_links, read_link_ids, read_link_lengths, read_probe_ids, read_probe_times

def main():
    probe_file = 'data/probe_points.csv'
    link_file = 'data/links.csv'

    probes = read_probes(probe_file)
    probe_ids = read_probe_ids(probe_file)
    probe_times = read_probe_times(probe_file)

    links = read_links(link_file)
    link_ids = read_link_ids(link_file)
    link_lengths = read_link_lengths(link_file)

    with open("data/probes.pkl", "wb") as fout:
        cPickle.dump(probes, fout, 2)
    with open("data/probe_ids.pkl", "wb") as fout:
        cPickle.dump(probe_ids, fout, 2)
    with open("data/probe_times.pkl", "wb") as fout:
        cPickle.dump(probe_times, fout, 2)

    with open("data/links.pkl", "wb") as fout:
        cPickle.dump(links, fout, 2)
    with open("data/link_ids.pkl", "wb") as fout:
    	cPickle.dump(link_ids, fout, 2)
    with open("data/link_lengths.pkl", "wb") as fout:
    	cPickle.dump(link_lengths, fout, 2)

if __name__ == "__main__":
    main()


from flask import make_response, request,session
import pandas as pd
from flask_restful import Resource, Api, marshal_with, fields
from .database import db
from .models import *
from .tasks import export_csv
from werkzeug.exceptions import HTTPException
import json
from flask_login import current_user
from flask_security import auth_token_required
from .controllers import cache

class DefaultError(HTTPException):
    def __init__(self, status_code, desc):
        self.response = make_response('', status_code)
        self.description = "<p>"+desc+"</p>"

class Success(HTTPException):
    def __init__(self, status_code, msg):
        self.response = make_response(msg, status_code)

class BError(HTTPException):
    def __init__(self, status_code, errorcode, errormsg):
        message = {
  "error_code": errorcode,
  "error_message": errormsg
}
        self.response = make_response(json.dumps(message), status_code)

cardinfo = {
    "CardID" : fields.Integer,
    "ListID" : fields.Integer,
    "Date_created" : fields.DateTime,
    "Last_modified" : fields.DateTime,
    "Deadline": fields.DateTime,
    "Date_completed":fields.DateTime,
    "Value":fields.Integer,
    "Description":fields.String
}
listinfo = {
    "ListID": fields.Integer,
    "List_name": fields.String,
    "Description": fields.String
}

class UsersAPI(Resource):
    def get(self):
        return json.dumps(cache.get('userid'))

class CardsAPI(Resource):
    @auth_token_required
    def get(self,cardid):
        card = Cards.query.filter(Cards.CardID == cardid).first()
        cards = [card.as_dict()]
        export_csv.delay(cards,"downloads/cards/card-"+str(cardid)+"_"+card.Last_modified.strftime("%Y-%m-%d_%H:%M")+".csv")
        return

    @auth_token_required
    def post(self):
        try:
            curr_user = current_user
            details = json.loads(request.get_data())
        except:
            raise DefaultError(status_code=400, desc='Bad Request')
        result = []
        for card in details.values():
            try:
                cardid = card['CardID']
                datecomp=None
                if card['Date_completed'] != None:
                    datecomp = datetime.datetime.strptime(card['Date_completed'], "%Y-%m-%dT%H:%M")

                updatedcard = {
                    "Date_created":datetime.datetime.strptime(card['Date_created'], "%Y-%m-%dT%H:%M"),
                    "Last_modified":datetime.datetime.strptime(card['Last_modified'], "%Y-%m-%dT%H:%M"),
                    "Deadline":datetime.datetime.strptime(card['Deadline'], "%Y-%m-%dT%H:%M"),
                    "Date_completed":datecomp,
                    "Title":card['Title'],
                    "Value":card['Value'],
                    "Description":card['Description'],
                }
                dbcard = Cards.query.filter(Cards.CardID == cardid).update(updatedcard)
                assn = Cardlists.query.filter(Cardlists.CardID == cardid).update({'ListID':card['ListID']})
                db.session.commit()
                result.append(cardid)
            except:
                raise DefaultError(status_code=500, desc="Internal Server Error")
        return json.dumps(result)

    @auth_token_required
    def delete(self,cardid):
        try:
            Cards.query.filter(Cards.CardID == cardid).delete()
            Cardlists.query.filter(Cardlists.CardID == cardid).delete()
            db.session.commit()
        except:
            raise DefaultError(status_code=500, desc="Internal Server Error")

        return json.dumps(str(cardid)+" deleted successfuly")

class ListsAPI(Resource):
    @auth_token_required
    def get(self,listid):
        cards = Lists.query.filter(Lists.ListID == listid).first().cards.all()
        cards = [card.as_dict() for card in cards]
        export_csv.delay(cards,"downloads/lists/list-"+str(listid)+".csv")
        return

    @auth_token_required
    def post(self):
        try:
            curr_user = current_user
            details = json.loads(request.get_data())
        except:
            raise DefaultError(status_code=400, desc='Bad Request')
        result = []
        for list in details.values():
            try:
                listid = list['ListID']

                updatedlist = {
                    "List_name": list['List_name']
                }
                dbcard = Lists.query.filter(Lists.ListID == listid).update(updatedlist)
                db.session.commit()
                result.append(listid)
            except:
                raise DefaultError(status_code=500, desc="Internal Server Error")
        return json.dumps(result)


import camelot
import os

print("Extracting tables from PDF, please wait...")

# path of source pdf
source_file = "./source/data-new.pdf"

# save them in a folder - if the folder doesn't exist, create it
output_folder = "tables"
if not os.path.isdir(output_folder):
    os.mkdir(output_folder)

# extract all the tables in the PDF file
tables = camelot.read_pdf(source_file, pages="all")

# export tables to Excel - same workbook but each table in its own worksheet
try:
    tables.export(os.path.join(output_folder, f"exported_tables.xlsx"), f='excel', compress=False)
except:
    print("Unable to convert PDF tables to Excel. Please make sure you have a valid PDF file.")

# number of tables extracted
print("Total number of tables extracted:", tables.n)


import datetime
from tqdm import tqdm
import time

def get_date():
    date = datetime.datetime.now()
    date = str(date.strftime('%d/%m/%Y'))
    return date

"""
total students roll numbers
can keep list of strings as roll numbers can also have alphabets
Example: 18H51A05A0
"""
master_data = [x for x in range(1, 11)]

# Welcome message
print("\t\t\t     Welcome Back AbhisheK!!!\n\n\t\t\t\tHave A Great Day.\n")
time.sleep(1)

"""
Added loading to make it look nice (optional)
"""
print('Loading Attendance Program.........\n')
for i in tqdm(range(int(30))):
    time.sleep(0.1)

print("\nEnter Roll Numbers Space Seperated In Same Line Everytime:")
roll_numbers = list(map(int, input().split(' ')))
# wrong stores wrong roll numbers entered, human error
present, wrong = [], []
absent = master_data.copy()

for roll in roll_numbers:
    if roll in absent:
        absent.remove(roll)
        present.append(roll)
    else:
        wrong.append(roll)

print("\nToday's Date: ", get_date())
print('Total Students: ', len(master_data))

print('Present Students: ', len(present))
present.sort()
for i in present:
    print(i)
print('\nAbsent Students: ', len(absent))
absent.sort()
for i in absent:
    print(i)
print('\nWrong or Re-Entered Roll Numbers Entered: ', len(wrong))
wrong.sort()
for i in wrong:
    print(i)
"""
input in single line, as it makes easy to delete few roll numbers while entering input also
Input: 1 2 3 3 30
"""


import numpy as np
from scipy.signal import firwin2, filtfilt

from .fft import rfftfreq, rfft, irfft
from .utils import _npads, _smart_pad, _trim

def _apply_notches(X, notches, rate, fft=True):
    """Low-level code which applies notch filters.

    Parameters
    ----------
    X : ndarray, (n_time, n_channels)
        Input data.
    notches : ndarray
        Frequencies to notch filter.
    rate : float
        Number of samples per second for X.
    fft : bool
        Whether to filter in the time or frequency domain.

    Returns
    -------
    Xp : ndarray, (n_time, n_channels)
        Notch filtered data.
    """
    delta = 1.
    if fft:
        fs = rfftfreq(X.shape[0], 1. / rate)
        fd = rfft(X, axis=0)
    else:
        nyquist = rate / 2.
        n_taps = 1001
        gain = [1, 1, 0, 0, 1, 1]
    for notch in notches:
        if fft:
            window_mask = np.logical_and(fs > notch - delta, fs < notch + delta)
            window_size = window_mask.sum()
            window = np.hamming(window_size)
            fd[window_mask] = fd[window_mask] * (1. - window)[:, np.newaxis]
        else:
            freq = np.array([0, notch - delta, notch - delta / 2.,
                             notch + delta / 2., notch + delta, nyquist]) / nyquist
            filt = firwin2(n_taps, freq, gain)
            Xp = filtfilt(filt, np.array([1]), X, axis=0)
    if fft:
        Xp = irfft(fd, n=X.shape[0], axis=0)
    return Xp

def apply_linenoise_notch(X, rate, fft=True):
    """Apply notch filters at 60 Hz and its harmonics.

    Filters +/- 1 Hz around the frequencies.

    Parameters
    ----------
    X : ndarray, (n_time, n_channels)
        Input data.
    rate : float
        Number of samples per second for X.
    fft : bool
        Whether to filter in the time or frequency domain.

    Returns
    -------
    Xp : ndarray, (n_time, n_channels)
        Notch filtered data.
    """

    nyquist = rate / 2.
    noise_hz = 60.
    npad = rate
    if nyquist < noise_hz:
        return X
    notches = np.arange(noise_hz, nyquist, noise_hz)
    npads, to_removes, _ = _npads(X, npad)
    X = _smart_pad(X, npads)

    Xp = _apply_notches(X, notches, rate, fft=fft)
    Xp = _trim(Xp, to_removes)
    return Xp


from DDCN_model_p import *
from DDCN_testing_PKU_100_per import *
from DDCN_testing_PKU_50_per import *
from DDCN_testing_PKU_10_per import *
import numpy as np
from copy import deepcopy
import sklearn.metrics

############  PATHS ############### please fix the paths

dataset_path = '/home/acw6ze/DDCN/data/PKU/data_PKU.npy' # path for data
label_path = '/home/acw6ze/DDCN/data/PKU/labels_PKU.npy' # path for labels
model_path = '/home/acw6ze/DDCN/model/model_params_PKU.pkl' # path for model

############ loading data ##############

dataset_d = np.load(dataset_path, allow_pickle=True)
label_d = np.load(label_path, allow_pickle=True)
###################################################

dtype = torch.FloatTensor
ltype = torch.LongTensor

use_cuda = torch.cuda.is_available()
if use_cuda:
    print('use gpu')
    dtype = torch.cuda.FloatTensor
    ltype = torch.cuda.LongTensor

def scale(X, x_min, x_max):
    nom = (X-X.min(axis=0))*(x_max-x_min)
    denom = X.max(axis=0) - X.min(axis=0)
    denom[denom==0] = 1
    return x_min + nom/denom

##################### Testing on Observation Ratio = 100% ######################

model_100 = DDCNModel(layers=10,
                     blocks=3,
                     dilation_channels=32,
                     residual_channels=32,
                     skip_channels=1024,
                     end_channels=512,
                     output_length=16,
                     dtype=dtype,
                     bias=True)

if use_cuda:
    model_100.cuda()
model_100.receptive_field = 30

tester_100 = DDCNTester_100(model=model_100, # initializing DDCN model
                         lr=0.0001,
                         weight_decay=0.0,
                         snapshot_path='snapshots',
                         snapshot_name='chaconne_model',
                         snapshot_interval=1000,
                         dtype=dtype,
                         ltype=ltype,
                        )
tester_100.model_path = model_path
tester_100.dataset_d = dataset_d
tester_100.label_d = label_d

print('start testing DDCN on Observation Ratio = 100%...')
result_100, label_100 = tester_100.test() # loading DDCN model

result_100 = np.concatenate(result_100)

label_100 = np.concatenate(label_100)

labels_100 = []
results_100 = []

for i in range(0, label_100.shape[0]):
    if (label_100[i] != -1):
        labels_100.append(label_100[i])
        results_100.append(result_100[i])

labels_100 = np.array(labels_100)

results_100 = np.array(results_100)

results_class_100 = []

for i in range(0, len(results_100)):
    results_class_100.append(list(results_100[i]).index(max(results_100[i])))
results_class_100 = np.array(results_class_100)

f1_100 = sklearn.metrics.f1_score(labels_100, results_class_100, average='micro')

##################### Testing on Observation Ratio = 50% ######################

model_50 = DDCNModel(layers=10,
                     blocks=3,
                     dilation_channels=32,
                     residual_channels=32,
                     skip_channels=1024,
                     end_channels=512,
                     output_length=16,
                     dtype=dtype,
                     bias=True)

if use_cuda:
    model_50.cuda()
model_50.receptive_field = 30

tester_50 = DDCNTester_50(model=model_100,
                         lr=0.0001,
                         weight_decay=0.0,
                         snapshot_path='snapshots',
                         snapshot_name='chaconne_model',
                         snapshot_interval=1000,
                         dtype=dtype,
                         ltype=ltype,
                        )
tester_50.model_path = model_path
tester_50.dataset_d = dataset_d
tester_50.label_d = label_d

print('start testing DDCN on Observation Ratio = 50%...')

result_50, label_50 = tester_50.test()

result_50 = np.concatenate(result_50)

label_50= np.concatenate(label_50)

labels_50 = []
results_50 = []

for i in range(0, label_50.shape[0]):
    if (label_50[i] != -1):
        labels_50.append(label_50[i])
        results_50.append(result_50[i])

labels_50 = np.array(labels_50)

results_50 = np.array(results_50)

results_class_50 = []

for i in range(0, len(results_50)):
    results_class_50.append(list(results_50[i]).index(max(results_50[i])))
results_class_50 = np.array(results_class_50)

f1_50 = sklearn.metrics.f1_score(labels_50, results_class_50, average='micro')

##################### Testing on Observation Ratio = 10% ######################

model_10 = DDCNModel(layers=10,
                     blocks=3,
                     dilation_channels=32,
                     residual_channels=32,
                     skip_channels=1024,
                     end_channels=512,
                     output_length=16,
                     dtype=dtype,
                     bias=True)

if use_cuda:
    model_10.cuda()
model_10.receptive_field = 30

tester_10 = DDCNTester_10(model=model_10,
                         lr=0.0001,
                         weight_decay=0.0,
                         snapshot_path='snapshots',
                         snapshot_name='chaconne_model',
                         snapshot_interval=1000,
                         dtype=dtype,
                         ltype=ltype,
                        )
tester_10.model_path = model_path
tester_10.dataset_d = dataset_d
tester_10.label_d = label_d

print('start testing DDCN on Observation Ratio = 10%...')
result_10, label_10 = tester_10.test()

result_10 = np.concatenate(result_10)

label_10 = np.concatenate(label_10)

labels_10 = []
results_10 = []

for i in range(0, label_10.shape[0]):
    if (label_10[i] != -1):
        labels_10.append(label_10[i])
        results_10.append(result_10[i])

labels_10 = np.array(labels_10)

results_10 = np.array(results_10)

results_class_10 = []

for i in range(0, len(results_10)):
    results_class_10.append(list(results_10[i]).index(max(results_10[i])))
results_class_10 = np.array(results_class_10)

f1_10 = sklearn.metrics.f1_score(labels_10, results_class_10, average='micro')

################ printing the results #################################

print( 'F1 score for DDCN on OR 100%  = ' + str(round(f1_100*100, 2)) + '%')
print( 'F1 score for DDCN on OR 50%  = ' + str(round(f1_50*100, 2)) + '%')
print( 'F1 score for DDCN on OR 10%  = ' + str(round(f1_10*100, 2)) + '%')


import os
import sys
import numpy as np

import torch
from torch import nn
import torch.nn.functional as F

class Cell(nn.Module):
    def __init__(self, in_dim, hidden_dim, out_dim, activation_function=torch.tanh,
                 activation_function_out=F.relu, state_initializer=None):
        super(Cell, self).__init__()
        self.in_dim = in_dim
        self.state_size = hidden_dim
        self.hidden_dim = hidden_dim
        self.out_dim = out_dim
        self.act_fun = activation_function
        self.act_fun_out = activation_function_out
        self.state_init = state_initializer
        self.a = None
        self.init_state()  # state

    def update_state(self, s):
        self.a = s

    def init_state(self, initializer=None):
        if self.state_init is not None:
            if callable(self.state_init):
                self.a = self.state_init(1, self.hidden_dim)
                assert self.hidden_dim in self.a.shape
            if isinstance(self.state_init, int):
                self.a = torch.zeros(1, self.hidden_dim) + initializer
        else:
            self.a = torch.zeros(1, self.hidden_dim)
        self.a.requires_grad = False

    def reset_state(self):
        self.init_state()

# Simple Recurrent Cell
class RNN(Cell):
    def __init__(self, in_dim, hidden_dim, out_dim, activation_function=F.tanh,
                 activation_function_out=F.relu, state_initializer=None):
        # in_dim = number of featurse for one element of time series
        super(RNN, self).__init__(in_dim, hidden_dim, out_dim, activation_function=activation_function,
                 activation_function_out=activation_function_out, state_initializer=state_initializer)
        self.w_in = nn.Linear(in_features=self.state_size+in_dim,
                              out_features=self.state_size)
        self.w_y = nn.Linear(self.state_size, out_dim)

    def forward(self, x, state=None):
        if state is None:
            state = self.a
        ax = self.w_in(torch.cat((state, x), 1))
        new_state = self.act_fun(ax)
        y = self.w_y(new_state)  # ? already use the new a here?
        y = self.act_fun_out(y)
        return y, new_state

# GRU cell ???
class GRU(Cell):
    def __init__(self, in_dim, hidden_dim, out_dim, activation_function=F.tanh,
                 activation_function_out=F.relu, state_initializer=None):
        # in_dim = number of featurse for one element of time series
        super(GRU, self).__init__(in_dim, hidden_dim, out_dim, activation_function=activation_function,
                 activation_function_out=activation_function_out, state_initializer=state_initializer)

        comb_size = hidden_dim+in_dim
        self.w_in = nn.Linear(in_features=comb_size, out_features=comb_size )
        self.w_y = nn.Linear(hidden_dim, out_dim)
        self.act_fun = activation_function
        self.act_fun_out = activation_function_out
        self.gate_update = nn.Linear(in_features=comb_size , out_features=hidden_dim)
        self.gate_relevance = nn.Linear(in_features=comb_size, out_features=comb_size)

    def forward(self, x):
        ax = torch.cat((self.a, x))
        gr = torch.sigmoid(self.gate_relevance(ax))
        ar = torch.mul(gr, self.a)
        arx = torch.cat((ar, x))
        new_state = self.act_fun(self.w_in(arx))
        gu = torch.sigmoid(self.gate_update(ax))
        new_state = torch.mul(gu, new_state) + torch.mul((1-gu), self.a)
        y = self.w_y(new_state)
        y = self.act_fun_out(y)
        return y, new_state

# LSTM cell
class LSTM(Cell):
    def __init__(self, in_dim, hidden_dim, out_dim, activation_function=F.tanh,
                 activation_function_out=F.relu, state_initializer=None):
        super(LSTM, self).__init__(in_dim, hidden_dim, out_dim, activation_function=activation_function,
                 activation_function_out=activation_function_out, state_initializer=state_initializer)
        raise NotImplementedError('LSMT not implemented')