from functools import cache
from random import random
import time
from generalizedYShapeAnalysis import YLattice
from newNodeNetwork import NodeNetwork, Node
import numpy as np
import cv2
import math
import argparse

#Set up argparser to allow for input image
parser = argparse.ArgumentParser(description='MFM image analysis')
parser.add_argument('image', metavar='image', type=str, nargs='+',help='Path of image')
parser.add_argument('-s', "--spacing",  help="how dense the islands are packed small=denser (default=0.25)", type=float, default=0.25)
parser.add_argument("-t", "--trim", help="Set if the offset row is shorter than the non-offset rows",action="store_true", default=False)
parser.add_argument("-a", "--reference_image", help="image of the height(to help line up the sample points)", type=str)
args=parser.parse_args()

WINDOWSIZE=800

#read image and reference image
try:
    phase_image = cv2.imread(args.image[0])
    phase_image=cv2.resize(phase_image,(WINDOWSIZE,WINDOWSIZE))
except:
    raise Exception("File not found")

if args.reference_image is not None:
    try:
        height_image = cv2.imread(args.reference_image)
        height_image = cv2.resize(height_image, (WINDOWSIZE,WINDOWSIZE))
    except:
        raise Exception("File not found")
else:
    height_image=np.zeros((WINDOWSIZE,WINDOWSIZE,3), np.uint8)

def getBWImage(image):
        pointSampleWidth=1
        avg_color_per_row = np.average(image, axis=0)
        avg_color = np.average(avg_color_per_row, axis=0)
        avg=np.average(avg_color,axis=0)

        print("Average color:",avg)
        blur = cv2.GaussianBlur(image,(pointSampleWidth,pointSampleWidth),15)

        blurredImage=blur
        blur=cv2.cvtColor(blur,cv2.COLOR_RGB2GRAY)
        BWImage=cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11,0)
        #BWImage=cv2.cvtColor(BWImage,cv2.COLOR_GRAY2RGB)

        return BWImage

global lastMouse

def degToRad(ang):
    return ang*np.pi/180
def cosDeg(ang):
    return np.cos(degToRad(ang))
def sinDeg(ang):
    return np.sin(degToRad(ang))

class RowCol:
    def __init__(self,row,col):
        self.row=row
        self.col=col
    def __str__(self) -> str:
        return f"r{self.row}c{self.col}"
    def __hash__(self):
        return hash(str(self))

class YIsland():
    def __init__(self,row,col,leg1Angle,radius):
        self.leg1Angle=leg1Angle
        self.row=row
        self.col=col
        self.radius=radius

    def getPoints(self):

        center=np.array([self.col,self.row])
        points=[center]
        for angle in [self.leg1Angle, self.leg1Angle+120, self.leg1Angle+240]:
            points.append(center+self.radius*np.array([cosDeg(angle),sinDeg(angle)]))

        return [RowCol(point[1],point[0]) for point in points]

    def hasError(colorPattern):
        return sum(colorPattern)!=0

class Pattern:
    def __init__(self,repeatRow,repeatCol):
        self.repeatRow=repeatRow
        self.repeatCol=repeatCol
        self.islands=[]

        self.colOffset=0
        self.rowOffset=0

        self.colEndOffset=0
        self.rowEndOffset=0

    def addIsland(self,island):
        self.islands.append(island)

    def invalidateCache(self):
        self.getSamplePoints.cache_clear()

    @cache
    def getSamplePoints(self,maxRow,maxCol):
        if self.colOffset>0:self.colOffset-=self.repeatCol
        if self.colOffset<-self.repeatCol: self.colOffset+=self.repeatCol
        if self.rowOffset>0:self.rowOffset-=self.repeatRow
        if self.rowOffset<-self.repeatRow: self.rowOffset+=self.repeatRow
        if self.colEndOffset>0:self.colEndOffset=0
        if self.rowEndOffset>0:self.rowEndOffset=0

        legAngles=[]
        points=[]
        for island in self.islands:
            islePoints=island.getPoints()
            for point in islePoints:
                point.row-=2*self.rowOffset
                point.col-=2*self.colOffset
            points.append(islePoints)
            legAngles.append(island.leg1Angle)

        newPoints=[]
        for i in range(math.floor(self.rowOffset),math.ceil(maxRow/self.repeatRow)):
            for island,legAngle in zip(points,legAngles):
                pointGroup=[]
                for point in island:
                    pointGroup.append(RowCol(point.row+i*self.repeatRow,point.col))
                newPoints.append(pointGroup)
                legAngles.append(legAngle)
        points+=newPoints

        newPoints=[]
        for i in range(math.floor(self.colOffset),math.ceil(maxCol/self.repeatCol)):
            for island,legAngle in zip(points,legAngles):
                pointGroup=[]
                for point in island:
                    pointGroup.append(RowCol(point.row,point.col+i*self.repeatCol))
                newPoints.append(pointGroup)
                legAngles.append(legAngle)
        points+=newPoints

        validPoints=[]
        validLegAngles=[]
        for island,legAngle in zip(points,legAngles):
            valid=True
            for point in island:
                if point.row<0 or point.col<0 or point.row>=maxRow+self.rowEndOffset or point.col>=maxCol+self.colEndOffset:
                    valid=False
                    break

            if valid:
                validPoints.append(island)
                validLegAngles.append(legAngle)
        points=validPoints
        legAngles=validLegAngles

        #remove duplicates
        seenHashes=[]
        validPoints=[]
        validLegAngles=[]
        for island,legAngle in zip(points,legAngles):
            thisHash=hash(",".join([str(point) for point in island]))
            if thisHash not in seenHashes:
                validPoints.append(island)
                validLegAngles.append(legAngle)
                seenHashes.append(thisHash)

        assert len(validPoints)==len(validLegAngles)

        return validPoints, validLegAngles

    def incrementYRadius(self):
        for island in self.islands:
            island.radius*=1.01
        self.invalidateCache()
    def decrementYRadius(self):
        for island in self.islands:
            island.radius*=0.99
        self.invalidateCache()

latticeType="bethe"

if latticeType=="normal":
    yLattice=Pattern(math.sqrt(3),2)
    yLattice.addIsland(YIsland(0,0.5,90,0.1))
    yLattice.addIsland(YIsland(0,1.5,90,0.1))
    yLattice.addIsland(YIsland(math.sqrt(3)/2,1,90,0.1))
    yLattice.addIsland(YIsland(math.sqrt(3)/2,2,90,0.1))
elif latticeType=="YOnKag":
    yLattice=Pattern(math.sqrt(3),2)
    yLattice.addIsland(YIsland(0,0,90,0.1))
    yLattice.addIsland(YIsland(0,1,90,0.1))
    yLattice.addIsland(YIsland(math.sqrt(3)/2,0.5,90,0.1))
elif latticeType=="YOnHex":
    yLattice=Pattern(math.sqrt(3),3)
    yLattice.addIsland(YIsland(0,0,90,0.1))
    yLattice.addIsland(YIsland(0,1,90,0.1))
    yLattice.addIsland(YIsland(math.sqrt(3)/2,1.5,90,0.1))
    yLattice.addIsland(YIsland(math.sqrt(3)/2,2.5,90,0.1))
elif latticeType=="hex":
    yLattice=Pattern(math.sqrt(3),3)
    yLattice.addIsland(YIsland(0,0,0,0.1))
    yLattice.addIsland(YIsland(0,1,60,0.1))
    yLattice.addIsland(YIsland(math.sqrt(3)/2,1.5,0,0.1))
    yLattice.addIsland(YIsland(math.sqrt(3)/2,2.5,60,0.1))
elif latticeType=="snowflake":
    r3o2=math.sqrt(3)/2

    yLattice=Pattern((math.sqrt(5)/2+4/8),1)
    yLattice.addIsland(YIsland(1/8,0,30,0.1))
    yLattice.addIsland(YIsland(-1/8,0.5,90,0.1))
    yLattice.addIsland(YIsland(math.sqrt(5)/4+1/8,0,90,0.1))
    yLattice.addIsland(YIsland(math.sqrt(5)/4+3/8,0.5,30,0.1))
    #yLattice.addIsland(YIsland(0,,90,0.1))
    #yLattice.addIsland(YIsland(0,1.5,30,0.1))
