# The animation_class.py file houses the code for the actual animation:
# Button classes and subclasses, and ModalApp architecture
# Run this file as main to run actual experience.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
from matplotlib.image import imread
from scipy.spatial import Delaunay
from tkinter import *
from cmu_112_graphics import *
from triangle_image_class import *
from triangulator_class import *
from PIL import Image, ImageChops
import cv2, random, time, io

#Base Button Class
class Button():
    def __init__(self, x, y, width, height, color, text):
        self.x, self.y = x, y
        self.width, self.height = width, height
        self.color = color
        self.text = text

    def draw(self, canvas):
        canvas.create_rectangle(self.x - self.width//2, self.y - self.height//2,
        self.x + self.width//2, self.y + self.height//2, fill=self.color)
        canvas.create_text(self.x, self.y, text=self.text,
        fill=LowPolyGenerator.rgbString(180,180,180), font="Arial 12")

    def buttonFunction(self, mode):
        pass
# Skews of buttons with spcific methods (change parameters, go to Help screen)
class ParametersButton(Button):
    def buttonFunction(self, mode):
        mode.changeParameters()

class HelpButton(Button):
    def buttonFunction(self, mode):
        mode.selected = (-1,-1)
        mode.app.setActiveMode(mode.app.helpMode)

class ReturnButton(Button):
    def buttonFunction(self, mode):
        mode.app.setActiveMode(mode.app.bridgeMode)

class PathButton(Button):
    def __init__(self, x, y, width, height, color, text, path):
        super().__init__(x, y, width, height, color, text)
        self.path = path
    def buttonFunction(self, mode):
        mode.directory = self.path + "/" + self.text

class SplashButton(Button):
    def buttonFunction(self, app):
        # file dialog from https://stackoverflow.com/questions/11295917/how-to-select-a-directory-and-store-the-location-using-tkinter-in-python
        app.startPath = filedialog.askdirectory()

    def draw(self, canvas):
        canvas.create_rectangle(self.x - self.width//2, self.y - self.height//2,
        self.x + self.width//2, self.y + self.height//2, fill=self.color)
        canvas.create_text(self.x, self.y, text=self.text,
        fill=LowPolyGenerator.rgbString(180,180,180), font="Arial 30")

# CMU graphics package from http://www.cs.cmu.edu/~112/notes/notes-animations-part2.html
# Modified to allow for a crucial MVC violation
class PolyBridge(ModalApp):
    def appStarted(self):
        self.timerDelay = 100
        self.toRender = (None, None)
        self.rendered = None
        self.blurSize = 3
        self.sharpen = True
        self.cannyLow = 100
        self.cannyHigh = 500
        self.randomNoiseRate = 500
        self.nodeSampleDistanceThreshold = 20
        self.nodeSampleRate = 0.1
        self.nodeThresholdRate = 0.2
        self.bridgeMode = BridgeMode()
        self.renderMode = RenderMode()
        self.splashScreenMode = SplashScreenMode()
        self.helpMode = HelpMode()
        self.setActiveMode(self.splashScreenMode)

class SplashScreenMode(Mode):
    def appStarted(self):
        self.button = SplashButton(self.width//2, 3*self.height//4, 360, 100, LowPolyGenerator.rgbString(78,78,78), "Pick a starting directory")
        self.startPath = ""
    # Checks if buttons are pressed
    def mousePressed(self, event):
        mx, my = event.x, event.y
        button = self.button
        if mx > button.x - button.width//2 and \
        mx < button.x + button.width//2 and \
        my > button.y - button.height//2 and \
        my < button.y + button.height//2:
            button.buttonFunction(self)
        if self.startPath != "":
            self.app.setActiveMode(self.app.bridgeMode)

    def drawBridgeLogo(self, canvas):
        brown = LowPolyGenerator.rgbString(38,28,4)
        orange = LowPolyGenerator.rgbString(242,183,63)
        canvas.create_rectangle(100,100,self.width - 100, self.height//2 - 100, fill=orange, width=0)
        canvas.create_rectangle(110,110,self.width - 110, self.height//2 - 110, fill=brown, width=0)
        canvas.create_text(self.width//2, self.height//4, text="LowPolyGen", font="Arial 120", fill=orange)

    def redrawAll(self, canvas):
        canvas.create_rectangle(0, 0, self.width, self.height, fill=LowPolyGenerator.rgbString(50,50,50), width=0)
        self.drawBridgeLogo(canvas)
        self.button.draw(canvas)

# Help screen mode that demonstrates steps of rendering and the effects of
# each parameter on the image's render
class HelpMode(Mode):
    def appStarted(self):
        self.tipIndex = 0
        self.blurImage = Image.open(os.getcwd() + "/assets/cmuBS.jpg")
        self.cannyImage = Image.open(os.getcwd() + "/assets/cmuCanny.jpg")
        self.polyImage = Image.open(os.getcwd() + "/assets/cmuPoly.jpg")
        self.blurImage.thumbnail((self.width*0.3, self.width*0.3), Image.ANTIALIAS)
        self.cannyImage.thumbnail((self.width*0.3, self.width*0.3), Image.ANTIALIAS)
        self.polyImage.thumbnail((self.width*0.3, self.width*0.3), Image.ANTIALIAS)
        self.returnButton = ReturnButton(self.width//2, 9*self.height//10, 100, 30, LowPolyGenerator.rgbString(78,78,78), "Return")

        self.tips = ["Use the arrow keys to scroll and resize the file system.","Blur determines the size of blur filter applied to the image. \n Sharpen decides whether to then run a sharpen kernel that \n increases the number of edges detected.", "Edge detection bounds determine the lower and upper bounds of edges. \n Generally, higher and closer together is more selective, \n resulting in less nodes (white dots) detected.", "Random sample points and node sample rate \n determine how many pixel \"edges\" as well as random points \n are input into the algorithm.", "Node threshold distance is the minimum side length of the generated triangles. \n Threshold check rate determines how likely triangle sides are to be \n ensured to be the minimum length. 100% will yield all sides with that minimum.", "Note that increasing the number of nodes through node or \n random sample rate increases can have an adverse effect on render times."]

    # checks if buttons are pressed
    def mousePressed(self, event):
        mx, my = event.x, event.y
        button = self.returnButton
        if mx > button.x - button.width//2 and \
        mx < button.x + button.width//2 and \
        my > button.y - button.height//2 and \
        my < button.y + button.height//2:
            button.buttonFunction(self)

    def keyPressed(self, event):
        if event.key == "Right":
            self.tipIndex += 1
            self.tipIndex %= len(self.tips)
        elif event.key == "Left":
            self.tipIndex -= 1
            self.tipIndex %= len(self.tips)
        elif event.key == "h":
            self.app.setActiveMode(self.app.bridgeMode)

    def drawImages(self, canvas):
        canvas.create_image(self.width//6, self.height//3, image=ImageTk.PhotoImage(self.blurImage))
        canvas.create_image(self.width//2, self.height//3, image=ImageTk.PhotoImage(self.cannyImage))
        canvas.create_image(5*self.width//6, self.height//3, image=ImageTk.PhotoImage(self.polyImage))

    def drawTip(self, canvas):
        canvas.create_text(self.width//2, 2*self.height//3, text=self.tips[self.tipIndex], font="Arial 40", justify="center", fill=LowPolyGenerator.rgbString(180,180,180))
        canvas.create_text(self.width//2, self.height//16, text=f"Tip #{self.tipIndex + 1}", font="Arial 40", justify="center", fill=LowPolyGenerator.rgbString(180,180,180))

    def redrawAll(self, canvas):
        canvas.create_rectangle(0, 0, self.width, self.height, fill=LowPolyGenerator.rgbString(50,50,50), width=0)
        self.drawImages(canvas)
        self.drawTip(canvas)
        self.returnButton.draw(canvas)

# This is the ModalApp Mode that draws all of the triangles in a split second
# then immediately exits back to the bridge mode
class RenderMode(Mode):
    def appStarted(self):
        self.lowPolyImage, self.renderSize = self.app.toRender
        self.tempW, self.tempH = self.app.width, self.app.height
        self.app.height, self.app.width = self.lowPolyImage.imageSize
        self.height, self.width = self.lowPolyImage.imageSize
        self.timerDelay = 0.1
    def redrawAll(self, canvas):
        if self.app.toRender != (None, None):
            self.lowPolyImage.drawImage(canvas, self.width, self.height)
            # poly image canvas saving from https://stackoverflow.com/questions/34777676/
            # how-to-convert-a-python-tkinter-canvas-postscript-file-to-an-image-file-readable
            ps = canvas.postscript(colormode='color')
            image = Image.open(io.BytesIO(ps.encode('utf-8')))
            self.app.rendered = image
            self.app.width, self.app.height = self.tempW, self.tempH
        self.app.setActiveMode(self.app.bridgeMode)
    def keyPressed(self, event):
        if event.key == "s":
            self.app.saveSnapshot()
        else:
            self.app.setActiveMode(self.app.bridgeMode)

# This is the mode where most of the UX is done. This is meant to mimic the
# Adobe Bridge aesthetic
class BridgeMode(Mode):
    def appStarted(self):
        self.width, self.height = self.app.width, self.app.height
        self.scroll = -40
        self.margin = 20
        self.selected = (-1,-1)
        self.selectedFile = ""
        self.previewSize = self.width//2
        self.previewImage = None
        self.showHidden = False
        self.mousePosition = (None, None)
        self.thumbnailSize = (self.width - self.previewSize - 4*self.margin)//3
        self.directory = self.app.splashScreenMode.startPath
        self.directoryList = self.generateFileGrid()
        self.parametersButton = ParametersButton(self.width - self.previewSize//2, self.height - 200, 200, 60, LowPolyGenerator.rgbString(78,78,78), "Change Parameters")
        self.helpButton = HelpButton(self.width - self.previewSize//2, self.height - 140, 100, 30, LowPolyGenerator.rgbString(78,78,78), "Help")
        self.pathButtons = []
        self.generateDirectoryButtons()
        self.folderIcon = Image.open(os.getcwd() + "/assets/folderIcon.jpg")
        self.fileIcon = Image.open(os.getcwd() + "/assets/fileIcon.jpg")

    # Generates the string of buttons at the top according to the current path
    # clicking on them is meant to bring
    def generateDirectoryButtons(self):
        self.pathButtons = []
        split = self.directory.split("/")
        for i in range(len(split)):
            name = split[i]
            if name != "":
                self.pathButtons.append(PathButton(60 + (100 + 5)*len(self.pathButtons), 30, 100, 30, LowPolyGenerator.rgbString(78,78,78), name, "/".join(split[:i])))
        while 105*len(self.pathButtons) > self.width - self.previewSize:
            self.pathButtons.pop(0)
            for button in self.pathButtons:
                button.x -= 105
        try:
            self.generateFileGrid()
        except:
            pass

    # generates a 2D list of thumbnails and paths to be displayed
    def generateFileGrid(self):
        thumbnailSize = self.thumbnailSize
        files, directories = [],[]
        path = self.directory
        for file in os.listdir(path):
            if file.endswith(".jpg") or \
            file.endswith(".JPG") or \
            file.endswith(".jpeg") or \
            file.endswith(".JPEG"):
                files.append(path + "/" + file)
            elif self.showHidden or not file.startswith("."):
                directories.append(file)
        directoryThumbnails = [("directory", path + "/" + dir) for dir in directories]
        backDirectory = "/".join(path.split("/")[:-1])
        directoryThumbnails.insert(0, ("directory", backDirectory))
        thumbnails = []
        for file in files:
            thumbnail = Image.open(file)
            thumbnail.thumbnail((self.thumbnailSize*0.8, self.thumbnailSize*0.8), Image.ANTIALIAS)
            thumbnails.append((thumbnail,file))
        self.thumbnails = directoryThumbnails + thumbnails
        maxC = (self.width - self.previewSize - 4*self.margin)//self.thumbnailSize
        self.thumbnailArray = [[None]*maxC for _ in range(len(self.thumbnails)//maxC + 1)]
        r,c = 0,0
        for i in range(len(self.thumbnails)):
            self.thumbnailArray[r][c] = self.thumbnails[i]
            c += 1
            if c > maxC - 1:
                r += 1
                c = 0
    # checks for button clicks on mouse pressed event
    def checkButtonClicks(self, mx, my):
        for button in self.pathButtons + [self.parametersButton, self.helpButton]:
            if mx > button.x - button.width//2 and \
            mx < button.x + button.width//2 and \
            my > button.y - button.height//2 and \
            my < button.y + button.height//2:
                button.buttonFunction(self)
                return True
        return False

    # Returns the selected file in grid of click
    def getRowCol(self, mx, my):
        for r in range(len(self.thumbnailArray)):
            for c in range(len(self.thumbnailArray[0])):
                if my > r*self.thumbnailSize + (r+1)*self.margin - self.scroll and \
                my < (r+1)*self.thumbnailSize + (r+2)*self.margin - self.scroll and \
                mx > c*self.thumbnailSize + (c+1)*self.margin and \
                mx < (c+1)*self.thumbnailSize + (c+2)*self.margin and \
                self.thumbnailArray[r][c] != None:
                    return (r,c)
        return (-1,-1)

    # whitespace cropping from from https://stackoverflow.com/questions/10615901/trim-whitespace-using-pil
    # trims whitespace from image capture
    def trim(self, im):
        bg = Image.new(im.mode, im.size, im.getpixel((im.size[0]-1,im.size[1]-1)))
        diff = ImageChops.difference(im, bg)
        diff = ImageChops.add(diff, diff, 2.0, -100)
        bbox = diff.getbbox()
        if bbox:
            return im.crop(bbox)

    def mousePressed(self, event):
        if self.checkButtonClicks(event.x, event.y):
            r,c = self.selected
        else:
            r,c = self.getRowCol(event.x, event.y)
        self.selected = (r,c)
        if (r,c) != (-1,-1):
            # if the selection isnt empty/default, and its a JPEG, render it
            self.selectedFile = self.thumbnailArray[r][c][1]
            if self.selectedFile.endswith(".jpg") or \
            self.selectedFile.endswith(".JPG") or \
            self.selectedFile.endswith(".jpeg") or \
            self.selectedFile.endswith(".JPEG"):
                self.lowPolyGenerator = LowPolyGenerator(self.selectedFile,
                blurSize=self.app.blurSize, sharpen=self.app.sharpen,
                nodeSampleDistanceThreshold=self.app.nodeSampleDistanceThreshold,
                randomNoiseRate=self.app.randomNoiseRate,
                cannyLow=self.app.cannyLow, cannyHigh=self.app.cannyHigh,
                nodeSampleRate=self.app.nodeSampleRate,
                nodeThresholdRate=self.app.nodeThresholdRate)
                self.lowPolyGenerator.generateTriangulation()
                self.lowPolyImage = LowPolyImage(self.lowPolyGenerator, self.selectedFile)
                self.app.toRender = (self.lowPolyImage, self.selectedFile)
                self.app.setActiveMode(self.app.renderMode)
                self.previewImage = self.app.rendered
                self.previewImage = self.trim(self.previewImage)
                 #Magic Number
                self.previewImage.thumbnail((2*self.previewSize//3, 2*self.previewSize//3))
                self.app.renderMode = RenderMode()
                self.generateFileGrid()
            #Otherwise, if its a directory, navigate to that
            elif os.path.isdir(self.selectedFile):
                self.directory = self.selectedFile
                self.generateFileGrid()
                self.scroll = -40
                self.selected = (-1,-1)
        self.generateDirectoryButtons()

    # draws grid of icons on left
    def drawGrid(self, canvas):
        thumbnailSize = self.thumbnailSize
        folderIconColor = LowPolyGenerator.rgbString(120,180,210)
        captionColor = LowPolyGenerator.rgbString(180,180,180)
        lighterBackgroundColor = LowPolyGenerator.rgbString(78,78,78)
        backgroundColor = LowPolyGenerator.rgbString(50,50,50)
        darkerBackgroundColor = LowPolyGenerator.rgbString(38,38,38)
        outlineBlue = LowPolyGenerator.rgbString(38,101,203)

        canvas.create_rectangle(0,0, self.width, self.height, fill=backgroundColor)
        availableLength = self.width - self.previewSize - 4*self.margin
        canvas.create_line(self.width - self.previewSize, 0,
        self.width - self.previewSize, self.height, fill = "black")
        maxC = availableLength//thumbnailSize
        # Draws images, boxes, and captions
        r,c = 0,0
        for i in range(len(self.thumbnails)):
            if (r,c) == self.selected:
                boxColor = lighterBackgroundColor
                outlineColor = outlineBlue
            else:
                boxColor = darkerBackgroundColor
                outlineColor = "black"
            canvas.create_rectangle(
            c*thumbnailSize + (c+1)*self.margin,
            r*thumbnailSize + (r+1)*self.margin - self.scroll,
            c*thumbnailSize + self.thumbnailSize + (c+1)*self.margin,
            r*thumbnailSize + self.thumbnailSize + (r+1)*self.margin - self.scroll,
            fill = boxColor, outline = outlineColor)
            suffixes = (".jpg", ".JPG", ".jpeg", "JPEG")
            if self.thumbnails[i][1].endswith(suffixes):
                canvas.create_image(c*thumbnailSize + self.thumbnailSize//2 + (c+1)*self.margin,
                r*thumbnailSize + self.thumbnailSize//2 - self.scroll + (r+1)*self.margin,
                image=ImageTk.PhotoImage(self.thumbnails[i][0]))
            else:
                if os.path.isdir(self.thumbnails[i][1]):
                    iconThumbnail = self.folderIcon.copy()
                    iconThumbnail.thumbnail((self.thumbnailSize//2,self.thumbnailSize//2), Image.ANTIALIAS)
                else:
                    iconThumbnail = self.fileIcon.copy()
                    iconThumbnail.thumbnail((self.thumbnailSize//2,self.thumbnailSize//2), Image.ANTIALIAS)

                color = folderIconColor
                canvas.create_image(c*thumbnailSize + self.thumbnailSize//2 + (c+1)*self.margin,
                r*thumbnailSize + self.thumbnailSize//2 - self.scroll + (r+1)*self.margin,
                image=ImageTk.PhotoImage(iconThumbnail))
                # else:
                #     color = "green"
                #     canvas.create_rectangle(
                #     c*thumbnailSize + self.thumbnailSize//2 - self.thumbnailSize//4 + (c+1)*self.margin,
                #     r*thumbnailSize + self.thumbnailSize//2 - self.thumbnailSize//4 + (r+1)*self.margin - self.scroll,
                #     c*thumbnailSize + self.thumbnailSize//2 + self.thumbnailSize//4 + (c+1)*self.margin,
                #     r*thumbnailSize + self.thumbnailSize//2 + self.thumbnailSize//4 + (r+1)*self.margin - self.scroll,
                #     fill = color)
            imgName = self.thumbnails[i][1].split("/")[-1]
            if imgName == self.directory.split("/")[-2]:
                imgName = ".."
            if len(imgName) > 2*thumbnailSize//12:
                imgName = "..."+imgName[-15:]
            canvas.create_text(c*thumbnailSize + self.thumbnailSize//2 + (c+1)*self.margin,
            r*thumbnailSize + thumbnailSize - self.scroll - 5 + (r+1)*self.margin,
            text=imgName, anchor="s", font="Arial 12", fill=captionColor)
            c += 1
            if c > maxC - 1:
                r += 1
                c = 0

    def keyPressed(self, event):
        scrollDelta = 40
        thumbnailDelta = 20
        if event.key == "Down":
            self.scroll += scrollDelta
        elif event.key == "Up":
            self.scroll -= scrollDelta
            self.scroll = max(self.scroll, -40)
        elif event.key == "Left":
            self.thumbnailSize -= thumbnailDelta
            self.thumbnailSize = max(self.thumbnailSize, 1)
            self.scrollDelta = int(0.7*scrollDelta)
            try:
                self.directoryList = self.generateFileGrid()
            except:
                pass
        elif event.key == "Right":
            self.thumbnailSize += thumbnailDelta
            self.scrollDelta = int(1.3*scrollDelta)
            try:
                self.directoryList = self.generateFileGrid()
            except:
                pass
        elif event.key == "h":
            self.app.setActiveMode(self.app.helpMode)
        elif event.key == "p":
            self.changeParameters()
        elif event.key == "s":
            self.saveImage()

    # Saves the current previewed image
    def saveImage(self):
        if self.previewImage != None:
            name = self.selectedFile.split("/")[-1]
            name = name.split(".")[0]
            hashStr = hash((self.app.blurSize,
            self.app.sharpen,
            self.app.cannyLow,
            self.app.cannyHigh,self.app.randomNoiseRate,
            self.app.nodeSampleDistanceThreshold,
            self.app.nodeSampleRate,
            self.app.nodeThresholdRate))
            hashStr = str(hashStr)[-4:]
            try:
                os.mkdir(os.path() + "/Saved")
            except:
                pass
            self.previewImage.save(f"./Saved/{name}Poly{hashStr}.jpg")
            print("Saved")
        elif event.key == ".":
            self.showHidden = not self.showHidden
            self.directoryList = self.generateFileGrid()

    # Displays Matplotlib sliders to change parameters
    def changeParameters(self):
        fig, ax = plt.subplots(figsize=(8.5, 3))
        plt.axis('off')
        high = plt.axes([0.25, 0.2, 0.65, 0.03])
        low = plt.axes([0.25, 0.3, 0.65, 0.03])
        blur = plt.axes([0.25, 0.4, 0.65, 0.03])
        sharpenAx = plt.axes([0.25, 0.5, 0.65, 0.03])
        noise = plt.axes([0.25, 0.6, 0.65, 0.03])
        threshold = plt.axes([0.25, 0.7, 0.65, 0.03])
        nodeSample = plt.axes([0.25, 0.8, 0.65, 0.03])
        nodeThreshold = plt.axes([0.25, 0.9, 0.65, 0.03])
        blurSize = \
        Slider(blur, "Blur Size", valmin=1, valmax=9,
        valinit=self.app.blurSize, valstep=2)
        sharpen = \
        Slider(sharpenAx, "Sharpen", valmin=0, valmax=1,
        valinit=int(self.app.sharpen), valstep=1)
        cannyLow = \
        Slider(low, "Edge Low", valmin=1, valmax=1000,
        valinit=self.app.cannyLow, valstep=1)
        cannyHigh = \
        Slider(high, "Edge High", slidermin=cannyLow, valmin=1, valmax=1000,
        valinit=self.app.cannyHigh, valstep=1)
        noiseRate = \
        Slider(noise, "Noise Rate", valmin=0, valmax=5000,
        valinit=self.app.randomNoiseRate, valstep=100)
        nodeSampleDistanceThreshold = \
        Slider(threshold, "Threshold distance", valmin=0, valmax=100,
        valinit=self.app.nodeSampleDistanceThreshold, valstep=5)
        nodeSampleRate = \
        Slider(nodeSample, "Node Sample Rate", valmin=0, valmax=1,
        valinit=self.app.nodeSampleRate, valstep=0.01)
        nodeThresholdRate = \
        Slider(nodeThreshold, "Node Threshold Check Rate", valmin=0, valmax=1,
        valinit=self.app.nodeThresholdRate, valstep=0.01)
        plt.show()
        self.app.blurSize = int(blurSize.val)
        self.app.sharpen = bool(sharpen.val)
        self.app.cannyLow = int(cannyLow.val)
        self.app.cannyHigh = int(cannyHigh.val)
        self.app.randomNoiseRate = int(noiseRate.val)
        self.app.nodeSampleDistanceThreshold = int(nodeSampleDistanceThreshold.val)
        self.app.nodeSampleRate = nodeSampleRate.val
        self.app.nodeThresholdRate = nodeThresholdRate.val

    def drawCols(self, canvas):
        for i in range(self.width//100):
            if not (i*100 == self.previewSize):
                canvas.create_line(100*i, 0, 100*i, self.height)

    # Checks if mouse is hovering over the parameters button
    def checkParametersHover(self, event):
        button = self.parametersButton
        mx, my = event.x, event.y
        if mx > button.x - button.width//2 and \
        mx < button.x + button.width//2 and \
        my > button.y - button.height//2 and \
        my < button.y + button.height//2:
            self.mousePosition = (mx, my)
        else:
            self.mousePosition = (None, None)

    def mouseMoved(self, event):
        self.checkParametersHover(event)

    # Draws box with current parameters on hover
    def drawParametersText(self, canvas, x, y):
        captionColor = LowPolyGenerator.rgbString(180,180,180)
        lighterBackgroundColor = LowPolyGenerator.rgbString(78,78,78)
        text = f" Blur size: {self.app.blurSize} \n Sharpen: {self.app.sharpen} \n Edge Detection Bounds: ({self.app.cannyLow} : {self.app.cannyHigh}) \n Approximate Randomly Sampled Points: {self.app.randomNoiseRate} \n Node Sample Rate: {self.app.nodeSampleRate} \n Node Threshold Distance and Check Rate: {(100*self.app.nodeSampleDistanceThreshold)//100}, {self.app.nodeThresholdRate}"
        canvas.create_rectangle(x - 175, y - 150, x + 175, y - 40, fill=lighterBackgroundColor)
        canvas.create_text(x - 175, y - 50, text=text, fill=captionColor, anchor="sw")

    def redrawAll(self, canvas):
        self.drawGrid(canvas)
        canvas.create_text(self.width - self.previewSize//2, 20,
        text = f"{self.selectedFile}", font="Arial 12", fill=LowPolyGenerator.rgbString(180,180,180))
        if self.previewImage != None:
            canvas.create_image(self.width - self.previewSize//2, self.height//3, image = ImageTk.PhotoImage(self.previewImage))
        canvas.create_rectangle(0,0,self.width-self.previewSize, 60, fill=LowPolyGenerator.rgbString(50,50,50), width=0)
        self.parametersButton.draw(canvas)
        self.helpButton.draw(canvas)
        for button in self.pathButtons:
            button.draw(canvas)
        if self.mousePosition != (None, None):
            self.drawParametersText(canvas, self.mousePosition[0], self.mousePosition[1])

if __name__ == "__main__":
    app = PolyBridge(width=1500, height=1000)


import numpy as np
import cv2 as cv
import glob
import sys

sys.path.insert(0, '../utils/')
from jsontools import JsonTools

'''
src: https://docs.opencv.org/4.x/dc/dbb/tutorial_py_calibration.html

Get variables from reliable cameramatrix like this:
+------------+
| fx, 0,  cx |
| 0,  fy, cy |
| 0,  0,  1  |
+------------+
'''

# Termination criteria
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30, 0.001)

# Size of chessboard
size = (6,9)

# Prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
objp = np.zeros((size[0]*size[1],3), np.float32)
objp[:,:2] = np.mgrid[0:size[0],0:size[1]].T.reshape(-1,2)

# Arrays to store object points and image points from all the images.
objpoints = [] # 3d point in real world space
imgpoints = [] # 2d points in image plane.
images = glob.glob('images/*.jpg')

print(len(images), 'images')

numWork = 0

for fname in images:
    img = cv.imread(fname)
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

    # Find the chess board corners
    ret, corners = cv.findChessboardCorners(gray, size, None)

    # If found, add object points, image points (after refining them)
    if ret == True:
        numWork += 1
        objpoints.append(objp)
        corners2 = cv.cornerSubPix(gray,corners, (11,11), (-1,-1), criteria)
        imgpoints.append(corners)

        # Draw and display the corners
        cv.drawChessboardCorners(img, size, corners2, ret)
        cv.imshow('img', img)

print(numWork, 'work')

# Camera matrix, distortion coefficients, rotation and translation vectors
ret, mtx, dist, rvecs, tvecs = cv.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)

h,  w = img.shape[:2]
newcameramtx, roi = cv.getOptimalNewCameraMatrix(mtx, dist, (w,h), 1, (w,h))

# Undistort
dst = cv.undistort(img, mtx, dist, None, newcameramtx)

# Crop the image
x, y, w, h = roi
dst = dst[y:y+h, x:x+w]
cv.imwrite('calibresult.png', dst)
error = 0
for i in range(len(objpoints)):
    projected_points = cv.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)[0]
    temp = cv.norm(imgpoints[i], projected_points, cv.NORM_L2)/len(projected_points)
    error += temp

error /= len(objpoints)

#Write things to file
stuff = {
    'fx': mtx[0][0],
    'fy': mtx[1][1],
    'cx': mtx[0][2],
    'cy': mtx[1][2],
    'error' : error
}

print(stuff)

tools = JsonTools()
tools.writeJson('../files/matrix.txt', stuff)


#!/usr/bin/env python

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

VERSION = "1.32"

ext_modules = [
    Extension("bitfield",
              ["cimpl/field.pyx"],
              extra_compile_args=["-g"],
              extra_link_args=["-g"],
              depends=["cimpl/field.h", "cimpl/field.c"]
              )
]

if __name__ == "__main__":
    setup(
        name="bitfield",
        version=VERSION,
        license="BSD",

        description="A Cython fast compressed number set",
        author="Steve Stagg",
        author_email="stestagg@gmail.com",

        url="http://github.com/stestagg/bitfield",

        classifiers=[
            'Development Status :: 4 - Beta',
            'Intended Audience :: Developers',
            'License :: OSI Approved :: BSD License',
            'Operating System :: OS Independent',
            'Programming Language :: Python',
        ],

        package_data={"Cython": ["cimpl/*.pyx"]},

        cmdclass={"build_ext": build_ext},
        ext_modules=ext_modules,
    )


import unittest
import time
from copy import deepcopy

# O (NxN)

def rotate_matrix_algo(matrix):
    """rotates a matrix 90 degrees clockwise"""
    new_matrix = deepcopy(matrix)
    for i, row in enumerate(matrix):
        curr_row = 0
        for j, number in enumerate(row):
            curr_column = len(row) - i - 1
            new_matrix[curr_row][curr_column] = number
            curr_row += 1
    return new_matrix

class Test(unittest.TestCase):
    test_cases = [
        (
            [
                [1, 2, 3],
                [4, 5, 6],
                [7, 8, 9],
            ],
            [
                [7, 4, 1],
                [8, 5, 2],
                [9, 6, 3],
            ]
        ),
        (
            [
                [1, 2, 3, 4, 5],
                [6, 7, 8, 9, 10],
                [11, 12, 13, 14, 15],
                [16, 17, 18, 19, 20],
                [21, 22, 23, 24, 25],
            ],
            [
                [21, 16, 11, 6, 1],
                [22, 17, 12, 7, 2],
                [23, 18, 13, 8, 3],
                [24, 19, 14, 9, 4],
                [25, 20, 15, 10, 5],
            ],
        ),
    ]

    testable_functions = [
        rotate_matrix_algo
    ]

    def test_rotate_matrix(self):
        for function in self.testable_functions:
            start = time.perf_counter()
            for _ in range(1000):
                for matrix, expected in self.test_cases:
                    actual = function(matrix)
                    assert actual == expected, f"Failed {function.__name__} for: {[matrix]}"
            duration = time.perf_counter() - start
            print(f"{function.__name__} {duration * 1000:.1f}ms")

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


from django.core.exceptions import ObjectDoesNotExist

from rest_framework import serializers, status
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from drf_spectacular.utils import extend_schema, OpenApiParameter

from authentication.decorators import has_permissions
from authentication.models import Qualification
from authentication.serializers import QualificationSerializer, QualificationListSerializer
from authentication.filters import QualificationFilter

from commons.enums import PermissionEnum
from commons.pagination import Pagination

# Create your views here.

@extend_schema(
	parameters=[
		OpenApiParameter("page"),
		OpenApiParameter("size"),
  ],
	request=QualificationSerializer,
	responses=QualificationSerializer
)
@api_view(['GET'])
# @permission_classes([IsAuthenticated])
# @has_permissions([PermissionEnum.PERMISSION_LIST_VIEW.name])
def getAllQualification(request):
	qualifications = Qualification.objects.all()
	total_elements = qualifications.count()

	page = request.query_params.get('page')
	size = request.query_params.get('size')

	# Pagination
	pagination = Pagination()
	pagination.page = page
	pagination.size = size
	qualifications = pagination.paginate_data(qualifications)

	serializer = QualificationListSerializer(qualifications, many=True)

	response = {
		'qualifications': serializer.data,
		'page': pagination.page,
		'size': pagination.size,
		'total_pages': pagination.total_pages,
		'total_elements': total_elements,
	}

	return Response(response, status=status.HTTP_200_OK)

@extend_schema(
	parameters=[
		OpenApiParameter("page"),
		OpenApiParameter("size"),
  ],
	request=QualificationSerializer,
	responses=QualificationSerializer
)
@api_view(['GET'])
# @permission_classes([IsAuthenticated])
# @has_permissions([PermissionEnum.PERMISSION_LIST_VIEW.name])
def getAllQualificationWithoutPagination(request):
	qualifications = Qualification.objects.all()

	serializer = QualificationListSerializer(qualifications, many=True)

	return Response({'qualifications': serializer.data}, status=status.HTTP_200_OK)

@extend_schema(request=QualificationSerializer, responses=QualificationSerializer)
@api_view(['GET'])
# @permission_classes([IsAuthenticated])
# @has_permissions([PermissionEnum.PERMISSION_DETAILS_VIEW.name])
def getAQualification(request, pk):
	try:
		qualification = Qualification.objects.get(pk=pk)
		serializer = QualificationSerializer(qualification)
		return Response(serializer.data, status=status.HTTP_200_OK)
	except ObjectDoesNotExist:
		return Response({'detail': f"Qualification id - {pk} doesn't exists"}, status=status.HTTP_400_BAD_REQUEST)

@extend_schema(request=QualificationSerializer, responses=QualificationSerializer)
@api_view(['GET'])
# @permission_classes([IsAuthenticated])
# @has_permissions([PermissionEnum.PRODUCT_DETAILS.name])
def searchQualification(request):

	qualifications = QualificationFilter(request.GET, queryset=Qualification.objects.all())
	qualifications = qualifications.qs

	print('qualifications: ', qualifications)

	total_elements = qualifications.count()

	page = request.query_params.get('page')
	size = request.query_params.get('size')

	# Pagination
	pagination = Pagination()
	pagination.page = page
	pagination.size = size
	qualifications = pagination.paginate_data(qualifications)

	serializer = QualificationListSerializer(qualifications, many=True)

	response = {
		'qualifications': serializer.data,
		'page': pagination.page,
		'size': pagination.size,
		'total_pages': pagination.total_pages,
		'total_elements': total_elements,
	}

	if len(qualifications) > 0:
		return Response(response, status=status.HTTP_200_OK)
	else:
		return Response({'detail': f"There are no qualifications matching your search"}, status=status.HTTP_400_BAD_REQUEST)

@extend_schema(request=QualificationSerializer, responses=QualificationSerializer)
@api_view(['POST'])
@permission_classes([IsAuthenticated])
# @has_permissions([PermissionEnum.PERMISSION_CREATE.name])
def createQualification(request):
	data = request.data
	filtered_data = {}

	for key, value in data.items():
		if value != '' and value != 0 and value != '0':
			filtered_data[key] = value

	print('data: ', data)
	print('filtered_data: ', filtered_data)

	serializer = QualificationSerializer(data=filtered_data)

	if serializer.is_valid():
		serializer.save()
		return Response(serializer.data, status=status.HTTP_201_CREATED)
	else:
		return Response(serializer.errors)

@extend_schema(request=QualificationSerializer, responses=QualificationSerializer)
@api_view(['PUT'])
@permission_classes([IsAuthenticated])
# @has_permissions([PermissionEnum.PERMISSION_UPDATE.name, PermissionEnum.PERMISSION_PARTIAL_UPDATE.name])
def updateQualification(request,pk):
	data = request.data

	print('data: ', data)
	print('request.content_type: ', request.content_type)

	qualification_dict = {}

	for key, value in data.items():
		if 'image_doc' in key and type(value) == str:
			pass
		else:
			qualification_dict[key] = value

	print('qualification_dict: ', qualification_dict)

	try:
		qualification = Qualification.objects.get(pk=pk)

		serializer = QualificationSerializer(qualification, data=qualification_dict)
		if serializer.is_valid():
			serializer.save()
			return Response(serializer.data, status=status.HTTP_200_OK)
		else:
			return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
	except ObjectDoesNotExist:
		return Response({'detail': f"Qualification id - {pk} doesn't exists"}, status=status.HTTP_400_BAD_REQUEST)

@extend_schema(request=QualificationSerializer, responses=QualificationSerializer)
@api_view(['DELETE'])
@permission_classes([IsAuthenticated])
# @has_permissions([PermissionEnum.PERMISSION_DELETE.name])
def deleteQualification(request, pk):
	try:
		qualification = Qualification.objects.get(pk=pk)
		qualification.delete()
		return Response({'detail': f'Qualification id - {pk} is deleted successfully'}, status=status.HTTP_200_OK)
	except ObjectDoesNotExist:
		return Response({'detail': f"Qualification id - {pk} doesn't exists"}, status=status.HTTP_400_BAD_REQUEST)


from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

import os, shutil
import json
import time

destination = "C:/Users/rjada/OneDrive/Documents/Python/download-organisation/Test-1"
source = "C:/Users/rjada/OneDrive/Documents/Python/download-organisation/Test-2"

class Handler(FileSystemEventHandler):
    def on_modified(self,event):
        for filename in os.listdir(source):
            origin = source + "/" + filename
            new_destination = destination + "/" + filename
            os.rename(origin, new_destination)

event_handler = Handler()
observer = Observer()
observer.schedule(event_handler, source, recursive=True)

try :
    while True:
        time.sleep(10)
except KeyboardInterrupt:
    observer.stop()

observer.join()

if __name__ == "__main__":
    print(destination)
    print(source)


import os
import time
import asyncio
import math
from datetime import datetime
import ccxt.async_support as ccxt

class data_loader:

    def __init__(self,target_list,t_int = 10,**kwargs):

        self.exchange_id = 'binance'
        self.binance_key = None
        self.binance_secret = None
        self.base_path = None
        # connect to the exchange
        self.connect()
        if 'target_pairs' in kwargs:
            self.target_pairs = kwargs['target_pairs']
            self.target_table = {key:None for key in self.target_pairs}

        self.cur_limit = 10
        self.target_list = target_list
        self.t_int = t_int

    def connect(self):
        exchange_cls = getattr(ccxt, self.exchange_id)
        exchange = exchange_cls({'apiKey': self.binance_key, 'secret': self.binance_secret})
        self.exchange = exchange

    def main(self):
        while True:
            try:
                asyncio.run(self.overall(self.t_int))
            except Exception as e:
                print(f'error_occured_{time.localtime()}')
                print(e)
                time.sleep(10)

    async def fetch_all(self,target):
        fetch_tasks = [self.exchange.fetch_l2_order_book(symbol = cur_target, limit = self.cur_limit) for cur_target in target]
        fetched_data = await asyncio.gather(*fetch_tasks)
        return fetched_data

    async def write(self,datum,target_date):
        # parse datum - symbol, 10 datas - qty, pr

        symbol = datum['symbol']
        bid = [str(j) for i in datum['bids'] for j in i]
        ask = [str(j) for i in datum['asks'] for j in i]
        ask = ask + bid
        lined_txt = ','.join(ask)
        symbol = datum['symbol']

        # make it into one liner
        lined_data = [symbol] + [str(int(time.time()*1000))] + ask + bid
        lined_txt = ', '.join(lined_data)
        # write to file
        cur_path = os.path.join(self.base_path,symbol)
        os.makedirs(cur_path, exist_ok= True)
        cur_path = os.path.join(cur_path,target_date + '.csv')
        with open(cur_path, "a+") as f:
            f.write(lined_txt)
            f.write("\n")

    async def write_all(self,data,target_date):
        write_tasks = [self.write(datum,target_date) for datum in data]
        await asyncio.gather(*write_tasks)
        return True

    async def overall(self,t_int):
        target_list = self.target_list

        # 1. time setup
        cur_time = time.time() * 1000
        target_time = math.ceil(cur_time)
        time_till_d_end = target_time % (1000 * 3600 * 24)
        #target_date = datetime.utcfromtimestamp(int(target_time/1000)).strftime('%Y%m%d')
        target_date = datetime.utcnow().strftime('%Y%m%d')
        await asyncio.sleep(target_time - cur_time)

        while True:
            #3. fetch all
            data = await self.fetch_all(target_list)
            #4. write all
            _ = await self.write_all(data,target_date)
            # 5. daily timer - ignore daily timer
            #time_till_d_end -= t_int * 1000
            # 6. current sleep time setup
            target_time += t_int * 1000
            # 5.1 date update by cond.
            if time_till_d_end < 0:
                time_till_d_end = 3600 * 24 * 1000
            #target_date = datetime.utcfromtimestamp(int(target_time/1000)).strftime('%Y%m%d')
            target_date = datetime.utcnow().strftime('%Y%m%d')
            time_diff = target_time/1000 - time.time()
            # fault tolerance code
            #
            print(time_diff)
            await asyncio.sleep(time_diff)

if __name__ == "__main__":
    target_pairs = ['BTCUSDT','ETHUSDT',"BNBUSDT","XRPUSDT","ADAUSDT"]
    binance = data_loader(target_list = target_pairs, t_int=0.5)
    binance.main()


from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
from numpy import random
import seaborn as sns
import pandas as pd

resultados_exames = pd.read_csv("/content/exames.csv")

SEED = 123143
random.seed(SEED)

valores_exames = resultados_exames.drop(columns=['id', 'diagnostico'])
diagnostico = resultados_exames.diagnostico
valores_exames_v1 = valores_exames.drop(columns="exame_33")

treino_x, teste_x, treino_y, teste_y = train_test_split(valores_exames_v1,
                                                        diagnostico,
                                                        test_size = 0.3)

classificador = RandomForestClassifier(n_estimators = 100)
classificador.fit(treino_x, treino_y)

padronizador = StandardScaler()
padronizador.fit(valores_exames_v1)

valores_exames_v2 = padronizador.transform(valores_exames_v1)
valores_exames_v2 = pd.DataFrame(data = valores_exames_v2, columns=valores_exames_v1.keys())

valores_exames_v3 = valores_exames_v2.drop(columns=["exame_29", "exame_4"])

def classificar(valores):
    SEED = 1234
    random.seed(SEED)
    treino_x, teste_x, treino_y, teste_y = train_test_split(valores,
                                                        diagnostico,
                                                        test_size = 0.3)

    classificador = RandomForestClassifier(n_estimators = 100)
    classificador.fit(treino_x, treino_y)
    print("Resultado da classificação %.2f%%\n\n" %(classificador.score(teste_x,teste_y)*100))

matriz_correlacao = valores_exames_v3.corr()
plt.figure(figsize = (17, 15))
sns.heatmap(matriz_correlacao, annot = True, fmt = ".1f")

matriz_correlacao_v1 = matriz_correlacao[matriz_correlacao>0.99]
matriz_correlacao_v1
matriz_correlacao_v2 = matriz_correlacao_v1.sum()

variaveis_correlacionadas = matriz_correlacao_v2[matriz_correlacao_v2>1]
variaveis_correlacionadas
valores_exames_v4 = valores_exames_v3.drop(columns=variaveis_correlacionadas.keys())

valores_exames_v5 = valores_exames_v3.drop(columns=["exame_3", "exame_24"])
classificar(valores_exames_v5)


import csv
import sigFigs
def getMMass(sVal):
    temp = ''
    for i in sVal:
        if i == '(':
            break
        elif i != '[' and i != ']':
            temp += i
    return temp
def getInfo(sFileName = 'PeriodicTable.csv'):
    elements = [[],[]]
    ptF = open(sFileName)
    csPtF = csv.reader(ptF)
    for row in csPtF:
        elements[0].append(row[1])
        elements[1].append(getMMass(row[3]))
    ptF.close()
    return elements
elements = getInfo()
def symToMass(sSym,coef = 1):
    try:
        for i in range(0,len(elements[0])):
            if  sSym == elements[0][i]:
                return str(coef * float(elements[1][i]))
                break
        raise ValueError(sSym + ' Was not found in the elemental database')
    except ValueError as err:
        print(err)
        return ('Err')
def interpForm(formula):
    temp =  formula
    syms =  []
    #getting each element in the formula
    t = ''
    for i in temp:
        if i.isupper():
            syms.append(t)
            t = i
        else:
            t += i
    if t != '':
        syms.append(t)
    del syms[0]
    molarWeight = ''
    for i in syms:
        tem = ''
        sstc = ''
        istc = 0
        for j in i:
            if j.isdigit():
                sstc += j
            else:
                tem += j
        if len(sstc) == 0:
            sstc = '1'
        istc = int(sstc)
        try:
            mw = symToMass(tem, istc)
            if mw == 'Err':
                raise ValueError()
            if molarWeight == '':
                molarWeight = mw
            else:
                molarWeight = sigFigs.add(molarWeight,mw)
        except ValueError:
            return 'Err'
    return molarWeight
def getStCoe(sFormula):
    sStCoe = ''
    #getting the stoechiometric coefficient
    for i in range(0,len(sFormula)):
        if sFormula[i].isdigit():
            sStCoe += sFormula[i]
        else:
            break
    if len(sStCoe) == 0:
        sStCoe = '1'
    return sStCoe
def cMolarWeight():
    CF = input('Enter the chemical formula: ')
    if hasElement(CF) == False:
        print('Invalid Input')
        return 'Err'
    temp =  CF
    sStCoe = getStCoe(CF)
    #getting the stoechiometric coefficient
    if len(sStCoe) > 1:
        temp = CF[len(sStCoe):len(CF)]
    MW = str(interpForm(temp))
    if MW == 'Err':
        return 'Err'
    print('The molar weight of', CF,'is', sigFigs.eMultiply(MW,int(sStCoe)),'amu')
    return sigFigs.eMultiply(MW,int(sStCoe))
def cProductYeild():
    CFR = input('Enter the formula of the reactant (with the stoichiometric coefficient): ')
    if hasElement(CFR) == False:
        print('Invalid Input')
        return 'Err'
    #getting the molar weight and the stoichiometric coefficient of the reactant
    tempRF =  CFR
    sStCoeR = getStCoe(CFR)
    if len(sStCoeR) > 1:
        sStCoeR = CFR[len(sStCoeR):len(CFR)]
    MWR = str(interpForm(tempRF))
    if MWR == 'Err':
        return 'Err'
    MR = input('Enter the mass of the reactant (in grams): ')
    if hasChar(MR) == True:
        print('Invalid Input')
        return 'Err'
    elif '-' in MR:
        print('Cannot compute negative numbers')
        return 'Err'
    molR = sigFigs.divide(MR,MWR)
    CFP = input('Enter the formula of the product (with the stoichiometric coefficient): ')
    if hasElement(CFP) == False:
        print('Invalid Input')
        return 'Err'
    #getting the molar weight and the stoichiometric coefficient of the product
    tempPF =  CFP
    sStCoeP = getStCoe(CFP)
    if len(sStCoeP) > 1:
        sStCoeP = CFP[len(sStCoeP):len(CFP)]
    MWP = str(interpForm(tempPF))
    if MWP == 'Err':
        return 'Err'
    molP = sigFigs.eMultiply(molR,float(sStCoeP)/float(sStCoeR))
    print(molR,'moles', CFR,'*',float(sStCoeP),'/',float(sStCoeR),'=',molP,'moles',CFP)
    MP = sigFigs.multiply(molP,MWP)
    print('Theoretical yeild is', molP,'moles',tempPF, 'or', MP,'g',tempPF)
    CPY = input('Would you like to calculate the percent Yield?').lower()
    if CPY == 'yes':
        EY = input('Enter the mass of the product (in grams): ')
        PY = sigFigs.eMultiply(sigFigs.divide(EY,MP),100)
        print('The percent yield is',PY+'%')

    else:
        return molP
#Error trapping functions
def hasElement(sVal):
    for i in sVal:
        if i.isalpha():
            if i.isupper():
                return True
    return False
def hasChar(sVal):
    for i in sVal:
        if i.isalpha():
            return True
    return False
def prompt():
    print('Enter the number of the desired calculation:')
    print('1 - Molar Weight Calculator')
    print('2 - Theoretical Yeild Calculator')
    ans = input('Calculation #: ')
    if ans == '1':
        cMolarWeight()
    elif ans == '2':
        cProductYeild()
    else:
        print('There are no calculations that correspond with your input')
#Run from here
p = 'yes'
while p in ('yes','y','ok','i do'):
    p = ''
    prompt()
    p = input('Would you like to make another calculation? ').lower()


import matplotlib.pyplot as plt

class PlotSaver():
    """
    This class allow to save plots to images.
    """

    def __init__(self, model_description:str, pyplot_figure):
        """
        The class constructor.
            :param model_description:str: something to name the image unique and is also the file name
        """
        try:
            self._model_description:str = model_description
            self._pyplot_figure = pyplot_figure
        except Exception as ex:
            template = "An exception of type {0} occurred in [PlotSaver.Constructor]. Arguments:\n{1!r}"
            message = template.format(type(ex).__name__, ex.args)
            print(message)

    def SavePyPlotToFile(self, extender:str = None, orientation:str = 'landscape', image_type:str = 'png'):
        """
        This function is a simple wrapper for the PyPlot savefig function with default values.
            :param extender:str: extender for the filename [Default None]
            :param orientation:str: print orientation [Default 'landscape']
            :parama image_type:str: image file type [Default 'png']
        """
        try:
            if extender is None:
                self._pyplot_figure.savefig((self._model_description+'plot.'+image_type), orientation=orientation)
            else:
                self._pyplot_figure.savefig((self._model_description+extender+'.'+image_type), orientation=orientation)
        except Exception as ex:
            template = "An exception of type {0} occurred in [PlotSaver.SavePyPlotToFile]. Arguments:\n{1!r}"
            message = template.format(type(ex).__name__, ex.args)
            print(message)
            print(ex)


# -*- coding: utf-8 -*-
# File: distributed.py

import tensorflow as tf

def get_distributed_session_creator(server):
    """
    Args:
       server (tf.train.Server):

    Returns:
        tf.train.SessionCreator
    """

    server_def = server.server_def
    is_chief = (server_def.job_name == 'worker') and (server_def.task_index == 0)

    init_op = tf.global_variables_initializer()
    local_init_op = tf.local_variables_initializer()
    ready_op = tf.report_uninitialized_variables()
    ready_for_local_init_op = tf.report_uninitialized_variables(tf.global_variables())
    sm = tf.train.SessionManager(
        local_init_op=local_init_op,
        ready_op=ready_op,
        ready_for_local_init_op=ready_for_local_init_op,
        graph=tf.get_default_graph())

    # to debug wrong variable collection
    # from pprint import pprint
    # print("GLOBAL:")
    # pprint([(k.name, k.device) for k in tf.global_variables()])
    # print("LOCAL:")
    # pprint([(k.name, k.device) for k in tf.local_variables()])

    class _Creator(tf.train.SessionCreator):
        def create_session(self):
            if is_chief:
                return sm.prepare_session(master=server.target, init_op=init_op)
            else:
                tf.logging.set_verbosity(tf.logging.INFO)   # print message about uninitialized vars
                ret = sm.wait_for_session(master=server.target)
                tf.logging.set_verbosity(tf.logging.WARN)
                return ret

    return _Creator()


class Solution:
    def minRemoveToMakeValid(self, s: str) -> str:
        stack = []
        for i, c in enumerate(s):
            if c == '(':
                stack.append(i)
            elif c == ')':
                if stack and s[stack[-1]] == '(':
                    stack.pop()
                else:
                    stack.append(i)
        res = []
        for i, c in enumerate(s):
            if i not in stack:
                res.append(c)
        return ''.join(res)


class Solution:
    def topKFrequent(
            self, nums: List[int], k: int) -> List[int]:  # 55.48% 84.54%
        count = {}
        for num in nums:
            count[num] = count.get(num, 0) + 1
        return sorted(count, key=count.get)[-k:]

    def topKFrequent_best_speed(self, nums: List[int], k: int) -> List[int]:
        d = collections.defaultdict(int)
        for num in nums:
            d[num] += 1
        h = []
        for key, val in d.items():
            if not h or len(h) < k:
                heapq.heappush(h, (val, key))
            else:
                if h[0][0] < val:
                    heapq.heappop(h)
                    heapq.heappush(h, (val, key))
        out = []
        for _ in range(k):
            curr = heapq.heappop(h)
            out.append(curr[1])
        return out

    def topKFrequent_3d_best_speed(self, nums: List[int], k: int) -> List[int]:
        freq = collections.Counter(nums)
        heap = [(-v, k) for k, v in freq.items()]
        heapq.heapify(heap)
        output = []
        for i in range(k):
            v, k = heapq.heappop(heap)
            output.append(k)
        return output

Study Plan - Data Structure II/Day 20 Heap (Priority Queue)/347 - Top K Frequent Elements.py


casos_teste = int(input())

for i in range(casos_teste):
    ganhador_index = None
    menor_diferenca = 9999999999999

    alunos, numero_sorteado = [int(z) for z in input().split()]

    numeros_chutados = [int(z) for z in input().split()]

    for index, numero_chutado in enumerate(numeros_chutados):
        if abs(numero_sorteado - numero_chutado) < menor_diferenca:
            menor_diferenca = abs(numero_sorteado - numero_chutado)
            ganhador_index = index

    print(ganhador_index + 1)


"""
Logger functionality.

Author: Jonathan Ratschat
Date: 21.03.2022
"""

import logging

from constants import log_path

def load_logger(file_pth: str):
    logging.basicConfig(
        filename=log_path / file_pth,
        level=logging.INFO,
        filemode="w",
        format="%(name)s - %(levelname)s - %(message)s",
    )

    return logging


import random
import json

with open("config.json", "r") as f:
    config = json.load(f)

def guessgame():
    to_guess = random.randint(
        config["min_guess"],
        config["max_guess"],
    )

    guesses = config["guesscount"]

    while True:
        print(f"You have {guesses} left, what is your guess?")

        try:
            guess = int(input("Guess a number: "))
        except ValueError:
            print("Well that was silly, way to waste a guess on a non-number!")
        else:
            if guess == to_guess:
                print("Yay you win!!!")
            else:
                print("Wrong!!1 ", end="")
                if guess < to_guess:
                    print("Guess higher ^_^")
                else:
                    print("Guess lower ._.")
        finally:
            guesses -= 1

        if guesses == 0:
            print("Out of guesses buddy!")
            break

def exit():
    raise SystemExit(0)

options = {
    0: exit,
    1: guessgame,
}

def main():
    while True:
        print("Welcome to THE GAME please make a pick:")
        print("(0) Exit!")
        print("(1) Guess a number!")

        choice = input("Enter number of game to play: ")

        try:
            choice = int(choice)
        except ValueError:
            print("Could not understand your choice???")
            return

        if choice not in options:
            print("Could not understand your choice???")

        options[choice]()

if __name__ == "__main__":
    main()


## Exercícios com Strings

## 4 e 5 - Nome na vertical em escada e em escada invertida.
##         F
##         FU
##         FUL
##         FULA
##         FULAN
##         FULANO
##         FULAN
##         FULA
##         FUL
##         FU
##         F

import os
while 1:
    frase = input("Digite uma palavra ou frase: ").upper()
    if len(frase) > 0: break

for i in range(len(frase)):
    print(frase[:i])

for i in range(len(frase), 0, -1):
    print(frase[:i])

print("\n\nPressione qualquer tecla para fechar...")
os.system("pause >nul")

6 - Exercícios com Strings - Exercício 04 e 05.py


# Project name : HackerRank: Day 15: Linked List
# Link         : https://www.hackerrank.com/challenges/30-linked-list/problem
# Try it on    :
# Author       : Wojciech Raszka
# E-mail       : contact@gitpistachio.com
# Date created : 2020-07-03
# Description  :
# Status       : Accepted (167018361)
# Tags         : python, linked list
# Comment      :

class Node:
    def __init__(self,data):
        self.data = data
        self.next = None
class Solution:
    def display(self,head):
        current = head
        while current:
            print(current.data,end=' ')
            current = current.next

    def insert(self, head, data):
        new_node = Node(data)
        if head is None:
            head = new_node

        else:
            node = head
            while node.next is not None:
                node = node.next

            node.next = new_node
        return head

mylist= Solution()
T=int(input())
head=None
for i in range(T):
    data=int(input())
    head=mylist.insert(head,data)
mylist.display(head)

HackerRank/30 Days of Code/Day 15 Linked List/Linked List.py


import json
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
import numpy as np
from programs.model.modules.net_utils import run_lstm, col_name_encode

class SelPredictor(nn.Module):
    def __init__(self, N_word, N_h, N_depth, max_tok_num, use_ca, use_sel_cnn, filter_num):
        super(SelPredictor, self).__init__()
        self.use_ca = use_ca
        self.use_sel_cnn = use_sel_cnn
        self.filter_num = filter_num
        self.max_tok_num = max_tok_num
        if use_sel_cnn:
            self.sel_conv = nn.Sequential(
                nn.Conv2d(
                    in_channels=1,
                    out_channels=self.filter_num,
                    kernel_size= (7, N_word),
                    stride= (1, 1),
                    padding= (3, 0)
                ),
                nn.BatchNorm2d(self.filter_num),
                nn.RReLU()
            )
            self.sel_dropout = nn.Dropout2d(p=0.5)
            self.sel_name_enc = nn.LSTM(input_size=N_word,
                    hidden_size=int(self.filter_num/2), num_layers=N_depth,
                    batch_first=True, dropout=0.5, bidirectional=True)
            self.sel_att = nn.Linear(self.filter_num, 1)

            self.sel_out_K = nn.Linear(self.filter_num, self.filter_num)
            self.sel_out_col = nn.Linear(self.filter_num, self.filter_num)
            self.sel_out  = nn.Linear(self.filter_num, 1)
        else:
            self.sel_lstm = nn.LSTM(input_size=N_word, hidden_size=int(N_h/2),
                    num_layers=N_depth, batch_first=True,
                    dropout=0.3, bidirectional=True)
            if use_ca:
                print ("Using column attention on selection predicting")
                self.sel_att = nn.Linear(N_h, N_h)
            else:
                print ("Not using column attention on selection predicting")
                self.sel_att = nn.Linear(N_h, 1)
            self.sel_col_name_enc = nn.LSTM(input_size=N_word, hidden_size=int(N_h/2),
                    num_layers=N_depth, batch_first=True,
                    dropout=0.3, bidirectional=True)
            self.sel_out_K = nn.Linear(N_h, N_h)
            self.sel_out_col = nn.Linear(N_h, N_h)
            self.sel_out = nn.Sequential(nn.Tanh(), nn.Linear(N_h, 1))

        self.softmax = nn.Softmax()

    def forward(self, x_emb_var, x_len, col_inp_var,
            col_name_len, col_len, col_num):
        B = len(x_emb_var)
        max_x_len = max(x_len)

        if self.use_sel_cnn:
            e_cond_col, _ = col_name_encode(col_inp_var, col_name_len, col_len, self.sel_name_enc)
            x_cond_col = torch.unsqueeze(x_emb_var, dim=1)
            sel_conv_h = self.sel_conv(x_cond_col)
            sel_h = sel_conv_h.squeeze()
            sel_att_val = torch.bmm(e_cond_col, sel_h)
            for idx, num in enumerate(x_len):
                if num < max_x_len:
                    sel_att_val[idx, :, num:] = -100
            sel_att = self.softmax(sel_att_val.view(
                (-1, np.asscalar(max_x_len)))).view(B, -1, np.asscalar(max_x_len))
            sel_val = (sel_h.transpose(1,2).unsqueeze(1) * sel_att.unsqueeze(3)).sum(2)
            sel_score = self.sel_out(sel_val).squeeze()
            max_col_num = max(col_num)
            for b, num in enumerate(col_num):
                if num < max_col_num:
                    sel_score[b, num:] = -100
        else:
            e_col, _ = col_name_encode(col_inp_var, col_name_len,
                    col_len, self.sel_col_name_enc)

            if self.use_ca:
                h_enc, _ = run_lstm(self.sel_lstm, x_emb_var, x_len)
                att_val = torch.bmm(e_col, self.sel_att(h_enc).transpose(1, 2))
                for idx, num in enumerate(x_len):
                    if num < max_x_len:
                        att_val[idx, :, num:] = -100
                att = self.softmax(att_val.view((-1, np.asscalar(max_x_len)))).view(
                        B, -1, np.asscalar(max_x_len))
                K_sel_expand = (h_enc.unsqueeze(1) * att.unsqueeze(3)).sum(2)
            else:
                h_enc, _ = run_lstm(self.sel_lstm, x_emb_var, x_len)
                att_val = self.sel_att(h_enc).squeeze()
                for idx, num in enumerate(x_len):
                    if num < max_x_len:
                        att_val[idx, num:] = -100
                att = self.softmax(att_val)
                K_sel = (h_enc * att.unsqueeze(2).expand_as(h_enc)).sum(1)
                K_sel_expand=K_sel.unsqueeze(1)

            sel_score = self.sel_out( self.sel_out_K(K_sel_expand) + \
                    self.sel_out_col(e_col) ).squeeze()
            max_col_num = max(col_num)
            for idx, num in enumerate(col_num):
                if num < max_col_num:
                    sel_score[idx, num:] = -100
        return sel_score


list4 = [9, [1,[[[2,4,5],6]]],27,[3,[[["a","b","c"]]],6],45,[9,18],36]
n=str(list4).count('[')
print(n)

for x in range(n):
    flatten = []
    for i in list4:
        if type(i) == list:
            for j in i:
                flatten.append(j)

        else:
            flatten.append(i)
    list4=flatten.copy()

print(list4)


import subprocess

from selenium import webdriver

def driver(browser):
    # Init Browser
    driver_options = {
        'Edge': webdriver.EdgeOptions(),
        'Chrome': webdriver.ChromeOptions(),
        'Firefox': webdriver.FirefoxOptions()
    }

    options = driver_options.get(browser)
    options.add_argument('window-size=1920,1080')
    options.add_argument('--headless')  # Run webdriver in headless mode (without opening a browser window)

    driver_executables = {
        'Edge': './msedgedriver.exe',
        'Chrome': './chromedriver.exe',
        'Firefox': './geckodriver.exe'
    }

    return webdriver.__getattribute__(browser)(executable_path=driver_executables.get(browser), options=options)

def module():
    # Check pip module installed
    while True:
        try:
            import bs4
            import selenium
            import pandas
            import openpyxl

        except ModuleNotFoundError as e:
            print('Error: Dependency module not found. Try to installing')
            subprocess.call(['python', '-m', 'pip', '--disable-pip-version-check', 'install', 'BeautifulSoup4'])
            subprocess.call(['python', '-m', 'pip', '--disable-pip-version-check', 'install', 'pandas'])
            subprocess.call(['python', '-m', 'pip', '--disable-pip-version-check', 'install', 'openpyxl'])
            subprocess.call(['python', '-m', 'pip', '--disable-pip-version-check', 'install', 'selenium'])

        else:
            break

def args(thr, browser, new):
    # Check argument validity
    try:
        if int(thr) < 1 or int(thr) > 11:
            print('Error: Thread option must be in range of 1, 10')
            exit()

    except ValueError:
        print('Error: Thread option must be Int type, in range of 1,10')
        exit()

    support_bro = ['Edge', 'Chrome', 'Firefox']
    boolean = ['True', 'False']

    if browser not in support_bro:
        print('Error: You have to select browser in support browser list')
        exit()

    if new not in boolean:
        print('Error: You have to select True or False for crawling new data anyway')
        exit()


import json

class Solution:
    def fourSum(self, nums: list[int], target: int) -> list[list[int]]:
        results = set()
        duplicates1 = []
        duplicates2 = []
        values = {}
        for idx1, val1 in enumerate(nums):
            if val1 not in duplicates1:
                duplicates1.append(val1)
                for idx2, val2 in enumerate(nums[idx1+1:]):
                    if val2 not in duplicates2:
                        duplicates2.append(val2)
                        for idx3, val3 in enumerate(nums[idx2+1:]):
                            complement = (- val1 - val2 - val3 + target)
                            if complement in values:
                                results.add(tuple(sorted((val1, val2, val3, complement))))
                            values[val3] = idx3
                        values[val2] = idx2
                        duplicates2 = []
        return results

nums = [1,0,-1,0,-2,2]
target = 0
# Output: [[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
# nums = [2,2,2,2,2]
# target = 8
# Output: [[2,2,2,2]]
print(nums)
s = Solution().fourSum(nums, target)
print(
    s
)


import numpy as np
from sklearn.model_selection import train_test_split
import torch
from torch import tensor
import pandas as pd
import os
from torch.utils.data.sampler import SubsetRandomSampler
import constants_cmap
from scipy.stats import zscore, rankdata
import shutil

constants_cmap.DATASETS_DIR= os.path.join(constants_cmap.BASE_PROFILE, "tcga_datasets")

CANCER_TYPES= ["LUSC", "KIRC" , "KIRP", "LUSC", "LUAD", "COAD", "BRCA", "STAD", "LIHC", "READ", "PRAD", "BLCA", "HNSC", "THCA", "UCEC", "OV", "PAAD"]
constants_cmap.DATASETS_FILES=[
    "BLCA_normal_19.tsv",
    "BLCA_tumor_411.tsv",
    "BRCA_normal_113.tsv",
    "BRCA_tumor_1097.tsv",
    "COAD_normal_41.tsv",
    "COAD_tumor_469.tsv",
    "BLCA_normal_19.tsv",
    "BLCA_tumor_411.tsv",
    "COAD_tumor_469.tsv",
    "HNSC_normal_44.tsv",
    "HNSC_tumor_500.tsv",
    "KIRC_normal_72.tsv",
    "KIRC_tumor_534.tsv",
    "KIRP_normal_32.tsv",
    "KIRP_tumor_288.tsv",
    "LIHC_normal_50.tsv",
    "LIHC_tumor_371.tsv",
    "LUAD_normal_59.tsv",
    "LUAD_tumor_524.tsv",
    "LUSC_normal_49.tsv",
    "LUSC_tumor_501.tsv",
    "OV_normal_0.tsv",
    "OV_tumor_374.tsv",
    "PAAD_normal_4.tsv",
    "PAAD_tumor_177.tsv",
    "PRAD_normal_52.tsv",
    "PRAD_tumor_498.tsv",
    "READ_normal_10.tsv",
    "READ_tumor_166.tsv",
    "STAD_normal_32.tsv",
    "STAD_tumor_375.tsv",
    "THCA_normal_58.tsv",
    "THCA_tumor_502.tsv",
    "UCEC_normal_35.tsv",
    "UCEC_tumor_547.tsv"
]

constants_cmap.DATASETS_NAMES=["_".join(a.split("_")[0:2]) for a in constants_cmap.DATASETS_FILES]

constants_cmap.DATASETS_F=[0 for a in constants_cmap.DATASETS_FILES]
constants_cmap.DATASETS_F_NAMES=["nib" for a in constants_cmap.DATASETS_FILES]

dataset_files=[a for i, a in enumerate(constants_cmap.DATASETS_FILES)]

dataset_names=[a for i, a in enumerate(constants_cmap.DATASETS_NAMES)]
dataset_files=[a for i, a in enumerate(constants_cmap.DATASETS_FILES)]
dataset_f=[a for i, a in enumerate(constants_cmap.DATASETS_F)]
dataset_f_names=[a for i, a in enumerate(constants_cmap.DATASETS_F_NAMES)]

path_to_cache=os.path.join(constants_cmap.CACHE_GLOBAL_DIR, "datasets", "tcga")
n_input_layer=2000
all_datasets=[pd.read_csv(os.path.join(constants_cmap.DATASETS_DIR, ds), sep='\t', index_col=0) for ds in dataset_files]

i=0
all_datasets_normalized=[]
for df, name in zip(all_datasets, dataset_names):
    indices= df.index
    # df=pd.DataFrame(data=zscore(cur_ds), index=indices, columns=genes)
    # df=df.apply(lambda a: (a-min(a))/(max(a)-min(a)))
    # df = df.divide(df.max(axis=1), axis=0)

    all_datasets_normalized.append(df)

all_datasets=all_datasets_normalized

df_X_all = pd.concat(all_datasets, axis=0).astype(np.float)
df_X_all.dropna(axis=1)

genes= df_X_all.columns
indices= df_X_all.index
df_X_all = np.apply_along_axis(lambda a: (a-min(a))/(max(max(a)-min(a), 0.0001)), 0, zscore(df_X_all))
df_X_all=pd.DataFrame(df_X_all, columns=genes)
df_X_all=df_X_all.dropna(axis=1)
genes= df_X_all.columns
df_X_all=df_X_all.values
genes_i=rankdata(df_X_all.var(axis=0))>df_X_all.shape[1]-n_input_layer
genes=genes[genes_i]
df_X_all =df_X_all[:,genes_i]
df_y_all = [i for i, a in enumerate(all_datasets) for b in np.arange(a.shape[0])]
df_y_all_names = [dataset_names[i] for i, a in enumerate(all_datasets) for b in np.arange(a.shape[0])]
df_y_f = [dataset_f[i] for i, a in enumerate(all_datasets) for b in np.arange(a.shape[0])]
df_y_f_names = [dataset_f_names[i] for i, a in enumerate(all_datasets) for b in a]

start_i=0
for cur_ds, name in zip(all_datasets,dataset_names):

    try:
        os.makedirs(os.path.join(path_to_cache, name))
    except Exception:
        pass

    X=df_X_all[start_i:start_i+cur_ds.shape[0]]
    y=df_y_all[start_i:start_i+cur_ds.shape[0]]
    y_names=df_y_all_names[start_i:start_i+cur_ds.shape[0]]
    y_f=df_y_f[start_i:start_i+cur_ds.shape[0]]
    y_f_names=df_y_f_names[start_i:start_i+cur_ds.shape[0]]

    np.save(os.path.join(path_to_cache, name, "X.npy"), X)
    np.save(os.path.join(path_to_cache, name, "y.npy"), y)
    np.save(os.path.join(path_to_cache, name, "y_names.npy"), y_names)
    np.save(os.path.join(path_to_cache, name, "y_f.npy"), y_f)
    np.save(os.path.join(path_to_cache, name, "y_f_names.npy"), y_f_names)

    start_i+=cur_ds.shape[0]

np.save(os.path.join(path_to_cache, "genes.npy"), genes)


#DAY1 and Day2

# string pattern match
# first occurence
# pattern filter
# pattern split
# pattern replace
# patter  match

# program1

# \w [a-z][A-Z][0-9]

import re
str = 'qas man sun mop run'
e1 = re.search(r'm\w\w',str)
if e1:
    print('pattern find')
    print(e1.group())
else:
    print('patter not found')

# program 2
str2 = 'qas man sun mop run'
e2 = re.findall(r'm\w\w',str2)
#[] falsy value
if e2:
    print('pattern found')
    for item in e2:
        print(item)
else:
    print('pattern not found')

#program 3
str3 ='mas man sun mop run'
e3 = re.match(r'm\w\w',str3)
if e3:
    print('match found')
    print(e3.group())
else:
    print('match not found')

#program 4
str4 = "i am learning javascript"
e4 = re.sub(r'javascript','java',str4)
print(e4)

# program5
#\W non alphanumeric not [a-z][A-Z][0-9]
str5 = 'This ; is the "Core" python\'s book'
e5 =re.split(r'\W+',str5)
print(e5)

#-----------------------------------------------------
#\w  ===>  [a-z] [A-Z][0-9]
#\b     ===> " "
#\W     ===> not [a-z][A-Z][0-9]
#\d     ===> [0,9]

str6 = 'an apple a day keeps the doctor away'
e6 = re.findall(r'\ba[\w]*\b',str6)
print(e6)

# DAY#
import re
# [a-z A-Z 0-9]
str = 'an apple a day keeps doctor away'
e  = re.findall(r'a[\w]*',str)
print(e)

e2 = re.findall(r'\ba[\w]*\b',str)
print(e2)

#program2
str2 = 'The meeting will be conducted on 1st and 21st of every month'
e3 = re.findall(r'\d[\w]*',str2)
print(e3)

#program3
str2 = "one two three four five six seven 8 9 10"
e4 = re.search(r'\b\w{5}\b',str2)
print(e4.group())

e5 = re.findall(r'\b\w{5}\b',str2) #[a-zA-z0-9]
print(e5)

#program4 (four or more)
e6 = re.findall(r'\b\w{4,}\b',str2)
print(e6)

#program5(minimum3 and maximum5)

e6 = re.findall(r'\b\w{3,5}\b',str2)
print(e6)

#str2 = "one two three four five six seven 8 9 10"
e7 = re.findall(r'\b\d{1,}\b',str2)
print(e7)


# Display the following menu to the user:
# 1) Create a new file.
# 2) Display the file.
# 3) Add a new item to the file.
# Make a selection 1,2 or 3.

# Ask the user to enter 1, 2 or 3. If they select anything other than 1, 2 or 3 it should display a
# suitable error message. If they select 1, ask the user to enter a school
# subject and save it to a new file called “Subject.txt”. It should overwrite any existing file
# with a new file. If they select 2, display the contents of the
# “Subject.txt” file. If they select 3, ask the user to enter a new
# subject and save it to the file and then display the entire contents of the file.

print("1) Create a new file.")
print("2) Display the file.")
print("3) Add a new item to the file.")
print("Make a selection 1,2 or 3.")

userChoice=int(input("Enter 1, 2 or 3 : "))

if userChoice==1 or userChoice==2 or userChoice==3:
    if userChoice==1:
        subject=input("Enter school subject Names: ")
        file=open("Day_14/Subject.txt","w")
        file.write(subject)
        file.close()
    elif userChoice==2:
        file=open("Day_14/Subject.txt","r")
        print(file.read())
        file.close()
    else:
        pass
        newSubject=input("Enter New subject Names: ")
        file=open("Day_14/Subject.txt","a")
        file.write(newSubject)
        file.close()
        file=open("Day_14/Subject.txt","r")
        print(file.read())
        file.close()
else:
    raise Exception("Enter the Correct Number.")


from . import views
from django.urls import path,include
from django.conf.urls import url
from rest_framework import routers

router = routers.DefaultRouter()
router.register(r'mode', views.ModeViewSet)
router.register(r'state', views.StateViewSet)

urlpatterns=[
path('adminpage/',views.adminview,name='adminpage'),
path('emppage/',views.empview,name='emppage'),
path('register/',views.register,name='register'),
path('adminsignin/',views.adminsignin,name='adminsignin'),
path('empsignin/',views.empsignin,name='empsignin'),
path('lightreg/',views.lightreg,name='lightreg'),
path('areareg/',views.areareg,name='areareg'),
path('logout/',views.logoutview,name='logout'),
path('lightview/',views.lightview,name='lightview'),
path('automanual/',views.automanual,name='automanual'),
path('LowHigh/',views.LowHigh,name='LowHigh'),
path('report/',views.report,name='report'),
path('', include(router.urls)),
]


from numpy.lib.npyio import save
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import os
from tqdm import trange
import zipfile

def load_data(filedir):
    data_frame = pd.read_csv(filedir, header=0, parse_dates=True)  #names=['app_name', 'zone', 'time', 'value']
    data_frame = data_frame.drop(data_frame.columns[0], axis=1)
    grouped_data = list(data_frame.groupby(["app_name", "zone"]))
    # covariates = gen_covariates(data_frame.index, 3)
    all_data = []
    for i in range(len(grouped_data)):
        single_df = grouped_data[i][1].drop(labels=['app_name', 'zone'], axis=1).sort_values(by="time", ascending=True)
        times = pd.to_datetime(single_df.time)
        single_df['weekday'] = times.dt.dayofweek / 6
        single_df['hour'] = times.dt.hour / 23
        single_df['month'] = times.dt.month / 12
        temp_data = single_df.values[:, 1:]
        if (temp_data[:, 0] == 0).sum() / len(temp_data) > 0.2:
            continue

        all_data.append(temp_data)

    return all_data

def visualize(data, index, save_dir):
    os.makedirs(save_dir, exist_ok=True)
    for i in range(index):
        x = np.arange(len(data[i]))
        f = plt.figure()
        plt.plot(x, data[i][:, 0])
        f.savefig(os.path.join(save_dir, "visual_{}.png".format(i)))
        plt.close()

def split_seq(sequences, seq_length, slide_step, predict_length, save_dir):
    """Divide the training sequence into windows"""
    train_data = []
    test_data = []
    for seq_id in trange(len(sequences)):
        split_start = 0
        single_seq = sequences[seq_id][:, 0]
        single_covariate = sequences[seq_id][:, 1:]
        windows = (len(single_seq)-seq_length+slide_step) // slide_step
        count = 0
        train_count = int(0.97 * windows)
        while len(single_seq[split_start:]) > (seq_length + predict_length):
            seq_data = single_seq[split_start:(split_start+seq_length+predict_length-1)]
            single_data = np.zeros((seq_length+predict_length-1, 5))
            single_data[:, 0] = seq_data.copy()
            single_data[:, 1:4] = single_covariate[split_start:(split_start+seq_length+predict_length-1)]
            single_data[:, -1] = seq_id

            count += 1
            if count < train_count:
                train_data.append(single_data)
            else:
                test_data.append(single_data)
            split_start += slide_step

    os.makedirs(save_dir, exist_ok=True)

    train_data = np.array(train_data, dtype=np.float32)
    train_data, v = normalize(train_data, seq_length)
    save(train_data, v, save_dir + 'train')
    test_data = np.array(test_data, dtype=np.float32)
    test_data, v = normalize(test_data, seq_length)
    save(test_data, v, save_dir + 'test')

def normalize(inputs, seq_length):
    base_seq = inputs[:, :(seq_length-1), 0]
    nonzeros = (base_seq > 0).sum(1)
    v = base_seq.sum(1) / nonzeros
    v[v == 0] = 1
    inputs[:, :, 0] = inputs[:, :, 0] / v[:, None]

    return inputs, v

def save(data, v, save_dir):
    np.save(save_dir+'_data_flow.npy', data)
    np.save(save_dir+'_v_flow.npy', v)

def dezip(filedir):
    zip_file = zipfile.ZipFile(filedir)
    zip_list = zip_file.namelist()

    parent_dir = filedir.split('/')[0]
    for f in zip_list:
        zip_file.extract(f, parent_dir)

    zip_file.close()

if __name__ == '__main__':
    zip_dir = 'data/app_zone_rpc_hour_encrypted.zip'
    dezip(zip_dir)
    data_dir = 'data/app_zone_rpc_hour_encrypted.csv'
    data = load_data(data_dir)
    split_seq(data, 192, 24, 24, 'data/flow/')


import json
import os

directory = "media"
project_dir = os.path.split(os.getcwd())[0]
data = {}

for major_name in os.listdir(directory):
    major_path = os.path.join(directory, major_name)
    major = {}
    if os.path.isdir(major_path):

        for semester_name in os.listdir(major_path):
            semester_path = os.path.join(major_path, semester_name)
            semester = {}
            if os.path.isdir(semester_path):

                for module_name in os.listdir(semester_path):
                    module_path = os.path.join(semester_path, module_name)
                    module = {
                        "categories": {}
                    }
                    if os.path.isdir(module_path):

                        for file_name in os.listdir(module_path):
                            file_path = os.path.join(module_path, file_name)
                            if os.path.isfile(file_path):
                                if file_name.count(" - ") == 2:

                                    category = file_name.split(" - ")[1]

                                    if category in module["categories"]:
                                        module["categories"][category].append(file_name)
                                    else:
                                        module["categories"][category] = [file_name]
                                else:
                                    print(file_name)

                        if module != {}:
                            module["module_src_dir"] = module_path
                            semester[module_name] = module

                if semester != {}:
                    major[semester_name] = semester

        if major != {}:
            data[major_name] = major

json_data = json.dumps(data, indent=4)
with open(os.path.join(project_dir, "src", "data", "data.json"), "w") as json_file:
    json_file.write(json_data)


#题目描述
#一只青蛙一次可以跳上1级台阶，也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
# -*- coding:utf-8 -*-
class Solution:
    def jumpFloorII(self, number):
        # write code here
        a, b = 1 ,1

        for _ in range(number):

            a, b = b , a + b

        return a % 1000000007

#本题是动态规划 动态规划经典 f（n） = f(n-1) + f(n-2) + b


from django.urls import path

from rest_framework.urlpatterns import format_suffix_patterns

from .views import *

urlpatterns = [
    path("children/", ChildrenList.as_view(), name="case_list"),
    path("children/<int:pk>/", ChildDetails.as_view(), name="case_details"),
    path("anonymized-cases/", AnonymizedCaseList.as_view(), name="anonymized_case_list"),
    path("anonymized-case/<int:pk>/", AnonymizedCaseDetail.as_view(), name="anonymized_case_detail"),
    path("shared_organizations/", SharedOrganizationList.as_view(), name="shared_organization_list"),
    path("dashboard/", DashboardCaseList.as_view(), name="dashboard_case_list"),
    path("", CaseList.as_view(), name="case_list"),
    path("<int:pk>/", CaseDetails.as_view(), name="case_details"),
    path("social_media/", SocialMediaList.as_view(), name="social_media_list"),
    path("social_media/<int:pk>/", SocialMediaDetails.as_view(), name="social_media_details"),
    path("<int:pk>/volunteers/add/", AddCaseVolunteer.as_view(), name="add_case_volunteers"),
    path("<int:pk>/volunteers/", CaseVolunteerList.as_view(), name="case_volunteers"),
    path("active_volunteers/", ActiveVolunteerList.as_view(), name="active_volunteers"),
    path("number_of_places/", NumberOfPlacesList.as_view(), name="number_of_places"),
    path("<int:pk>/similar_cases/", SimilarCasesList.as_view(), name="similar_cases_list"),
    path("<int:pk>/linked_cases/", LinkedCasesList.as_view(), name="linked_cases_list"),
    path("<int:pk>/linked_cases/<int:linked_case_id>/", LinkedCaseDetails.as_view(), name="linked_case_details"),
    path("<int:pk>/volunteers/<int:volunteer_id>/", CaseVolunteerDetails.as_view(), name="case_volunteers"),
    path("<int:pk>/files/", FileList.as_view(), name="file_list"),
    path("<int:pk>/files/<int:file_id>/", FileDetails.as_view(), name="file_details"),
    path("<int:pk>/files/<int:file_id>/download-image/", DownloadImage.as_view(), name="image_download"),
    path("<int:pk>/files/<int:file_id>/download-file/", DownloadFile.as_view(), name="file_download"),
    path("<int:pk>/feed/", FeedList.as_view(), name="feed_list"),
    path("<int:pk>/feed/<int:feed_id>/", FeedDetails.as_view(), name="feed_details"),
    path("<int:pk>/close_case/", CloseCase.as_view(), name="close_case"),
    path("<int:pk>/deactivate_alerts/", DeactivateAlerts.as_view(), name="deactivate_alerts"),
    path("<int:pk>/archive_case/", ArchiveCase.as_view(), name="archive_case"),
    path("facility_cases/", FacilityCaseList.as_view(), name="facility_case_list"),
    path("facility_cases/<int:pk>/", FacilityCaseDetails.as_view(), name="facility_case_list"),
    path("facility_cases/<int:pk>/state/", FacilityCaseState.as_view(), name="case_state"),
    path("facility_cases/<int:pk>/report_missing/", FacilityCaseReportMissing.as_view(), name="case_state"),
]

urlpatterns = format_suffix_patterns(urlpatterns)


import configparser
import sys
import subprocess
import multiprocessing
import time
import glob
import os

import detect_and_track

class BulkProcessor(object):

    def __init__(self):

        num_nvidia_gpus = str(subprocess.check_output(["nvidia-smi", "-L"])).count('UUID')

        config = configparser.ConfigParser()
        config.sections()
        config.read('bulk_config.ini')

        self.gpu_ids = config.items( "Gpus" )
        self.configs = config.items( "Configs" )
        self.inputs = config.items( "Input" )
        self.num_instances = config.items( "Instances_per_gpu" )
        self.file_types = config.items( "File_type" )

        if len(self.gpu_ids) < 1 or len(self.gpu_ids) > num_nvidia_gpus:
        	sys.exit('Number of processors to use must be greater than 0 and smaller than gpus available')

        if len(self.gpu_ids) != len(self.configs):
        	sys.exit('len(self.gpu_ids) != len(self.configs) != len(self.inputs) != len(self.outputs)')

    def process(self, i, j, count, file):

        print("Starting process %d on GPU %d" % (j, int(self.gpu_ids[i][1])))

        try:
            process = detect_and_track.App(True,
                                           True,
                                           int(self.gpu_ids[i][1]),
                                           j,
                                           str(self.configs[i][1]),
                                           str(self.inputs[count][1]),
                                           str(file))
            process.start_bulk()
            print("Process on GPU %d stopped" % int(self.gpu_ids[i][1]))

        except Exception:

                e = sys.exc_info()[0] + '' + sys.exc_info()[1]
                print("Error: " + str(e))
                raise

if __name__ == '__main__':

    try:
        multiprocessing.set_start_method('spawn')
    except RuntimeError:
        pass

    bulk = BulkProcessor()

    proc_dict = {}
    count = 0

    for i in range(len(bulk.gpu_ids)):
        for j in range(int(bulk.num_instances[i][1])):

            glob_list = glob.glob(bulk.inputs[count][1] + '/**/*.' + bulk.file_types[i][1], recursive=True)
            procs = []

            for index, vid_file_name in enumerate(glob_list):
                file_name = os.path.splitext(vid_file_name)[0] + "_tracks.csv"
                if os.path.isfile(file_name) is not True:
                    p = multiprocessing.Process(target=bulk.process, args=(i, j, count, vid_file_name))
                    p.daemon = True
                    procs.append(p)

            if len(procs) > 0:
                proc_dict[str(i) + str(j)] = procs.copy()
                proc = procs[0]
                proc.start()
                time.sleep(30)

            count += 1

    while len(proc_dict) > 0:

        for key in list(proc_dict.keys()):
            procs = proc_dict[key]
            proc = procs[0]
            if not proc.is_alive():
                del procs[0]

                if len(procs) > 0:
                    proc_dict[key] = procs.copy()
                    next_proc = procs[0]
                    time.sleep(30)
                    next_proc.start()
                    time.sleep(30)
                else:
                    del proc_dict[key]

        time.sleep(1)


# -*- coding: utf-8 -*-

from datetime import datetime as dt
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from accidents.items import ASNDisasterRaw, AirportRaw
import re

RE_LISTING = r'.*/dblist\.php\?(Year)=(1920)$'
RE_RECORD = r'.*/record\.php\?id=((\d{8})-(\d+))$'
RE_AIRPORT = r'.*/airport\.php\?id=(\w+)$'

class ASNSpider(CrawlSpider):
    name = 'asn'
    allowed_domains = ['aviation-safety.net']
    start_urls = ['https://aviation-safety.net/database/']
    rules = [
        Rule(LinkExtractor(allow=RE_LISTING), callback='parse_list', follow=True),
        Rule(LinkExtractor(allow=RE_RECORD), callback='parse_record', follow=True),
        Rule(LinkExtractor(allow=RE_AIRPORT), callback='parse_airport', follow=False)
    ]

    @staticmethod
    def parse_list(response):
        m = re.match(RE_LISTING, response.url)
        print(f"Database listing WHERE '{m[1]}' = '{m[2]}'")

    @staticmethod
    def parse_airport(response):
        id = re.match(RE_AIRPORT, response.url)
        airportraw = AirportRaw()
        airportfields = response.xpath("//a[@name='general']/div[@class='infobox']//table[1]//tr")
        airportname = response.xpath("//a[@name='general']/div[@class='infobox']/span/text()")
        airportraw['id'] = id[1]
        airportraw['name'] = airportname
        airportraw['allfields'] = airportfields
        print(f"Airport listing WHERE 'id' = '{airportraw['id']}'")
        return airportraw

    @staticmethod
    def parse_record(response):
        id = re.match(RE_RECORD, response.url)
        disasterraw = ASNDisasterRaw()
        disasterfields = response.xpath("//div[@class='innertube']//table[1]//tr")
        disasterraw['id'] = id[1]
        disasterraw['date'] = dt.strptime(id[2], '%Y%m%d')
        disasterraw['allfields'] = disasterfields
        print(f"Accident listing WHERE 'id' = '{disasterraw['id']}'")
        return disasterraw


#/********************************************** NASH PROP ***********************************************************/
# Nash Prop is build on top fglib and Network X open source libraries in   python.
## We reused data strcutures for the variable Nodes and Factor Nodes with modifications to support the algorithm
## make_graph() was used for testing the algorithm for manual modifications in the links of the graphs to understand the behavior

import numpy as np
## Build parameters for NashProp
from random import choice
import matplotlib.pyplot as plt
import networkx as nx
from fglib import rv,graphs,inference
from fglib import nodes
from fglib.utils import draw_message,draw

#### A note on the Data Structure ####################
#### As in VNODE class : supports an additional parameter Projection matrix P .--- > contains a matrix of  size tau X tau
#### FNode class : is now initalized with the play off matrix between.
# F1 be a factor connexting edges x1 ,x2 ,x3 .. it is initialized with a payoff matrix of size 2^3 where actions of each plaers remain binary
#
def make_graph():
    G = graphs.FactorGraph()
    x1 = nodes.VNode('x1',rv.Discrete,P)
    x2 = nodes.VNode('x2',rv.Discrete,P)
    x3 = nodes.VNode('x3',rv.Discrete,P)
    x4 = nodes.VNode('x4', rv.Discrete, P)
    x5 = nodes.VNode('x5', rv.Discrete, P)
    dist_fa = np.array([[20,10],[20,80]])
    dist_fb = np.array([[40, 30], [30, 50]])
    dist_fc =  np.array([[30, 50], [40, 30]])
    dist_fd = np.array([[70,10],[10,20]])
    dist_fe = np.array([[120, 50], [80, 100]])
    dist_ff = np.array([[40,100],[70,30]])
    dist_fg = np.array([[20, 10], [50, 30]])
    fa = nodes.FNode('f1', rv.Discrete(dist_fa, x1,x2))
    fb = nodes.FNode('f2', rv.Discrete(dist_fb, x2,x3))
    fc = nodes.FNode('f3', rv.Discrete(dist_fc, x3,x4 ))
    fd = nodes.FNode('f4', rv.Discrete(dist_fd, x4,x1))
    fe = nodes.FNode('f5', rv.Discrete(dist_fe, x4,x5))
    ff = nodes.FNode('f6', rv.Discrete(dist_ff, x5,x3))
    fg = nodes.FNode('f7', rv.Discrete(dist_fg, x1, x3))

    G.set_nodes([x1, x2, x3,x4,x5])
    G.set_nodes([fa,fb, fc,fd,fe,ff,fg])
    # Add edges to factor graph
    G.set_edge(x1, fa)
    G.set_edge(fa, x2)
    G.set_edge(x2, fb)
    G.set_edge(fb, x3)
    G.set_edge(x3, fc)
    G.set_edge(fc, x4)
    G.set_edge(x4, fd)
    G.set_edge(fd, x1)
    G.set_edge(fe, x4)
    G.set_edge(x5, fe)
    G.set_edge(ff,x5)
    G.set_edge(x3, ff)
    G.set_edge(fg,x1)
    G.set_edge(x3, fg)
    draw(G,nx.spectral_layout(G))
    plt.show()
    inference.nash_propagation(G,20,epsilon,1/30,[x1,x2,x3,x4,x5],order = [fa,fb,fc,fd,fe,ff,fg,x1,x2,x3,x4,x5])

### Make arbit graph provides support to generate very large graphs by inputing
####  num_nodes --- Number of Players of the game
#### graph_mat ----  this provides a list of tuple where each tuple is a link in the graph .
def make_arbit_graph(num_nodes,graph_mat):
    # Create factor graph
    fg = graphs.FactorGraph()
    # Create variable nodes
    X  = {}
    F=  {}
    dist_fa = np.zeros([len(graph_mat),2,2])
    for k in range(len(graph_mat)):
        dist_fa[k] = np.random.rand(2,2)
    for i in range(num_nodes):
        X['x'+str(i+1)] = nodes.VNode("x"+str(i+1),rv.Discrete,P)

    fg.set_nodes(X.values())
    for i in range(len(graph_mat)):
        edge = graph_mat[i]
        nodez = [X["x" + str(edge[m])] for m in range(len(edge))]
        F['f'+str(i+1)] = nodes.FNode("f"+str(i+1),rv.Discrete(dist_fa[i],*nodez))
    fg.set_nodes(F.values())

    for i in range(len(graph_mat)):
        node_name = graph_mat[i]
        fg.set_edge(  X['x'+str(node_name[0])], F['f'+str(i+1)])
        fg.set_edge( F['f' + str(i+1)],X['x' + str(node_name[1])])

    print([attr["type"].value for (n, attr) in fg.nodes(data=True)])
    draw(fg,nx.spectral_layout(fg))
    plt.show()
    print([*F.values(), *X.values()])
    #belief = inference.loopy_belief_propagation(fg, 1000, [*X.values()], order=[*F.values(), *X.values()])
    grid = inference.nash_propagation(fg, 10, epsilon, 1 / 10, [*X.values()],
                               order=[*F.values(), *X.values()])
    ## COmpute the mixed strategy
    prob =[]
    prob_i=0
    print(len(grid.keys()))
    length =0
    for i in grid.keys():
        if(np.where(grid[str(i)]==1)!=[]):
            length = length+1

        prob_i = np.where(grid[str(i)]==1)
        print('new')
        print(prob_i)

    ## Now assign values to the factors ?

Num_Of_Players = 50
max_degree = 5
epsilon = 0.26 ## To be tuned for every experiement
tau = epsilon/(np.power(2,(max_degree+1)*max_degree*np.log(max_degree)))
# Initialize tables for each Node in the graph
fg = graphs.FactorGraph()
P = np.ones([10,10])

## Below create the links of the matrix
Mat_link=[]
for i in range(1,9):
    Mat_link.append((i, i % 9 + 1))
    Mat_link.append((i, np.random.randint(i+1,10)))

print(Mat_link)
#make_arbit_graph(10,graph_mat=Mat_link)
make_graph()