elif latticeType=="chiral":
    angle=15
    print(f"chiral angle: {angle} degrees")

    yLattice=Pattern(math.sqrt(3),2)
    yLattice.addIsland(YIsland(0,0.5,90-angle,0.1))
    yLattice.addIsland(YIsland(0,1.5,90-angle,0.1))
    yLattice.addIsland(YIsland(math.sqrt(3)/2,1,90-angle,0.1))
    yLattice.addIsland(YIsland(math.sqrt(3)/2,2,90-angle,0.1))
elif latticeType=="bethe":
    yLattice=Pattern(10,10)
    n=2
    gamma=0
    r3o2=math.sqrt(3)/2

    def addBetheIslands(yLattice,x,y,n,vectorAngle,islandSpacing,radius,gamma):
        if n==0:
            return

        if vectorAngle is None:
            angle=-90
            nextAngles=[90,210,330]
        else:
            angle=vectorAngle
            print(vectorAngle)
            nextAngles=[vectorAngle+60,vectorAngle-60]
        yLattice.addIsland(YIsland(y,x,-angle,radius))

        islandSpacing=islandSpacing*((1-gamma))
        for angle in nextAngles:
            addBetheIslands(yLattice,x+islandSpacing*cosDeg(angle),y+islandSpacing*sinDeg(angle),n-1,angle,islandSpacing,radius*(1-gamma),gamma)

    addBetheIslands(yLattice,1,1,n,None,2,0.5,gamma)

    # if N>1:
    #     dist=(1-gamma)+(1-2*gamma)
    #     yLattice.addIsland(YIsland(1/2*dist,-r3o2*dist,90,1-gamma))
    #     yLattice.addIsland(YIsland(0,dist,90,1-gamma))
    #     yLattice.addIsland(YIsland(-1/2*dist,-r3o2*dist,90,1-gamma))

BWImage=getBWImage(phase_image)

imageShown="phase"

def show():
    image=[]
    if imageShown=="phase":
        image=phase_image.copy()
    elif imageShown=="height":
        image=height_image.copy()
    elif imageShown=="bw":
        image=cv2.cvtColor(BWImage.copy(),cv2.COLOR_GRAY2RGB)

    n.draw(image,showGrid=False)

    if not n.dragging:
        points,_=yLattice.getSamplePoints(n.rows-1,n.cols-1)
        for island in points:
            colorPattern=[]
            for point in island:
                coord=n.getXY(point.row,point.col)
                bwColor=BWImage[coord[1]][coord[0]]
                if bwColor==0:
                    color=(255,0,0)
                    colorPattern.append(-1)
                elif bwColor==255:
                    color=(0,0,255)
                    colorPattern.append(1)
                else:
                    color=(0,255,0)
                    colorPattern.append(0)
                cv2.circle(image,coord,2,color,-1)

            if YIsland.hasError(colorPattern):
                cv2.circle(image,n.getXY(island[0].row,island[0].col),5,(0,255,0),3)

    cv2.imshow("window",image)

def cycleArea(x,y):
    type=BWImage[y][x]
    blankSquare=np.zeros((4,4))
    if type==255:
        blankSquare[::]=0
    elif type==0:
        blankSquare[::]=127
    elif(type==127):
        blankSquare[::]=255

    BWImage[(y-2):(y+2),(x-2):(x+2)]=blankSquare

def countTotalErrors():
    total=0
    points,_=yLattice.getSamplePoints(n.rows-1,n.cols-1)
    for island in points:
        colorPattern=[]
        for point in island:
            coord=n.getXY(point.row,point.col)
            bwColor=BWImage[coord[1]][coord[0]]
            if bwColor==0:
                colorPattern.append(-1)
            elif bwColor==255:
                colorPattern.append(1)
            else:
                colorPattern.append(0)

        if YIsland.hasError(colorPattern):
            total+=1
    return total

def jiggle(x,y):
    fixedPoint=n.getNearestFixedPoint(x,y)

    errorsBefore=countTotalErrors()

    node=fixedPoint["node"]
    originalNode=node.copy()

    radius=5

    node.x+=random()*2*radius-radius
    node.y+=random()*2*radius-radius
    n.invalidateCache()

    if(errorsBefore<countTotalErrors()):
        fixedPoint["node"]=originalNode

    n.invalidateCache()

def dataAsString():
    string="row,col,leg 1 angle,leg 1 color,leg 2 color,leg 3 color,center color\n"
    points,legAngles=yLattice.getSamplePoints(n.rows-1,n.cols-1)
    for island,legAngle in zip(points,legAngles):
        colorPattern=[]
        for point in island:
            coord=n.getXY(point.row,point.col)
            bwColor=BWImage[coord[1]][coord[0]]
            if bwColor==0:
                colorPattern.append(-1)
            elif bwColor==255:
                colorPattern.append(1)
            else:
                colorPattern.append(0)
        colorCode=colorPattern
        string+=f"{island[0].row},{island[0].col},{legAngle},{colorCode[1]},{colorCode[2]},{colorCode[3]},{colorCode[0]}\n"

    return string

def mouse_event(event, x, y,flags, param):
    global lastMouse
    if event == cv2.EVENT_RBUTTONDOWN:
        n.splitAtClosestPoint(x,y)
    elif event ==cv2.EVENT_LBUTTONDOWN:
        n.selectNearestFixedPoint(x,y)
        n.dragging=True
    elif event==cv2.EVENT_MOUSEMOVE:
        n.updateDragging(x,y)
    elif event==cv2.EVENT_LBUTTONUP:
        n.stopDragging()
    elif event == cv2.EVENT_RBUTTONDOWN:
        pass

    lastMouse=(x,y)

    show()

n=NodeNetwork(Node(10,10),Node(600,10),Node(10,600),Node(600,600),15,15)

show()
cv2.setMouseCallback('window', mouse_event)

while(True):
    show()

    key=cv2.waitKey(0)
    if(key==ord("\r")):
        break;
    elif(key==ord("r")):
        n.addRow()
    elif(key==ord("e")):
        n.removeRow()
    elif(key==ord("c")):
        n.addCol()
    elif(key==ord("x")):
        n.removeCol()
    elif(key==ord("q")):
        if imageShown=="phase":imageShown="height"
        elif imageShown=="height":imageShown="bw"
        elif imageShown=="bw":imageShown="phase"
    elif(key==ord("+")):
        yLattice.incrementYRadius()
    elif(key==ord("-")):
        yLattice.decrementYRadius()
    elif(key==ord("g")):
        yLattice.rowOffset-=0.01
        yLattice.invalidateCache()
    elif(key==ord("h")):
        yLattice.colOffset-=0.01
        yLattice.invalidateCache()
    elif(key==ord("a")):
        cycleArea(*lastMouse)
    elif(key==ord("j")):
        start=time.time()
        while(time.time()-start<0.25):
            jiggle(*lastMouse)
        print(countTotalErrors())
    elif(key==ord("b")):
        yLattice.colEndOffset-=0.25
        yLattice.invalidateCache()
    elif(key==ord("n")):
        yLattice.colEndOffset+=.25
        yLattice.invalidateCache()
    elif(key==ord("k")):
        yLattice.rowEndOffset-=0.25
        yLattice.invalidateCache()
    elif(key==ord("l")):
        yLattice.rowEndOffset+=0.25
        yLattice.invalidateCache()

outputname=args.image[0].split("/")[-1].split(".")[0]
print(outputname)

with open(outputname+".csv", 'w') as file:
    file.write(dataAsString())

outputImage=np.zeros((1000,1000,3), np.uint8)
outputImage[:,:]=(127,127,127)

cv2.imwrite("output.jpg", np.float32(outputImage));

cv2.destroyAllWindows()


import p1_maps

class Steps:
    def __init__(self, locationList):
        self.jsonData = p1_maps.getDirectionsData(locationList)

    def getInfo(self):

        if self.jsonData["route"]["routeError"]["errorCode"] == 2:
            yield "\nNO ROUTE FOUND"
        elif self.jsonData["route"]["routeError"]["errorCode"] == -400:
            yield "\nDIRECTIONS\n"+self.jsonData["route"]["legs"][0]["origNarrative"]

            manSize = len(self.jsonData["route"]["legs"][0]["maneuvers"])
            for i in range(manSize):
                yield self.jsonData["route"]["legs"][0]["maneuvers"][i]["narrative"]
        else:
            yield "\nMAPQUEST ERROR"

class TotalTime:
    def __init__(self, locationList):
        self.jsonData = p1_maps.getDirectionsData(locationList)

    def getInfo(self):

        if self.jsonData["route"]["routeError"]["errorCode"] == 2:
            yield "\nNO ROUTE FOUND"
        elif self.jsonData["route"]["routeError"]["errorCode"] == -400:
            yield "\nTOTAL TIME: %d minutes" % (self.jsonData["route"]["legs"][0]["time"]/60)
        else:
            yield "\nMAPQUEST ERROR"

class TotalDistance:
    def __init__(self, locationList):
        self.jsonData = p1_maps.getDirectionsData(locationList)

    def getInfo(self):

        if self.jsonData["route"]["routeError"]["errorCode"] == 2:
            yield "\nNO ROUTE FOUND"
        elif self.jsonData["route"]["routeError"]["errorCode"] == -400:
            yield "\nTOTAL DISTANCE: %d miles" % self.jsonData["route"]["legs"][0]["distance"]
        else:
            yield "\nMAPQUEST ERROR"

class LatLong:
    def __init__(self, locationList):
        self.locationList = locationList
        self.jsonData = p1_maps.getDirectionsData(locationList)

    def getInfo(self):

        if self.jsonData["route"]["routeError"]["errorCode"] == 2:
            yield "\nNO ROUTE FOUND"
        elif self.jsonData["route"]["routeError"]["errorCode"] == -400:
            print("\nLATLONGS")
            for i in self.locationList:
                latLng = (p1_maps.getGeocodingData(i))["results"][0]["locations"][0]["latLng"]
                lat = ("%.2f" % latLng["lat"] + "N") if latLng["lat"] > 0 else ("%.2f" % ((-1.0)*(latLng["lat"])) + "S")
                lng = ("%.2f" % latLng["lng"] + "E") if latLng["lng"] > 0 else ("%.2f" % ((-1.0)*(latLng["lng"])) + "W")
                yield lat + " " + lng

        else:
            yield "\nMAPQUEST ERROR"

class Elevation:
    def __init__(self, locationList):
        self.locationList = locationList
        self.jsonData = p1_maps.getDirectionsData(locationList)
    def getInfo(self):

        if self.jsonData["route"]["routeError"]["errorCode"] == 2:
            yield "\nNO ROUTE FOUND"
        elif self.jsonData["route"]["routeError"]["errorCode"] == -400:
            print("\nELEVATIONS")

            for i in self.locationList:
                latLngDict = (p1_maps.getGeocodingData(i))["results"][0]["locations"][0]["latLng"]
                latLng = str(latLngDict["lat"])+ "," +str(latLngDict["lng"])
                yield (p1_maps.getElevationData(latLng))["elevationProfile"][0]["height"]

        else:
            yield "\nMAPQUEST ERROR"


"""

Citation:
@inproceedings{ bitsnlp2021dravidian,
 title={Sentiment Analysis of Dravidian Code Mixed Data},
 author={Mandalam, Asrita Venkata and Sharma, Yashvardhan},
 booktitle={ 15th Conference of the European Chapter of the Association for Computational Linguistics 2021 (EACL 2021) },
 year={2021}
}

"""

import numpy as np
import pandas as pd
import re
from keras.layers import LSTM, Dense, Embedding, Input
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
import keras

from tqdm import tqdm
tqdm.pandas(desc="progress-bar")
from gensim.models.word2vec import Word2Vec
from gensim.models.doc2vec import TaggedDocument
import multiprocessing
from sklearn import utils
from keras.models import Model
from keras.layers import BatchNormalization, Activation

def token(sentence):
    tokens = []
    for t in re.findall("[a-zA-Z]+",sentence):
         if len(t)>=1:
             tokens.append(t)
    return tokens

def emoji_ch (words):
    if words == 'ЁЯШД' :
      words='good'
    elif words == 'ЁЯШЖ' :
      words='good'
    elif words == 'ЁЯШК' :
      words='good'
    elif words == 'ЁЯШГ' :
      words='good'
    elif words == 'ЁЯдм' :
      words='bad'
    elif words == 'ЁЯШП' :
      words='good'
    elif words == 'ЁЯШН' :
      words='good'
    elif words == 'ЁЯШШ' :
      words='good'
    elif words == 'ЁЯШЪ' :
      words='good'
    elif words == 'ЁЯШ│' :
      words='flushed'
    elif words == 'ЁЯШМ' :
      words='bad'
    elif words == 'ЁЯШЖ' :
      words='good'
    elif words == 'ЁЯШВ' :
      words='good'
    elif words == 'ЁЯШО' :
      words='good'
    elif words == 'ЁЯдп' :
      words='blow_mind'
    elif words == 'тЬМя╕П' :
      words='vhand'
    elif words == 'ЁЯдШ' :
      words='metal'
    elif words == 'ЁЯдж' :
      words='bad'
    elif words == 'ЁЯдй':
      words='good'
    elif words == 'ЁЯе░':
      words='good'
    elif words == 'ЁЯдФ':
      words='thinking'
    elif words == 'ЁЯдг':
      words='good'
    elif words == 'ЁЯдЧ':
      words = 'good'
    else :
      return None
    return words+" "

def tamilchar(ch):
    if ch == u'\u0B85' or ch== u'роЕ':
        ch="A"
    elif ch == u'\u0B86' or ch== u'роЖ':
        ch="AA"
    elif ch == u'\u0B87' or ch== u'роЗ':
        ch="I"
    elif ch == u'\u0B88' or ch== u'роИ':
        ch="II"
    elif ch == u'\u0B89' or ch== u'роЙ':
        ch="U"
    elif ch == u'\u0B8A' or ch== u'роК':
        ch="UU"
    elif ch == u'\u0B8E' or ch== u'роО':
        ch="E"
    elif ch == u'\u0B8F' or ch== u'роП':
        ch="EE"
    elif ch == u'\u0B90' or ch== u'роР':
        ch="AI"
    elif ch == u'\u0B92' or ch== u'роТ':
        ch="O"
    elif ch == u'\u0B93' or ch== u'роУ':
        ch="OO"
    elif ch == u'\u0B94' or ch== u'роФ':
        ch="AU"
    elif ch ==u'\u0B95'or ch==u'роХ':
        ch="KA"
    elif ch ==u'\u0B99'or ch==u'роЩ':
        ch="NGA"
    elif ch ==u'\u0B9A'or ch==u'роЪ':
        ch="SA"
    elif ch ==u'\u0B9C' or ch==u'роЬ':
        ch="JA"
    elif ch ==u'\u0B9E'or ch==u'роЮ':
        ch=u"NYA"
    elif ch ==u'\u0B9F'or ch==u'роЯ':
        ch="DA"
    elif ch ==u'\u0BA3'or ch==u'рог':
        ch="NNA"
    elif ch ==u'\u0BA4'or ch==u'род':
        ch="THA"
    elif ch ==u'\u0BA8'or ch==u'рои':
        ch="NA"
    elif ch ==u'\u0BA9' or ch==u'рой':
        ch="NA"
    elif ch ==u'\u0BAA'or ch==u'рок':
        ch="PA"
    elif ch ==u'\u0BAE'or ch==u'роо':
        ch="MA"
    elif ch ==u'\u0BAF' or ch==u'роп':
        ch="YA"
    elif ch ==u'\u0BB0' or ch==u'ро░':
        ch="RA"
    elif ch ==u'\u0BB1'or ch==u'ро▒':
        ch="RRA"
    elif ch ==u'\u0BB2' or ch==u'ро▓':
        ch="LA"
    elif ch ==u'\u0BB3'or ch==u'ро│':
        ch="LLA"
    elif ch ==u'\u0BB4'or ch ==u'ро┤':
        ch=="LLLA"
    elif ch ==u'\u0BB5'or ch==u'ро╡':
        ch="VA"
    elif ch ==u'\u0BB6'or ch==u'ро╢':
        ch="SHA"
    elif ch ==u'\u0BB7'or ch==u'ро╖':
        ch="SSA"
    elif ch ==u'\u0BB8'or ch==u'ро╕':
        ch="SA"
    elif ch ==u'\u0BB9'or ch==u'ро╣':
        ch="HA"
    elif ch ==u'\u0BBE'or ch==u'$ро╛':
        ch="AA"
    elif ch ==u'\u0BBF'or ch==u'$ро┐':
        ch="I"
    elif ch ==u'\u0BC0'or ch==u'$рпА':
        ch="II"
    elif ch ==u'\u0BC1'or ch==u'$рпБ':
        ch="U"
    elif ch ==u'\u0BC2'or ch==u'рпВ$':
        ch="UU"
    elif ch ==u'\u0BC6'or ch==u'$рпЖ':
        ch="E"
    elif ch ==u'\u0BC7'or ch==u'$рпЗ':
        ch="EE"
    elif ch ==u'\u0BC8'or ch==u'$рпИ':
        ch="AI"
    elif ch ==u'\u0BCA'or ch==u'$рпК':
        ch="O"
    elif ch ==u'\u0BCB'or ch==u'$рпЛ':
        ch="OO"
    elif ch ==u'\u0BCC'or ch==u'$рпМ':
        ch="AU"
    elif ch ==u'\u0BCD'or ch==u'$рпН':
        ch="PULLI"
    elif ch ==u'\u0BD0'or ch==u'рпР':
        ch="OM"
    elif ch ==u'\u0BD7'or ch==u'$рпЧ':
        ch="AU"
    else:
        return None
    return ch

def preprocess(word):
  word=re.sub(r'([a-z])\1+', r'\1',word)
  return word

def tamilword(word):
    fla=0
    string=""
    for ch in word:
        if(tamilchar(ch) is not None):
            ch=tamilchar(ch)
            fla=1
        if(emoji_ch(ch) is not None):
            ch=emoji_ch(ch)
            fla=1
        string=string+str(ch)
    if(fla==1):
        return string
    else:
        return None

def malchar(ch):
    if ch == u'р┤Е':
        ch="A"
    elif ch == u'р┤Ж':
        ch="AA"
    elif ch == u'р┤З':
        ch="I"
    elif ch == u'р┤И':
        ch="II"
    elif ch == u'р┤Й':
        ch="U"
    elif ch == u'р┤К':
        ch="UU"
    elif ch == u'р┤О':
        ch="E"
    elif ch == u'р┤П':
        ch="EE"
    elif ch == u'р┤Р':
        ch="AI"
    elif ch == u'р┤Т':
        ch="O"
    elif ch == u'р┤У':
        ch="OO"
    elif ch == u'р┤Ф':
        ch="AU"
    elif ch ==u'р┤Х'or ch==u'р┤Ц':
        ch="KA"
    elif ch ==u'р┤Ч'or ch==u'р┤Ш':
        ch="GA"
    elif ch ==u'р┤Щ':
        ch="NGA"
    elif ch ==u'р┤Ъ'or ch==u'р┤Ы':
        ch="CH"
    elif ch ==u'р┤Ъ'or ch==u'р┤Ы':
        ch="CH"
    elif ch ==u'р┤╢'or ch==u'р┤╖':
        ch="SH"
    elif ch ==u'р┤╕':
        ch="S"
    elif ch ==u'р┤Ь' or ch==u'р┤Э':
        ch="JA"
    elif ch ==u'р┤б'or ch==u'р┤ж':
        ch="DA"
    elif ch ==u'р┤е'or ch==u'р┤д':
        ch="THA"
    elif ch ==u'р┤г'or ch==u'р┤и':
        ch="NA"
    elif ch ==u'р┤к':
        ch="PA"
    elif ch ==u'р┤о':
        ch="MA"
    elif ch ==u'р┤п':
        ch="YA"
    elif ch ==u'р┤░':
        ch="RA"
    elif ch ==u'р┤│':
        ch="LA"
    elif ch ==u'р┤╡':
        ch="VA"
    elif ch ==u'р┤╣':
        ch="HA"
    elif ch ==u'р┤н'or ch==u'р┤м':
        ch="BA"
    elif ch ==u'р┤в'or ch==u'р┤з':
        ch="DH"
    elif ch ==u'р┤а':
        ch="DT"
    elif ch ==u'р┤Я':
        ch="T"
    elif ch ==u'р┤Ю':
        ch="NJ"
    elif ch ==u'р┤л':
        ch="PH"
    elif ch ==u'р┤┤':
        ch="ZH"
    elif ch ==u'р┤▒':
        ch="RA"
    else:
        return None
    return ch

def malword(word):
    fla=0
    string=""
    for ch in word:
        if(malchar(ch) is not None):
            ch=malchar(ch)
            fla=1
        string=string+str(ch)
    if(fla==1):
        return string
    else:
        return None

colnames=['text','label']
df = pd.read_csv(r'/content/drive/My Drive/Dravidian/EACL/tamil_train.tsv',names=colnames, delimiter='\t', error_bad_lines=False, header=None,
                      usecols=['text','label'], na_values=" NaN",skiprows=[0])

df_val = pd.read_csv(r'/content/drive/My Drive/Dravidian/EACL/tamil_dev.tsv',names=colnames, delimiter='\t', error_bad_lines=False, header=None,
                      usecols=['text','label'], na_values=" NaN",skiprows=[0])

colnames=['index','text','label']
df_test = pd.read_csv(r'/content/drive/My Drive/Dravidian/EACL/tamil_test.tsv',names=colnames, delimiter='\t', error_bad_lines=False, header=None,
                      usecols=['text','label'], na_values=" NaN",skiprows=[0])

# colnames=['text','label']
# df = pd.read_csv(r'/content/drive/MyDrive/Dravidian/EACL/malayalam_train.tsv',names=colnames, delimiter='\t', error_bad_lines=False, header=None,
#                       usecols=['text','label'], na_values=" NaN",skiprows=[0])

# df_val = pd.read_csv(r'/content/drive/MyDrive/Dravidian/EACL/malayalam_dev.tsv',names=colnames, delimiter='\t', error_bad_lines=False, header=None,
#                       usecols=['text','label'], na_values=" NaN",skiprows=[0])

# colnames=['index','text','label']
# df_test = pd.read_csv(r'/content/drive/MyDrive/Dravidian/EACL/malayalam_test.tsv',names=colnames, delimiter='\t', error_bad_lines=False, header=None,
#                       usecols=['text','label'], na_values=" NaN",skiprows=[0])

labels = ['Mixed_feelings ','Negative ','Positive ','not-Tamil ','unknown_state ']

for index, line in df.iterrows():
  if line['label'].lower() == labels[0].lower():
        line['label'] = 0
  elif line['label'].lower() == labels[1].lower():
        line['label'] = 1
  elif line['label'].lower() == labels[2].lower():
        line['label'] = 2
  elif line['label'].lower() == labels[3].lower():
        line['label'] = 3
  elif line['label'].lower() == labels[4].lower():
        line['label'] = 4
  i=line[0].split()
  for word in range(len(i)):
      for ch in range(len(i[word])):
          checker=emoji_ch(i[word][ch])
          if(checker is not None):
              i[word]+=checker

      checker=tamilword(i[word])
      if(checker is not None):
          i[word]=checker
      i[word]=preprocess(i[word])
  line[0]=' '.join(i)

for index, line in df_val.iterrows():
  if line['label'].lower() == labels[0].lower():
        line['label'] = 0
  elif line['label'].lower() == labels[1].lower():
        line['label'] = 1
  elif line['label'].lower() == labels[2].lower():
        line['label'] = 2
  elif line['label'].lower() == labels[3].lower():
        line['label'] = 3
  elif line['label'].lower() == labels[4].lower():
        line['label'] = 4
  i=line[0].split()
  for word in range(len(i)):
      for ch in range(len(i[word])):
          checker=emoji_ch(i[word][ch])
          if(checker is not None):
              i[word]+=checker

      checker=tamilword(i[word])
      if(checker is not None):
          i[word]=checker
      i[word]=preprocess(i[word])
  line[0]=' '.join(i)

labels = ['Mixed_feelings','Negative','Positive','not-Tamil','unknown_state']
for index, line in df_test.iterrows():
  if line['label'].lower() == labels[0].lower():
        line['label'] = 0
  elif line['label'].lower() == labels[1].lower():
        line['label'] = 1
  elif line['label'].lower() == labels[2].lower():
        line['label'] = 2
  elif line['label'].lower() == labels[3].lower():
        line['label'] = 3
  elif line['label'].lower() == labels[4].lower():
        line['label'] = 4
  i=line[0].split()
  for word in range(len(i)):
      for ch in range(len(i[word])):
          checker=emoji_ch(i[word][ch])
          if(checker is not None):
              i[word]+=checker
      i[word]=preprocess(i[word])

      checker=tamilword(i[word])
      if(checker is not None):
          i[word]=checker
      i[word]=preprocess(i[word])

  line[0]=' '.join(i)

print(df.head())
print(df_val.head())
print(df_test.head())

x_train = df['text']
y_train = df['label']
x_dev = df_val['text']
y_dev = df_val['label']
x_test = df_test['text']
y_test = df_test['label']

from collections import Counter
unique = Counter()
df['text'].str.lower().str.split().apply(unique.update)
avl=[]
for a in df['text']:
  avl.append(len(a))

import math
cbowsize=100
sgsize=100
totalsize=cbowsize+sgsize
maxlen=math.ceil(sum(avl)/len(avl))
tokmaxwords=len(unique)
batch_size=128

def LabelComments(tweets,label):
    result = []
    prefix = label
    for i, t in zip(tweets.index, tweets):
        result.append(TaggedDocument(t.split(), [prefix + '_%s' % i]))
    return result

trainTotal = x_train
trainTotalAll = LabelComments(trainTotal, 'all')

cores = multiprocessing.cpu_count()
CBOW_Model = Word2Vec(sg=0, size=cbowsize, negative=10, window=15, min_count=2, workers=cores, alpha=0.1, min_alpha=0.001)
CBOW_Model.build_vocab([x.words for x in tqdm(trainTotalAll)])
for epoch in range(10):
    CBOW_Model.train(utils.shuffle([x.words for x in tqdm(trainTotalAll)]), total_examples=len(trainTotalAll), epochs=1)

from gensim.models import FastText
FASTTEXT_Model = FastText([x.words for x in tqdm(trainTotalAll)], size=sgsize, window=15, workers=4,sg=1,negative=10,iter=10)

embeddings_index = {}
for w in CBOW_Model.wv.vocab.keys():
  if(w in FASTTEXT_Model.wv.vocab.keys()):
    embeddings_index[w] = np.append(CBOW_Model.wv[w],FASTTEXT_Model.wv[w])

tokenizer = Tokenizer(num_words=tokmaxwords)
tokenizer.fit_on_texts(x_train)
sequences = tokenizer.texts_to_sequences(x_train)
x_train_sequences = pad_sequences(sequences, maxlen=maxlen)

sequences_val = tokenizer.texts_to_sequences(x_dev)
x_val_sequences= pad_sequences(sequences_val, maxlen=maxlen)

sequences_test = tokenizer.texts_to_sequences(x_test)
x_test_sequences = pad_sequences(sequences_test, maxlen=maxlen)

num_words = tokmaxwords
embedding_matrix = np.zeros((num_words, totalsize))
for word, i in tokenizer.word_index.items():
    if i >= num_words:
        continue
    embedding_vector = embeddings_index.get(word)
    if embedding_vector is not None:
        embedding_matrix[i] = embedding_vector

def LSTM_model(max_sequence_length, max_words_fn, embedding_dim, numberOfClasses):
    embedding_layer = Embedding(max_words_fn,embedding_dim,input_length=max_sequence_length,trainable=False,weights=[embedding_matrix])
    sequence_input = Input(shape=(max_sequence_length,), dtype='float32')
    embedded_sequences = embedding_layer(sequence_input)
    layer1 = LSTM(64, return_sequences=True, dropout = 0.3, recurrent_dropout=0.2)(embedded_sequences)
    layer2 = LSTM(32, dropout = 0.3, recurrent_dropout =0.2)(layer1)
    layer3 = Dense(numberOfClasses)(layer2)
    layer4 = BatchNormalization()(layer3)
    preds = Activation('softmax')(layer4)
    model = Model(sequence_input, preds)
    model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['acc'])
    model.summary()
    return model

max_words = tokmaxwords
maxlen = maxlen
embedding_dims = totalsize
model = LSTM_model(maxlen, max_words, embedding_dims, 5)
num_epochs = 500

y_train2 = np.asarray(y_train).astype('float32').reshape((-1,1))
y_val2 = np.asarray(y_dev).astype('float32').reshape((-1,1))

es_callback = keras.callbacks.EarlyStopping(monitor='val_loss', patience=5)
history = model.fit(x_train_sequences, y_train2, batch_size=batch_size,
                  callbacks=[es_callback], epochs=num_epochs, validation_data=(x_val_sequences, y_val2), shuffle=True,verbose=1)

from keras.utils import np_utils
from sklearn.metrics import classification_report
y_test3 = np_utils.to_categorical(y_test, 5)
predictions = model.predict(x_test_sequences)
prediction = (predictions>0.20)
print(classification_report(y_test3, prediction))


import pygame
import math

class Menu:
    def __init__(self, clint_game):
        self.screen = clint_game.screen
        self.screen_rect = self.screen.get_rect()
        self.screen_width = clint_game.screen_width
        self.screen_height = clint_game.screen_height
        self.score = clint_game.stats.score
        self.clock = pygame.time.Clock()

        self.color = (227, 209, 34)
        self.text_color = (0, 0, 0)
        self.font = pygame.font.Font("fonts/8BitOperatorPlus8-Bold.ttf", 48)
        self.title_font = pygame.font.Font("fonts/deadsaloon.ttf", 84)

        self.rect = pygame.Rect(0, 0, self.screen_width, self.screen_height)
        self.rect.center = self.screen_rect.center

        self.rect_go = pygame.Surface(
            (int(self.screen_width) * 8 / 10, int(self.screen_height) * 8 / 10)
        )
        self.rect_go.set_alpha(128)

        # Blood

        self.blood_original_image = pygame.image.load("images/others/blood/blood.png")
        self.blood_image = pygame.transform.scale(
            self.blood_original_image, (100, 100)
        ).convert_alpha()
        self.blood_image.set_colorkey((0, 0, 0))

        self.blood_rect = self.blood_image.get_rect()
        self.blood_rect.top = self.screen_rect.top
        self.blood_rect.left = self.screen_rect.left + 200

        self.drop_1_image = pygame.image.load("images/others/blood/drop_1.png")
        self.drop_1_image = pygame.transform.scale(
            self.drop_1_image, (100, 100)
        ).convert_alpha()

        self.drop_1_rect = self.drop_1_image.get_rect()
        self.drop_1_rect.top = self.screen_rect.top
        self.drop_1_rect.left = self.screen_rect.left + 200

        self.drop_2_image = pygame.image.load("images/others/blood/drop_2.png")
        self.drop_2_image = pygame.transform.scale(
            self.drop_2_image, (100, 100)
        ).convert_alpha()

        self.drop_2_rect = self.drop_2_image.get_rect()
        self.drop_2_rect.top = self.screen_rect.top
        self.drop_2_rect.left = self.screen_rect.left + 200

        self.drop_3_image = pygame.image.load("images/others/blood/drop_3.png")
        self.drop_3_image = pygame.transform.scale(
            self.drop_3_image, (100, 100)
        ).convert_alpha()

        self.drop_3_rect = self.drop_3_image.get_rect()
        self.drop_3_rect.top = self.screen_rect.top
        self.drop_3_rect.left = self.screen_rect.left + 200

        # Andrew

        self.andrew_walk_1 = pygame.image.load("images/others/andrew/andrew_walk_1.png")
        self.andrew_walk_1 = pygame.transform.scale(
            self.andrew_walk_1, (130, 90)
        ).convert_alpha()

        self.andrew_walk_2 = pygame.image.load("images/others/andrew/andrew_walk_2.png")
        self.andrew_walk_2 = pygame.transform.scale(
            self.andrew_walk_2, (130, 90)
        ).convert_alpha()

        self.andrew_walk = [self.andrew_walk_1, self.andrew_walk_2]
        self.andrew_index = 1
        self.andrew_image = self.andrew_walk[int(self.andrew_index)]

        self.andrew_rect = self.andrew_walk_1.get_rect()
        self.andrew_rect.centerx = self.screen_rect.centerx + 150
        self.andrew_rect.centery = self.rect.centery - 200

    def prep_message(self, msg, y):
        self.msg_image = self.font.render(msg, True, self.text_color)
        self.msg_image_rect = self.msg_image.get_rect()
        self.msg_image_rect.right = self.screen_rect.right * 5 / 6
        self.msg_image_rect.centery = self.rect.centery + y
        self.screen.blit(self.msg_image, self.msg_image_rect)

    def prep_go_message(self, msg, y):
        self.msg_image = self.font.render(msg, True, self.text_color).convert_alpha()
        self.msg_image_rect = self.msg_image.get_rect()
        self.msg_image_rect.centerx = self.rect.centerx
        self.msg_image_rect.centery = self.rect.centery + y
        self.screen.blit(self.msg_image, self.msg_image_rect)

    def prep_title_message(self, msg, y):
        self.msg_image = self.title_font.render(msg, True, self.text_color)
        self.msg_image_rect = self.msg_image.get_rect()
        self.msg_image_rect.centerx = self.screen_rect.centerx + 150
        self.msg_image_rect.centery = self.rect.centery + y
        self.screen.blit(self.msg_image, self.msg_image_rect)

    def display_menu(self):
        self.menu_start_time = pygame.time.get_ticks()
        self.screen.fill(self.color, self.rect)
        self.prep_message("Start", 100)
        self.prep_message("Options", 150)
        self.prep_message("Highscores", 200)
        self.prep_message("Legend", 250)
        self.prep_message("Exit", 300)
        self.prep_title_message("Clint Adventures", -300)
        self.prep_title_message("The mystery of King Scorpio", -100)
        self.screen.blit(self.andrew_image, self.andrew_rect)
        self.screen.blit(self.blood_image, self.blood_rect)

    def display_game_over(self, score):
        self.rect_go.fill((255, 0, 0, 128))
        self.rect_go.set_alpha(128)
        self.screen.blit(
            self.rect_go,
            (self.screen_rect.right * 1 / 10, self.screen_rect.bottom * 1 / 10),
        )
        self.prep_go_message("Game over", -100)
        self.prep_go_message(f"you've scored  {score} points", -50)
        self.prep_go_message("press 's' to start again", 100)
        self.prep_go_message("press 'm' to go to menu", 150)

    def drop_1_animation(self):
        self.drop_1_height = self.drop_1_image.get_height()
        self.drop_1_image = pygame.transform.scale(
            self.drop_1_image, (100, self.drop_1_height + 1)
        ).convert_alpha()
        self.screen.blit(self.drop_1_image, self.drop_1_rect)

    def drop_2_animation(self):
        self.drop_2_height = self.drop_2_image.get_height()
        self.drop_2_image = pygame.transform.scale(
            self.drop_2_image, (100, self.drop_2_height + 3)
        ).convert_alpha()
        self.screen.blit(self.drop_2_image, self.drop_2_rect)

    def drop_3_animation(self):
        self.drop_3_height = self.drop_3_image.get_height()
        self.drop_3_image = pygame.transform.scale(
            self.drop_3_image, (100, self.drop_3_height + 1)
        ).convert_alpha()
        self.screen.blit(self.drop_3_image, self.drop_3_rect)

    def andrew_animation(self):
        self.andrew_rect.x += 5

        if self.andrew_index > 2:
            self.andrew_index = 0

        self.andrew_image = self.andrew_walk[int(self.andrew_index)]

        self.andrew_index += 0.2


from ._common_config import *

FILE_PATH = Path(__file__)
PARENT_PATH = FILE_PATH.parent.parent

def get_driver(
    name='Chrome',
    page_load_strategy='normal',
    use_manager=True,
    executable_path=None,
    headless=False,
    ip=None
):
    assert name in ['Chrome', 'Edge']

    options = (edge_options(), chrome_options())[name == 'Chrome']
    driver_cls = (webdriver.Edge, webdriver.Chrome)[name == 'Chrome']
    service_cls = (EdgeService, ChromeService)[name == 'Chrome']
    manager_cls = (EdgeChromiumDriverManager(), ChromeDriverManager())[name == 'Chrome']

    options.page_load_strategy = page_load_strategy
    if headless and name == 'Chrome':
        options.add_argument("--headless=new")
        options.add_argument("disable-gpu")
    elif headless and name == 'Edge':
        options.use_chromium = True
        options.add_argument("--headless=new")
        options.add_argument("disable-gpu")

    if ip is not None and isinstance(ip, str):
        options.add_argument("--proxy-server=http://"+ip)

    if use_manager:
        try:
            service = service_cls(manager_cls.install())
            driver = driver_cls(service=service, options=options)
        except:
            use_manager = False

    if not use_manager:
        path = (Path.joinpath(PARENT_PATH, 'msedgedriver'), Path.joinpath(PARENT_PATH, 'chromedriver'))[name == 'Chrome']
            # 如果指定可执行文件路径，就覆盖path变量
        if executable_path is not None:
            path = executable_path

        service = service_cls(executable_path=path)
        driver = driver_cls(service=service, options=options)

    return driver

def wait_for_show_up(
        driver, by_method=By.XPATH, page_path=None,
        duration=3, send_keys=None, click=False, sleep=0.5,
        roll_to_show=False, index=0
):
    """等待元素出现并点击或填充"""

    wait = WebDriverWait(driver, duration)
    elements = None

    if not roll_to_show:
        try:
            elements = wait.until(EC.presence_of_all_elements_located((by_method, page_path)))
        except:
            elements = None
    else:
        try:
            # 定位元素
            elements = driver.find_elements(by_method, page_path)
        except:
            # 判断元素是否存在
            if elements is None:
                # 元素不存在，向下滚动直到找到元素
                tik = time.time()
                tok = time.time()
                while True:
                    try:
                        elements = wait.until(EC.presence_of_all_elements_located((by_method, page_path)))
                        break
                    except Exception:
                        # 创建ActionChains对象
                        actions = webdriver.ActionChains(driver)

                        actions.key_down(Keys.PAGE_DOWN).key_up(Keys.PAGE_DOWN).perform()

                    finally:
                        tok = time.time()

                    if (tok - tik) > duration * 100:
                        break

    if elements is None or len(elements) == 0:
        if index == 'all':
            return [None]
        else:
            return None

    if index == 'all':
        return elements
    else:
        if click:
            elements[index].click()

        if send_keys:
            elements[index].send_keys(send_keys)

        time.sleep(sleep)
        return elements[index]

def move2center_screen(driver):
    """移动鼠标到页面中间"""
    import pyautogui

    # 获取页面的高度和窗口的高度
    page_height = driver.execute_script("return document.body.scrollHeight")

    # 计算鼠标应该移动到的垂直位置
    middle_point = -page_height // 2

    # 将鼠标移动到页面的中间位置
    driver.execute_script(f"window.scrollTo(0, {middle_point});")

    # 将鼠标移动到页面的中间位置，有随机偏移量，以确保不整齐排列
    pyautogui.moveTo((pyautogui.size()[0] // 2), middle_point)

    return pyautogui.position()

def scroll_screen(driver, click_offsets):
    """从屏幕中间开始滚动屏幕"""

    move2center_screen(driver)

    # 模拟鼠标滚动到目标坐标
    pyautogui.scroll(click_offsets)
    pyautogui.sleep(1)

    return pyautogui.position()

def move_element(driver, selector, click_offsets=10):
    """移动元素"""
    # 定位元素
    wait = WebDriverWait(driver, 10)
    current_element = wait.until(EC.presence_of_element_located((By.XPATH, selector)))
    cex = current_element.location.get('x')
    cey = current_element.location.get('y')
    middle_x, middle_y = scroll_screen(driver, click_offsets)

    x_offset = abs(abs(cex) - abs(middle_x))
    y_offset = abs(abs(cey) - abs(middle_y))
    # 4. 拖动元素到目标位置
    actions = webdriver.ActionChains(driver)
    actions.drag_and_drop_by_offset(current_element, x_offset, y_offset).perform()

    time.sleep(1)

    return pyautogui.position()

def lxml_parser(html):
    """获取DOM对象"""
    return etree.HTML(html)

def get_elements(dom, xpath):
    """获取元素"""
    return dom.xpath(xpath)


from fastapi import APIRouter, Depends, status, HTTPException
from api.utils import raiseUpdate404
from api import models, schemas, oauth2
from sqlalchemy.orm import Session
from api.database import get_db
from typing import List

router = APIRouter(prefix='/api/updates', tags=['UPDATES'])

@router.get('/', response_model=List[schemas.UpdateOutput])
def get_updates(db: Session = Depends(get_db)):
    updates = db.query(models.Update).all()
    return (updates)

@router.get('/{id}', response_model=schemas.UpdateOutput)
def get_update(id, db: Session = Depends(get_db)):
    update = db.query(models.Update).filter(models.Update.id == id).first()
    if update is None:
        raiseUpdate404(id)
    return (update)

@router.delete('/{id}', status_code=status.HTTP_204_NO_CONTENT)
def delete_update(id: int, db: Session = Depends(get_db), current_user: int = Depends(oauth2.get_current_user)):
    update_query = db.query(models.Update).filter(models.Update.id == id)
    update = update_query.first()
    if not update:
        raiseUpdate404(id)
    update_query.delete()
    db.commit()

@router.put('/{id}', response_model=schemas.UpdateOutput)
def update_update(data: schemas.UpdateBase, id: int, db: Session = Depends(get_db), current_user: int = Depends(oauth2.get_current_user)):
    update_query = db.query(models.Update).filter(models.Update.id == id)
    update = update_query.first()
    if not update:
        raiseUpdate404(id)
    update_query.update(data.model_dump())
    db.commit()
    return (update_query.first())


import json
import rich
from rich.console import Console
import pathlib
from rich.table import Table

console = Console()

def langs():
    # get the path of the json file
    my_path = pathlib.Path(__file__).parent.resolve() / "assets"
    lang_path = str(my_path) + "\\languages.json"

    # create a table
    table = Table(title="Languages Supported")

    table.add_column("Language Name", justify="right", style="cyan", no_wrap=True)
    table.add_column("Code", style="bold green", justify="middle")

    # read the json file
    with open(lang_path, 'r') as json_file:
            json_load = json.load(json_file)

    data = json_load['supported_languages']

    # add the data to the table
    for key, value in data.items():
        table.add_row(key, value)

    console.print(table)


# -*- coding: utf-8 -*-
from pymongo import MongoClient
import sys
import keys

def connect_to_db(EMOTION):
    connect = MongoClient(keys.MongoIP, 27017)
    db = connect.research
    collection = db["original_" + EMOTION]
    return collection

def extract_texts(docs):
    ret = []
    text_and_id = []
    for doc in docs:
        text = " ".join(doc['text'].strip().split()).replace("＃", "#")
        id = doc['id_str'].strip()
        ret.append([text, id])
    return ret

# ATTENTION: Pass one emotion as a command line argument
# 'joy', 'trust', 'fear', 'surprise', 'sadness', 'disgust', 'anger', 'anticipation', 'news', 'opinionated', 'testing_news'
if __name__ == '__main__':
    EMOTION = sys.argv[1]
    collection = connect_to_db(EMOTION)
    docs = collection.find()
    texts_and_ids = extract_texts(docs)

    out_file = "/home/sadayuki/Dropbox/Data-Mining-Research/data_original/original_tweets/original_" + EMOTION

    with open(out_file, mode="w+") as out_file:
        for text_and_id in texts_and_ids:
            out_file.write(text_and_id[0] + "\t" + text_and_id[1] + "\n")


import shutil
import os
import edit_distance
import remove_case
import line_break
import removeComments

def getFileInArray(filename):
  infile = open(filename, "r")
  array = []
  for line in infile:
    line = line.replace("\n","")
    line = line.replace(" ","")
    array.append(line)
    if "" in array:
      array.remove("")
  return array

def getSimilarIndex(check,inp):
  dist = 0
  for i in check:
    min = len(i)
    for j in inp:
      editdistance = edit_distance.computeDistance(i,j)
      if(editdistance < min):
        min = editdistance
    dist = dist + min
  return dist

def removeCases(checkFile,dirName):
  remove_case.fun(checkFile)
  for inpfile in os.listdir (dirName):
    remove_case.fun(dirName+'/'+inpfile)

def applyLineBreak(checkFile,dirName,breaker):
  line_break.fun(checkFile,breaker)
  for inpfile in os.listdir (dirName):
    line_break.fun(dirName+'/'+inpfile,breaker)

def removeSingleComments(checkFile,dirName,marker):
  removeComments.singleComment(checkFile,marker)
  for inpfile in os.listdir (dirName):
    removeComments.singleComment(dirName+'/'+inpfile,marker)

def removeBlogComments(checkFile,dirName,startMarker,endMarker):
  removeComments.blogComment(checkFile,startMarker,endMarker)
  for inpfile in os.listdir (dirName):
    removeComments.blogComment(dirName+'/'+inpfile,startMarker,endMarker)

def writeResultIntoFile(result,outputfile):
  out = open(outputfile, "w")
  out.write("FileName  PlagiarismIndex\n")
  for entry in result:
    out.write(entry[0] + "           " + str(entry[1]) + "\n")


from django.test import TestCase
from books.templatetags.book_tags import review_stars

class TestGetReviewStars(TestCase):

    def test_review_stars(self):
        star = "<i class='fa fa-star text-warning' aria-hidden='true'></i>"
        expected = star * 2
        # Ensure the template tag results the same resutl as expected
        self.assertEqual(review_stars(2.4), expected)


n=int(input())
b=[120,30,220,50,320,90]
while n>0:

    if n>=50:
        d=int(input())
        n=n-b[d-1]
        if(n>0):
            print(n)
        else:
            print("insufficient bal")
            n=n+b[d-1]
    else:
        print("your shopping is over")
        break


from rest_framework import viewsets, mixins, status
from educategories.models import EduCategory
from components.models import Component
from tests.models import Test
from components.serializers import ComponentSerializer
from educategories.serializers import EduCategorySerializer
from rest_framework.response import Response
from rest_framework.decorators import action
from components.feeds import ComponentRepository
from tests.serializers import TestSerializer

class CategoryViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin,
                      mixins.CreateModelMixin, viewsets.GenericViewSet):

    queryset = EduCategory.objects.all()
    serializer_class = EduCategorySerializer

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()

        if instance.depth == 0:
            EduCategory.objects.filter(lesson_id=instance.id).delete()
        elif instance.depth == 1:
            EduCategory.objects.filter(unit_id=instance.id).delete()
        elif instance.depth == 2:
            EduCategory.objects.filter(subject_id=instance.id).delete()

        instance.delete()

        return Response(status=status.HTTP_204_NO_CONTENT)

    @action(methods=['GET'], detail=False)
    def lessons(self, request):
        queryset = EduCategory.objects.filter(depth=0).all()

        serializer = EduCategorySerializer(queryset, many=True)
        return Response(serializer.data)

    @action(methods=['GET'], detail=True)
    def subs(self, request, pk=None):
        queryset = EduCategory.objects.filter(parent_id=pk).all()

        serializer = EduCategorySerializer(queryset, many=True)
        return Response(serializer.data)

    @action(methods=['GET'], detail=True)
    def components(self, request, pk=None):
        response = []

        queryset = Component.objects.prefetch_related('to_component','source_component').filter(edu_category_id=pk).all()

        for query in queryset:
            serialized_question = ComponentSerializer(query)
            item = serialized_question.data

            cr = ComponentRepository(component=query)
            cr.request = request

            cr.sub_components()
            cr.all_sub_components()
            cr.parent_components()

            all_components = cr.component_formats(
                sub_components='list',
                all_sub_components='list',
                parent_components='list',
                all_components='list',
                data_components='dict'
            )

            item.update(all_components)

            response.append(item)

        return Response(response)

    @action(methods=['GET'], detail=True)
    def tests(self, request, pk=None):
        queryset = Test.objects.filter(categories__id=pk).all()

        serializer = TestSerializer(queryset, many=True, context={'simple': True})
        return Response(serializer.data)


import numpy as np
import cv2

classes = ["aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train","tvmonitor"]
class_colors = [(255,102,102),
                (255,178,102),
                (255,255,102),
                (178,255,102),
                (102,255,102),
                (102,255,178),
                (102,255,255),
                (102,178,255),
                (102,102,255),
                (178,102,255),
                (255,102,255),
                (255,102,178),
                (192,192,192),
                (96,96,96   ),
                (204,0,0    ),
                (204,102,0  ),
                (153,153,0  ),
                (76,153,0   ),
                (0,153,153  ),
                (255,255,204)]

def interpret_output(output, img_width, img_height):
    w_img = img_width
    h_img = img_height
    #print ((w_img, h_img))
    threshold = 0.2
    iou_threshold = 0.5
    num_class = 20
    num_box = 2
    grid_size = 7
    probs = np.zeros((7,7,2,20))
    class_probs = (np.reshape(output[0:980],(7,7,20)))#.copy()
    #print(class_probs)
    scales = (np.reshape(output[980:1078],(7,7,2)))#.copy()
    #print(scales)
    boxes = (np.reshape(output[1078:],(7,7,2,4)))#.copy()
    offset = np.transpose(np.reshape(np.array([np.arange(7)]*14),(2,7,7)),(1,2,0))
    #boxes.setflags(write=1)
    boxes[:,:,:,0] += offset
    boxes[:,:,:,1] += np.transpose(offset,(1,0,2))
    boxes[:,:,:,0:2] = boxes[:,:,:,0:2] / 7.0
    boxes[:,:,:,2] = np.multiply(boxes[:,:,:,2],boxes[:,:,:,2])
    boxes[:,:,:,3] = np.multiply(boxes[:,:,:,3],boxes[:,:,:,3])

    boxes[:,:,:,0] *= w_img
    boxes[:,:,:,1] *= h_img
    boxes[:,:,:,2] *= w_img
    boxes[:,:,:,3] *= h_img

    for i in range(2):
        for j in range(20):
            probs[:,:,i,j] = np.multiply(class_probs[:,:,j],scales[:,:,i])
    #print (probs)
    filter_mat_probs = np.array(probs>=threshold,dtype='bool')
    filter_mat_boxes = np.nonzero(filter_mat_probs)
    boxes_filtered = boxes[filter_mat_boxes[0],filter_mat_boxes[1],filter_mat_boxes[2]]
    probs_filtered = probs[filter_mat_probs]
    classes_num_filtered = np.argmax(probs,axis=3)[filter_mat_boxes[0],filter_mat_boxes[1],filter_mat_boxes[2]]

    argsort = np.array(np.argsort(probs_filtered))[::-1]
    boxes_filtered = boxes_filtered[argsort]
    probs_filtered = probs_filtered[argsort]
    classes_num_filtered = classes_num_filtered[argsort]

    for i in range(len(boxes_filtered)):
        if probs_filtered[i] == 0 : continue
        for j in range(i+1,len(boxes_filtered)):
            if iou(boxes_filtered[i],boxes_filtered[j]) > iou_threshold :
                probs_filtered[j] = 0.0

    filter_iou = np.array(probs_filtered>0.0,dtype='bool')
    boxes_filtered = boxes_filtered[filter_iou]
    probs_filtered = probs_filtered[filter_iou]
    classes_num_filtered = classes_num_filtered[filter_iou]

    result = []
    for i in range(len(boxes_filtered)):
        result.append([classes_num_filtered[i],boxes_filtered[i][0],boxes_filtered[i][1],boxes_filtered[i][2],boxes_filtered[i][3],probs_filtered[i]])

    return result

def iou(box1,box2):
    tb = min(box1[0]+0.5*box1[2],box2[0]+0.5*box2[2])-max(box1[0]-0.5*box1[2],box2[0]-0.5*box2[2])
    lr = min(box1[1]+0.5*box1[3],box2[1]+0.5*box2[3])-max(box1[1]-0.5*box1[3],box2[1]-0.5*box2[3])
    if tb < 0 or lr < 0 : intersection = 0
    else : intersection =  tb*lr
    return intersection / (box1[2]*box1[3] + box2[2]*box2[3] - intersection)

def draw_boxes(img, results, img_width, img_height):
    img_cp = img.copy()
    # For each of the objects
    for i in range(len(results)):
        x = int(results[i][1])
        y = int(results[i][2])
        w = int(results[i][3])//2
        h = int(results[i][4])//2
        xmin = x-w
        xmax = x+w
        ymin = y-h
        ymax = y+h
        if xmin<0:
            xmin = 0
        if ymin<0:
            ymin = 0
        if xmax>img_width:
            xmax = img_width
        if ymax>img_height:
            ymax = img_height
        # Add boxes to the image
        color = class_colors[results[i][0]]
        cv2.rectangle(img_cp,(xmin,ymin),(xmax,ymax),color,2)
        cv2.rectangle(img_cp,(xmin,ymin-20),(xmax,ymin),color,-1)
        cv2.putText(img_cp,classes[results[i][0]] + ' : %.2f' % results[i][5],(xmin+5,ymin-7),cv2.FONT_HERSHEY_DUPLEX,0.5,(0,0,0),1)

    return(img_cp)


# coding=utf-8

from com.req import request
from com.sql.product import product

def get_cart(headers):
	url = '/cart/list'
	return request(method='get', url=url, headers=headers)

def update_cart(headers, goods_id, project_code=44030052, num=1, is_add=1):
	url = '/cart/update'
	product_info = product(goods_id)
	product_id = product_info['id']
	price = int(product_info['price'])
	data = {
		"project_code": project_code,
		"goods_id": goods_id,
		"product_id": product_id,
		"num": num,
		"price": price,
		"is_add": is_add
	}
	return request(method='post', url=url, headers=headers, json=data)


def solution(s):
    s = list(map(str, s[1:-1].split('},{')))

    for i in range(len(s)):
        if s[i].find('{') >= 0:
            s[i] = s[i].replace('{', '')
        if s[i].find('}') >= 0:
            s[i] = s[i].replace('}', '')

        s[i] = list(map(int, s[i].split(',')))

    s.sort(key=len)

    answer = s.pop(0)

    for set in s:
        answer += [el for el in set if el not in answer]

    return answer

if __name__ == '__main__':
    s = "{{4,2,3},{3},{2,3,4,1},{2,3}}"

    print(solution(s))