"""
A class for managing a list of image pairs stored on disk which also handles keeping track of processed and raw versions on each image
"""

from base import *
from .common import *

from pysideline import *

from PySide import QtGui, QtCore
from PySide.QtCore import Qt

import uuid
import os
import re

from . import processing

class ThumbnailJob(processing.ProcessingJob):

	priority = 100

	def __init__(self,app,image,cameraIndex,size,pm=None,withPreview=False):
		self.app = app
		self.image = image
		self.cameraIndex = cameraIndex
		self.size = size
		self.withPreview = withPreview
		self.pm = pm

	def execute(self):

		if self.image[self.cameraIndex].thumbnail.exists():
			self.scaledPM = QtGui.QPixmap()
			self.scaledPM.load(self.image[self.cameraIndex].thumbnail.getFilePath())
			return

		if not self.pm:
			self.pm = QtGui.QPixmap(self.image[self.cameraIndex].raw.getFilePath())
		s = self.pm.size()
		s.scale(self.size[0], self.size[1],Qt.KeepAspectRatio)
		self.scaledPM = self.pm.scaled(s,transformMode=Qt.SmoothTransformation)
		self.scaledPM.save(self.image[self.cameraIndex].thumbnail.getFilePath())

	def oncompletion(self):
		self.image.thumbnail.updateImage(self.scaledPM,cameraIndex=self.cameraIndex)
		if self.withPreview:
			preview = self.app.previews[self.cameraIndex]
			preview.loadFromData('raw',self.pm)

class CapturedImageFile(object):
	"""
	A basic image file object supporting the simple manipulations required for files in the image list

	@ivar path: the path to the directory in which the image is stored
	@ivar filename: the currently configured filename for the image (excluding path)
	"""

	def __init__(self,path,filename):
		self.path = path
		self.filename = filename
		self.ext = os.path.splitext(filename)[-1]

	def write(self,data):
		f = open(self.getFilePath(),'wb')
		f.write(data)
		f.close()

	def delete(self):
		if self.exists():
			os.remove(self.getFilePath())

	def rename(self,filename):
		filename = os.path.splitext(filename)[0] + self.ext
		exists = self.exists()
		oldFilePath = self.getFilePath()
		self.filename = filename
		newFilePath = self.getFilePath()
		if newFilePath == oldFilePath:
			return
		if exists:
			os.rename(oldFilePath,newFilePath)

	def exists(self):
		return os.path.exists(self.getFilePath())

	def getFilePath(self):
		return os.path.join(self.path,self.filename)

class CapturedImage(object):
	"""
	An image that can (optionally) have raw and processed versions stored on disk

	@ivar raw: a L{CapturedImageFile} object for the raw image
	@ivar processed: a L{CapturedImageFile} object for the raw image (the object if present even if no such file is ever created)
	"""

	def __init__(self,path,filename):
		self.raw = CapturedImageFile(path,filename)
		self.processed = CapturedImageFile(self.calcProcessedPath(path),filename)
		self.thumbnail = CapturedImageFile(self.calcThumbnailPath(path),filename)
		self.auxiliary = []

	@property
	def files(self):
		return [self.raw,self.processed,self.thumbnail] + self.auxiliary

	def delete(self):
		for f in self.files:
			f.delete()

	def rename(self,filename):
		for f in self.files:
			f.rename(filename)

	def addAuxFromFile(self,old):
		ext = os.path.splitext(old)[-1]
		rawBase = os.path.splitext(self.raw.getFilePath())[0]
		new = rawBase + ext
		path,filename = os.path.split(new)
		if os.path.exists(new):
			raise Exception('Cannot add new auxiliary file %s from %s because the new filename already exists'%(new,old))
		os.rename(old,new)
		self.auxiliary.append(CapturedImageFile(path,filename))

	def calcProcessedPath(self,path):
		return os.path.join(path,'processed')

	def calcThumbnailPath(self,path):
		return os.path.join(path,'thumbnails')

class CapturedImageBase(object):
	"""
	Common base for both kinds of image pair (the one that's actually a pair and the one that only looks like a pair!)
	"""

class CapturedImagePair(CapturedImageBase):
	"""
	An PAIR of images (left and right) that can (optionally) also have raw and processed versions stored on disk

	@ivar left: a L{CapturedImageFile} object for the left image
	@ivar right: a L{CapturedImageFile} object for the right image (the object if present even if no such file is ever created)
	"""

	def __init__(self,path,filename):
		self.uid = uuid.uuid1().hex
		base,ext = os.path.splitext(filename)
		self.left = CapturedImage(path,'%sL%s'%(base,ext))
		self.right = CapturedImage(path,'%sR%s'%(base,ext))

	def __getitem__(self,k):
		if k == 1:
			return self.left
		elif k == 2:
			return self.right
		else:
			raise KeyError(k)

	def delete(self):
		self.left.delete()
		self.right.delete()

	def rename(self,filename):
		base,ext = os.path.splitext(filename)
		self.left.rename('%sL%s'%(base,ext))
		self.right.rename('%sR%s'%(base,ext))

class CapturedImageSingle(CapturedImageBase):
	"""
	An SINGLE image to use in place of pairs where pairs are not wanted

	@ivar image: a L{CapturedImageFile} object for the underlying images
	"""

	def __init__(self,path,filename):
		self.uid = uuid.uuid1().hex
		self.image = CapturedImage(path,filename)

	def __getitem__(self,k):
		if k == 1:
			return self.image
		else:
			raise KeyError(k)

	def delete(self):
		self.image.delete()

	def rename(self,filename):
		self.image.rename(filename)

class CapturedImageManager(object):

	PAT_FILE_DOUBLE = re.compile(r'(page[0-9]+)([lr])\.(jpg|jpeg)',re.I)
	PAT_FILE_SINGLE = re.compile(r'(page[0-9]+)()\.(jpg|jpeg)',re.I)

	sideToCameraIndex = {'l':1,'L':1,'R':2,'r':2,'':1,None:1}

	def __init__(self,path,view,solo=False):
		self.path = path
		self._images = []
		self.view = view
		self.solo = solo
		self.selected = None

		if self.solo:
			self.cameraIndices = [1]
		else:
			self.cameraIndices = [1,2]

		pPath = os.path.join(self.path,'processed')
		if not os.path.exists(pPath):
			os.mkdir(pPath)

		tPath = os.path.join(self.path,'thumbnails')
		if not os.path.exists(tPath):
			os.mkdir(tPath)

	def fillFromDirectory(self,progressCallback=None):

		names = os.listdir(self.path)
		names.sort()

		if self.solo:
			pat = self.PAT_FILE_SINGLE
		else:
			pat = self.PAT_FILE_DOUBLE

		names = [name for name in names if pat.match(name)]
		total = len(names)
		done = 0
		for name in names:
			m = pat.match(name)
			side = m.group(2)
			baseName = '%s.%s'%(m.group(1),m.group(3))
			self.addFromExistingLocalFile(filename=name,baseFilename=baseName,cameraIndex=self.sideToCameraIndex[side])
			done += 1
			progressCallback(total,done)
		self.renameChanged()

	def new(self,filename):
		if self.solo:
			image = CapturedImageSingle(path=self.path,filename=filename)
		else:
			image = CapturedImagePair(path=self.path,filename=filename)
		self._images.append(image)
		image.thumbnail = self.view.new(uid=image.uid)
		image.thumbnail.image = image
		image.thumbnail.relabel()
		return image

	def addFromData(self,data=None,pm=None,cameraIndex=1,withPreview=False):

		if pm is None:
			pm = QtGui.QPixmap()
			pm.loadFromData(data)

		ndx = 0
		for ndx,image in enumerate(self._images):
			if not image[cameraIndex].raw.exists():
				break
		else:
			filename = self.calcBaseFilename(len(self._images))
			image = self.new(filename)

		pm.save(image[cameraIndex].raw.getFilePath())

		self.view.app.processingQueue.put(
			ThumbnailJob(
				app = self.view.app,
				image = image,
				cameraIndex = cameraIndex,
				size = (self.view.thumbnailWidth,self.view.thumbnailHeight),
				pm = pm,
				withPreview = withPreview,
			)
		)

		return image

	def addFromExistingLocalFile(self,filename,baseFilename,cameraIndex=1,withPreview=False):

		filepath = os.path.join(self.path,filename)

		for image in self._images:
			if not image[cameraIndex].raw.exists():
				break
			if image[cameraIndex].raw.filename == filename:
				break
		else:
			image = self.new(baseFilename)

		self.view.app.processingQueue.put(
			ThumbnailJob(
				app = self.view.app,
				image = image,
				cameraIndex = cameraIndex,
				size = (self.view.thumbnailWidth,self.view.thumbnailHeight),
				withPreview = withPreview
			)
		)

		return image

	def normalise(self,v):
		if isinstance(v,CapturedImageBase):
			image = v
			index = self._images.index(v)
		else:
			index = v
			image = self._images[v]
		return index,image

	def move(self,fromLocation,toLocation):
		fromIndex,fromImage = self.normalise(fromLocation)
		toIndex,toImage = self.normalise(toLocation)
		del(self._images[fromIndex])
		self._images.insert(toIndex,fromImage)
		self.view.move(fromImage.thumbnail,toIndex)
		self.renameChanged()

	def renameChanged(self):
		changed = []
		for ndx,image in enumerate(self._images):
			for cameraIndex in self.cameraIndices:
				if image[cameraIndex].raw.filename and image[cameraIndex].raw.filename != self.calcFilename(ndx,cameraIndex=cameraIndex):
					changed.append(image)
					break
		for ndx,image in enumerate(changed):
			image.rename('temp%04d.jpg'%(ndx+1))
		for ndx,image in enumerate(changed):
			image.thumbnail.relabel()
			for cameraIndex in self.cameraIndices:
				image[cameraIndex].rename(self.calcFilename(self._images.index(image),cameraIndex=cameraIndex))

	def delete(self,fromLocation):
		index,image = self.normalise(fromLocation)
		del(self._images[index])
		image.delete()
		self.view.remove(image.thumbnail)
		for ndx,i in enumerate(self._images[index:]):
			i.rename(self.calcBaseFilename(ndx+index))
			i.thumbnail.relabel()

	def select(self,image):
		self.selected = image
		if image is None:
			for cameraIndex in self.view.app.cameraIndices:
				self.view.app.previews[cameraIndex].clear()
		else:
			self.view.app.processingQueue.put(processing.ImageLoadJob(self.view.app,image))

	def calcFilename(self,ndx,cameraIndex=1):
		if self.solo:
			assert cameraIndex == 1
			return 'page%04d.jpg'%(ndx+1)
		else:
			assert cameraIndex in (1,2)
			if cameraIndex == 1:
				return 'page%04dL.jpg'%(ndx+1)
			else:
				return 'page%04dR.jpg'%(ndx+1)

	def calcBaseFilename(self,ndx):
		return 'page%04d.jpg'%(ndx+1)

	def getLabel(self,location):
		index,image = self.normalise(location)
		return 'page %d'%(index + 1)


import time
import pytest
from selenium.webdriver.chrome import webdriver
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service

from pages.choise_complekt_page import Choise_complekt_page
from pages.finish_cart_page import Finish_cart_page
from pages.main_page import Main_page
from pages.samsung_galaxy_Z_flip_4_page import Samsung_galaxy_Z_flip_4_page
from pages.samsung_page import Samsung_page

@pytest.mark.run(order=2)
def test_buy_products_1(set_up, set_group):
    # options = webdriver.ChromeOptions()
    options = webdriver.ChromeOptions()
    options.add_experimental_option('excludeSwitches', ['enable-logging'])
    options.add_experimental_option("detach", True)
    g = Service('C:\\Users\\Nasty\\PycharmProjects\\resourse\\chromedriver-win64\\chromedriver-win64\\chromedriver.exe')
    driver = webdriver.Chrome(options=options, service=g)

    print("Start Test 1")

    mp = Main_page(driver)
    mp.choise_product()
    sp = Samsung_page(driver)
    sp.f_product()
    gf = Samsung_galaxy_Z_flip_4_page(driver)
    gf.galaxy_product()
    time.sleep(10)
    cc = Choise_complekt_page(driver)
    cc.complekt_product()
    fp = Finish_cart_page(driver)
    fp.finish_product()

    print("Finish Test 1")
    time.sleep(10)
    driver.quit()

@pytest.mark.run(order=1)
def test_buy_products_2(set_up, set_group):
    # options = webdriver.ChromeOptions()
    options = webdriver.ChromeOptions()
    options.add_experimental_option('excludeSwitches', ['enable-logging'])
    options.add_experimental_option("detach", True)
    g = Service('C:\\Users\\Nasty\\PycharmProjects\\resourse\\chromedriver-win64\\chromedriver-win64\\chromedriver.exe')
    driver = webdriver.Chrome(options=options, service=g)

    print("Start Test 2")

    mp = Main_page(driver)
    mp.choise_product()
    sp = Samsung_page(driver)
    sp.f_product()
    gf = Samsung_galaxy_Z_flip_4_page(driver)
    gf.galaxy_product_2()
    time.sleep(10)
    cc = Choise_complekt_page(driver)
    cc.complekt_product_2()
    fp = Finish_cart_page(driver)
    fp.finish_product_2()

    print("Finish Test 2")
    time.sleep(10)
    driver.quit()


import os
from binance.client import Client
from make_trades import make_trade

api_key = os.getenv('BINANCE_API_KEY')
api_secret = os.getenv('BINANCE_API_SECRET')
client = Client(api_key, api_secret)

def execute_trade():
    decision = make_trade()
    if decision == 'buy':
        order = client.create_order(
            symbol='BTCUSDT',
            side=Client.SIDE_BUY,
            type=Client.ORDER_TYPE_MARKET,
            quantity=0.001
        )
        print("Bought 0.001 BTC")
    elif decision == 'sell':
        order = client.create_order(
            symbol='BTCUSDT',
            side=Client.SIDE_SELL,
            type=Client.ORDER_TYPE_MARKET,
            quantity=0.001
        )
        print("Sold 0.001 BTC")
    else:
        print("No trade made")

if __name__ == '__main__':
    execute_trade()


import os
import sys
import time
import urllib2
import urlparse
from curses import wrapper

####################
## Utility classes

class HumanReadable:

    def __init__(self):
        print('HumanReadable')

    def size(self, bytes=0):
        kbyte = 1024
        mbyte = (kbyte**2)
        gbyte = (kbyte**3)
        tbyte = (kbyte**4)
        pbyte = (kbyte**5)
        ebyte = (kbyte**6)
        zbyte = (kbyte**7)

        if bytes < kbyte:
            retv = '%dB' % int(bytes)
            return '%9s' % retv
        elif bytes >= kbyte and bytes < mbyte:
            retv = '%04.02fKB' % (float(bytes) / float(kbyte))
            return '%9s' % retv
        elif bytes >= mbyte and bytes < gbyte:
            retv = '%04.02fMB' % (float(bytes) / float(mbyte))
            return '%9s' % retv
        elif bytes >= gbyte and bytes < tbyte:
            retv = '%04.02fGB' % (float(bytes) / float(gbyte))
            return '%9s' % retv
        elif bytes >= tbyte and bytes < pbyte:
            retv = '%04.02fTB' % (float(bytes) / float(tbyte))
            return '%9s' % retv
        elif bytes >= pbyte and bytes < ebyte:
            retv = '%04.02fPB' % (float(bytes) / float(pbyte))
            return '%9s' % retv
        elif bytes >= ebyte and bytes < zbyte:
            retv = '%04.02fEB' % (float(bytes) / float(ebyte))
            return '%9s' % retv
        else:
            retv = '%04.02fZB' % (float(bytes) / float(zbyte))
            return '%9s' % retv

    def time(self, seconds=0):
        # These are for convenience
        minute = 60
        hour   = (minute**2)
        day    = (hour*24)
        week   = (day*7)
        month  = (week*4)
        year   = (month*12)

        secs, mins, hrs, days, weeks, months, years = 0, 0, 0, 0, 0, 0, 0

        if seconds > year:
            years   = (seconds / year)
            tmp     = (seconds % year)
            seconds = tmp
        if seconds > month:
            months  = (seconds / month)
            tmp     = (seconds % month)
            seconds = tmp
        if seconds > week:
            weeks   = (seconds / week)
            tmp     = (seconds % week)
            seconds = tmp
        if seconds > day:
            days    = (seconds / day)
            tmp     = (seconds % day)
            seconds = tmp
        if seconds > hour:
            hrs     = (seconds / hour)
            tmp     = (seconds % hour)
            seconds = tmp
        if seconds > minute:
            mins    = (seconds / minute)
            secs    = (seconds % minute)
        if seconds < minute:
            secs   = seconds

        if years != 0:
            return '%4dy%2dm%1dw%1dd %02d:%02d:%02d' % (
                years, months, weeks, days, hrs, mins, secs
            )
        if months != 0:
            return '%2dm%1dw%1dd %02d:%02d:%02d' % (
                months, weeks, days, hrs, mins, secs
            )
        if weeks != 0:
            return '%1dw%1dd %02d:%02d:%02d' % (
                weeks, days, hrs, mins, secs
            )
        if days != 0:
            return '%1dd %02d:%02d:%02d' % (days, hrs, mins, secs)

        return '%02d:%02d:%02d' % (hrs, mins, secs)

class Output(HumanReadable):
    def __init__(self):
        self.display_flag  = True
        self.display_count = None

        # This is the most portable way (across POSIX systems) to get
        # our screen size that I can find, so, screw windows. Yeah.
        wrapper(self.__setmaxyx)

    def __setmaxyx(self, stdscr):
        (self.max_y, self.max_x) = stdscr.getmaxyx()

    def display(self, inTot=None, inSz=None, outSz=None, start_time=None):
        try:
            a = self.lastupdate
        except AttributeError:
            self.lastupdate = (time.time() - 5)

        if inTot:
            remain  = (inTot - outSz)
            percent = (float(outSz) / float(inTot))
            elapsed = (time.time() - start_time)
            speed   = (float(outSz) / float(elapsed))
            eta     = int(remain / speed)

            # now build out the majority of the display string
            linest  = '%s in %s @ %s/sec [' % (
                self.size(outSz),
                self.time(elapsed),
                self.size(speed)
            )
            lineend = '] %3d%% eta %s' % (
                int(percent * 100),
                self.time(eta)
            )

            # now figure out how many hashmarks we need
            curlen  = (len(linest)+len(lineend))
            hashlen = (self.max_x - curlen)
            hashes  = int(hashlen * percent)
            padding = (hashlen - hashes)

            # and put the line together
            line    = '%s%s%s%s' % (
                linest,
                '#'*hashes,
                ' '*padding,
                lineend
            )

        else:
            line = '%s in %s @ %s/sec' % (
                self.size(outSz),
                self.time(time.time() - start_time),
                self.size((outSz / (time.time() - start_time)))
            )

        if (time.time() - self.lastupdate) >= 1 and not self.quiet:
            sys.stderr.write('%s\r' % line)
            sys.stderr.flush()
            self.lastupdate = time.time()

################
## I/O classes

class Io:
    def _validateTarget(self, target=None):
        # First lets see if this is a legit path/file
        if os.path.exists(target):
            return True
        result = urlparse.urlparse(target)
        if result.scheme in ['http', 'https', 'ftp', 'ftps', 'scp', 'sftp', 'file']:
            return True
        return False

    def close(self):
        self.target.close()

    def read(self, bsize=40960):
        return self.target.read(bsize)

    def write(self, data):
        return self.target.write(data)

    def seek(self, pos=None):
        if pos:
            return self.target.seek(pos)

class FileIo(Io):
    def __init__(self, target=None, mode=None):
        if not self._validateTarget(target):
            mode = 'w+'
        self.target = open(target, mode)
        if self.target.name != '/dev/stdout' and self.target.name != '/dev/stdin':
            self.size  = os.stat(self.target.name).st_size
            self.pipe  = False
        else:
            self.size  = None
            self.pipe  = True

class FifoIo(FileIo):
    pass

class HttpIo(Io):
    def __init__(self, target=None):
        self._validateTarget(target)
        self.target = urllib2.urlopen(target)

class FtpIo(HttpIo):
    pass

class ScpIo(Io):
    def __init__(self, bsize=10240, skip=0):
        pass

###################
## Transfer class

class Transfer(Output):
    def __init__(
            self,
            src=None,
            dst=None,
            tsize=None,
            bsize=40960,
            count=None,
            skip=None,
            quiet=False
    ):
        Output.__init__(self)
        self.src   = src
        self.dst   = dst
        self.bsize = bsize
        self.tsize = tsize
        self.count = count # TODO: Impliment
        self.skip  = skip  # TODO: Impliment
        self.quiet = quiet
        # Lets set our total size for display purposes
        if self.count:
            self.src.size = (self.bsize * self.count)
        # if we have set our total_size via an argument, lets go ahead, and set that
        try:
            if self.tsize:
                self.src.size = self.tsize
            elif not self.tsize and not os.path.isfile(self.src.target.name):
                self.src.size = -1
        except AttributeError:
            self.src.size = int(self.src.target.headers['content-length'])
        except:
            self.src.size = -1

    def start(self):
        blocks = 0
        totsze = 0

        try:
            st     = time.time()
            buff   = self.src.read(self.bsize)
            while buff:
                if totsze <= self.src.size or self.src.size == -1:
                    self.dst.write(buff)
                    blocks += 1
                    totsze += len(buff)
                    if self.src.size != -1:
                        self.display(self.src.size, totsze, totsze, st)
                    else:
                        self.display(None, totsze, totsze, st)
                    buff    = self.src.read(self.bsize)
                else:
                    buff    = None
            time.sleep(1)
            self.display(self.src.size, self.src.size, self.src.size, st)
            print
        except KeyboardInterrupt:
            print
            sys.exit(1)

#######################
## Main program entry

if __name__ == '__main__':
    # defaults
    iput  = FileIo('/dev/stdin', 'r')
    oput  = FileIo('/dev/stdout', 'a')
    ts    = None
    bs    = 40960 # 40KB
    count = None
    skip  = None
    quiet = False

    # help documentation
    usage = '''
Usage: %s <arg> <arg> ...

Arguments:

  if=<arg>      Set the input source
     /dev/stdin        # Default
     /path/to/file     # Set a path to a file or fifo
     (f|ht)tp(s)://uri # Use a remote location via http(s)/ftp(s)          (INPUT ONLY)
     scp://u@h:f       # Use SCP to get the file                           (TODO)

  of=<arg>      Set the output destination
     /dev/stdout       # Default
     /path/to/file     # Output to a file, device, fifo, socket file, etc.

  bs=<arg>      Specify the blocksize (in bytes only: Default 40960)
  ts=<arg>      Specify the total size in bytes (for use with pipes)
  count=<arg>   Specify how many blocks to transfer
  seek=<arg>    Seek <arg> number of blocks(bs) before reading data.
  quiet         Specify no progress output.
  help          Show this help screen.

''' % os.path.basename(sys.argv[0])

    # Parse out our arguments
    for arg in sys.argv:
        # Boolean args
        if arg == 'help':
            print(usage)
            sys.exit(0)
        if arg == 'quiet':
            quiet = True
        # Option args
        if arg.find('=') != -1:
            # this is a arg=opt style option, let's see which one.
            (key, val) = arg.split('=')
            if key == 'if': # input, see if it's a file
                if os.path.isfile(val):
                    iput = FileIo(val, 'r')
                else:
                    if val.find('http'):
                        iput = HttpIo(val)
                        oput = FileIo('./%s' % os.path.basename(val))
                    elif val.find('ftp'):
                        iput = FtpIo(val)
                        oput = FileIo('./%s' % os.path.basename(val))

            if key == 'of': # output, see if it's a file
                oput = FileIo(val, 'w+')
            if key == 'bs':
                bs    = int(val)
            if key == 'ts':
                ts    = int(val)
            if key == 'count':
                count = int(val)
            if key == 'skip':
                skip  = int(val)

    obj = Transfer(iput, oput, ts, bs, count, skip, quiet)
    obj.start()


# File: nn.py
#
from math import sqrt

import torch
from torch.nn import Module, Parameter, init

ACTIVATIONS = {'tanh': torch.nn.Tanh, 'relu': torch.nn.ReLU}

class LNMLP(torch.nn.Module):

    def __init__(self, input_size, hidden_sizes, output_size, activation='relu', gain=1.0,
                 ln=False):
        self._hidden_sizes = hidden_sizes
        self._gain = gain
        self._ln = ln
        super().__init__()
        if len(hidden_sizes) > 0:
            activation = ACTIVATIONS[activation]
            layers = [torch.nn.Linear(input_size, hidden_sizes[0])]
            layers.append(activation())
            if ln:
                layers.append(torch.nn.LayerNorm(hidden_sizes[0]))

            for i in range(len(hidden_sizes) - 1):
                layers.append(torch.nn.Linear(hidden_sizes[i], hidden_sizes[i + 1]))
                layers.append(activation())
                if ln:
                    layers.append(torch.nn.LayerNorm(hidden_sizes[i + 1]))

            layers.append(torch.nn.Linear(hidden_sizes[-1], output_size))
        else:
            layers = [torch.nn.Linear(input_size, output_size)]

        self._layers = layers
        self.mlp = torch.nn.Sequential(*layers)
        self.reset_params(gain=gain)

    def forward(self, inp):
        return self.mlp(inp)

    def reset_params(self, gain=1.0):
        self.apply(lambda x: weights_init_mlp(x, gain=gain))

def weights_init_mlp(m, gain=1.0):
    classname = m.__class__.__name__
    if classname.find('Linear') != -1:
        init_normc_(m.weight.data, gain)
        if m.bias is not None:
            m.bias.data.fill_(0)

def init_normc_(weight, gain=1.0):
    weight.normal_(0, 1)
    weight *= gain / torch.sqrt(weight.pow(2).sum(1, keepdim=True))


from django.contrib import admin

# Register your models here.

from .models import City, OWM, OWMForecast, Yahoo, YahooForecast

class OWMAdmin(admin.ModelAdmin):
    model = OWM
    #list_display = ('wine', 'rating', 'user_name', 'comment', 'pub_date')
    list_filter = ['req_date', 'name', 'city']
    #search_fields = ['comment']

class OWMForecastAdmin(admin.ModelAdmin):
    model = OWMForecast
    #list_display = ('wine', 'rating', 'user_name', 'comment', 'pub_date')
    #list_filter = ['owm']
    search_fields = ['forecast_text']

class YahooAdmin(admin.ModelAdmin):
    model = Yahoo
    #list_display = ('wine', 'rating', 'user_name', 'comment', 'pub_date')
    list_filter = ['req_date', 'name', 'city']
    #search_fields = ['comment']

class YahooForecastAdmin(admin.ModelAdmin):
    model = YahooForecast
    #list_display = ('wine', 'rating', 'user_name', 'comment', 'pub_date')
    #list_filter = ['owm']
    search_fields = ['forecast_text']

admin.site.register(City)
admin.site.register(OWM, OWMAdmin)
admin.site.register(OWMForecast, OWMForecastAdmin)
admin.site.register(Yahoo, YahooAdmin)
admin.site.register(YahooForecast, YahooForecastAdmin)


from django import forms
from .models import URL_Short
from django.utils.translation import ugettext_lazy as _

class UrlForm(forms.ModelForm):

    class Meta:
        model = URL_Short
        fields = ('short_url', 'long_url')
        labels = {
            'short_url': _('Token'),
        }
        widgets = {
            'long_url': forms.TextInput(attrs=({'class': 'url-input'})),
            'short_url': forms.TextInput(attrs=({'class': 'url-input'}))
        }

    def __init__(self, *args, **kwargs):
        super(UrlForm, self).__init__(*args, **kwargs)
        self.fields['short_url'].required = False


from fastapi import APIRouter, HTTPException

from back.crud.setting import (
    AIRFLOW_SETTING_PATH,
    is_airflow_setting,
    is_setting,
    update_airflow_settings,
    update_settings,
)
from back.dependency.security import api_security
from back.init.setting import init_settings_with_examples
from back.model.scope import ScopeEnum
from back.settings import (
    DEFAULT_AIRFLOW_SETTING_NAME,
    DEFAULT_SETTING_NAME,
    Setting,
    setting,
)

router = APIRouter(prefix="/system")

@router.get(
    "",
    response_model=Setting,
    dependencies=[api_security([ScopeEnum.setting_system_get.value])],
)
def get_settings() -> Setting:
    return setting

@router.post(
    "",
    response_model=Setting,
    dependencies=[api_security([ScopeEnum.setting_system_post.value])],
)
def post_settings(setting: Setting) -> Setting:
    if is_setting():
        HTTPException(
            status_code=409, detail=f"`{DEFAULT_SETTING_NAME}` already exists."
        )
    setting = init_settings_with_examples(setting)
    update_settings(setting)
    return setting

@router.put(
    "",
    response_model=Setting,
    dependencies=[api_security([ScopeEnum.setting_system_put.value])],
)
def put_settings(setting: Setting) -> Setting:
    update_settings(setting, force=True)
    return setting

@router.get(
    "/airflow",
    response_model=Setting,
    dependencies=[api_security([ScopeEnum.setting_system_airflow_get.value])],
)
def get_airflow_settings() -> Setting:
    setting = Setting(_env_file=str(AIRFLOW_SETTING_PATH))
    return setting

@router.post(
    "/airflow",
    response_model=Setting,
    dependencies=[api_security([ScopeEnum.setting_system_airflow_post.value])],
)
def post_airflow_settings(setting: Setting) -> Setting:
    if is_airflow_setting():
        HTTPException(
            status_code=409, detail=f"`{DEFAULT_AIRFLOW_SETTING_NAME}` already exists."
        )
    setting = init_settings_with_examples(setting)
    update_airflow_settings(setting)
    return setting

@router.put(
    "/airflow",
    response_model=Setting,
    dependencies=[api_security([ScopeEnum.setting_system_airflow_put.value])],
)
def put_airflow_settings(setting: Setting) -> Setting:
    update_airflow_settings(setting)
    return setting


import cv2
import numpy as np

img = cv2.imread("img.png")

gris = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

_,valor = cv2.threshold(gris, 50, 255, cv2.THRESH_BINARY)

kernel = np.ones((3,3), np.uint8)
figura = cv2.morphologyEx(valor, cv2.MORPH_CLOSE, kernel)
contorno, _ = cv2.findContours(
    figura,
    cv2.RETR_EXTERNAL,
    cv2.CHAIN_APPROX_SIMPLE)

lista_contornos = []

for index in range(len(contorno)):
    area = cv2.contourArea(contorno[index])
    if area > 500:
        objecto = contorno[index]
        lista_contornos.append(objecto)

cv2.drawContours(img, contorno[index], -1, (0,255,0), 5)
cv2.namedWindow("original", cv2.WINDOW_NORMAL)
cv2.imshow("original", img)

cv2.waitKey()
cv2.destroyAllWindows()


# 个人主页功能
__author__ = 'zhangxp'
import tornado.web
from controller.base import BaseHandler
from tornado import gen

# 发帖子
class PublishHandler(BaseHandler):
    @tornado.web.asynchronous
    @gen.coroutine
    def get(self, *args, **kwargs):
        cursor = self.db.post_category.find()
        colls = []
        i = 0
        while (yield cursor.fetch_next):
                coll = cursor.next_object()
                colls.append({})
                for k,v in coll.items():
                    colls[i][k]=v
                print(colls)
                i+=1
        self.render("Publish.html",Message="欢迎发帖",colls = colls)
    @tornado.web.asynchronous
    @gen.coroutine
    def post(self, *args, **kwargs):
        username = self.get_current_user()
        print(username)
        articleTitle = self.get_body_argument("articleName")
        print(articleTitle)
        articleText = self.get_body_argument("editor")
        print(articleText)
        articleCategory = self.get_body_argument("articleCategory")
        print(articleCategory)
        # "sername":发表用户姓名
        # "ArticleTitle":文章标题
        # "ArticleText":文章内容
        # "ZambisCount":赞次数
        # "CollectionCount":收藏次数
        # "Comment":[{"name":"","text":""}]
        yield self.db.user_publish.insert({"username":username,
                                           "ArticleTile":articleTitle,
                                           "ArticleText":articleText,
                                           "ArticleCategory":articleCategory,
                                           "ZambisCount":0,
                                           "CollectionCount":0,
                                           "Comment":[{}],
                                           "PublishTime":self.get_current_time()})
        self.render("Publish.html",Message = "发表成功!",colls = self.category_colls)


# -*- coding: utf-8 -*-
import json
import time
import requests
import hashlib
from common                 import config
from bs4                    import BeautifulSoup
from datetime               import datetime
from handle.mongo           import mongo
from updates.upload         import Upload
from handle.datamanager  import Datamanager
from handle.replace         import _replace

class FlixFling():
    def __init__(self, ott_site_uid, ott_site_country, type):
        self._config                = config()['ott_sites'][ott_site_uid]
        self._created_at            = time.strftime("%Y-%m-%d")
        self.mongo                  = mongo()
        self._platform_code         = self._config['countries'][ott_site_country]
        self.titanScraping          = config()['mongo']['collections']['scraping']
        self.titanScrapingEpisodios = config()['mongo']['collections']['episode']
        self.sesion                 = requests.session()
        self.skippedEpis            = 0
        self.skippedTitles          = 0

        if type == 'scraping':
            self._scraping()

        if type == 'return':
            '''
            Retorna a la Ultima Fecha
            '''

            params = {"PlatformCode" : self._platform_code}
            lastItem = self.mongo.lastCretedAt(self.titanScraping, params)
            if lastItem.count() > 0:
                for lastContent in lastItem:
                    self._created_at = lastContent['CreatedAt']

            self._scraping()

    def _scraping(self):
        listaCategorias = [
            "hotflix",
            "subscriber%20picks",
            "animated",
            "classic",
            "concerts",
            "drama",
            "comedy",
            "fitness",
            "action%20&%20adventure",
            "holiday",
            "horror",
            "lgbt",
            "music",
            "musical",
            "mystery",
            "romance",
            "scifi",
            "special%20interests",
            "sports",
            "thriller",
            "western"
        ]

        listPayload = []
        listDBMovie = Datamanager._getListDB(self,self.titanScraping)
        for x in range(0,len(listaCategorias)):
            soup = Datamanager._getSoup(self,"https://www.flixfling.com/browse/{}".format(listaCategorias[x]))

            for item in soup.findAll('div',{'class':'movie_item col-sm-2 col-xs-4'}):
                listDirector = []
                listCast = []
                listGenre = []

                link = item.find('a').get('href')
                contenidoId = str(link).split("/")[2]
                link = "https://www.flixfling.com{}".format(link)
                soupMovie = Datamanager._getSoup(self,link)

                if soupMovie.find('span',{'class':'btn_premium_button'}):
                    buyPrice = None
                    rentPrice = None

                    rentButton = soupMovie.find('span',{'class':'rentBtnPrice'})
                    if rentButton:
                        rentPrice = float(rentButton.text.strip().replace('FROM','').replace(' ','').replace('$',''))

                    buyButton = soupMovie.find('span',{'class':'buyBtnPrice'})
                    if buyButton:
                        buyPrice = float(buyButton.text.strip().replace('FROM','').replace(' ','').replace('$',''))

                    packages = [
                        {
                            'Type' : 'transaction-vod',
                            'RentPrice': rentPrice,
                            'BuyPrice': buyPrice,
                            'Currency': 'USD'
                        }
                    ]

                    if not buyPrice and not rentPrice:
                        continue

                else:
                    packages = [
                        {
                            'Type' : 'subscription-vod'
                        }
                    ]

                print(packages)

                try:
                    title = soupMovie.find('a',{'itemprop':'url'}).find('span').text
                except:
                    continue

                try:
                    duracion = int(int(soupMovie.find('meta',{'property':'video:duration'}).get('content'))/60)
                except:
                    duracion = None

                try:
                    anio = int(str(soupMovie.find('span',{'itemprop':'releasedEvent'}).text)[0:4])
                except:
                    anio = None

                try:
                    int(duracion)
                except:
                    duracion = None

                descripcion = str(soupMovie.find('meta',{'name':'twitter:description'}).get('content'))

                for x in soupMovie.findAll('a',{'itemprop':'director'}):
                    listDirector.append(x.text)

                for x in soupMovie.findAll('a',{'itemprop':'actor'}):
                    listCast.append(x.text)

                for x in soupMovie.findAll('span',{'itemprop':'genre'}):
                    listGenre.append(x.text)

                imageLink = soupMovie.find('img',{'itemprop':'image'}).get('src')
                images = []
                images.append(imageLink)

                payload = {
                'PlatformCode'      : self._platform_code,
                'Id'                : contenidoId,
                'Type'              : 'movie',
                'Title'             : title,
                'CleanTitle'        : _replace(title),
                'OriginalTitle'     : None,
                'Year'              : anio,
                'Duration'          : duracion,
                'Deeplinks'         :  {
                    'Web'     : link,
                    'Android' : None,
                    'iOS'     : None
                },
                'Synopsis'          : descripcion,
                'Rating'            : None,
                'Provider'          : None,
                'Genres'            : listGenre,
                'Cast'              : listCast,
                'Directors'         : listDirector,
                'Availability'      : None,
                'Download'          : None,
                'IsOriginal'        : None,
                'IsAdult'           : None,
                'Image'             : images,
                'Country'           : None,
                'Packages'          : packages,
                'Timestamp'         : datetime.now().isoformat(),
                'CreatedAt'         : self._created_at
                }

                Datamanager._checkDBandAppend(self,payload,listDBMovie,listPayload)

        Datamanager._insertIntoDB(self,listPayload, self.titanScraping)
        '''
        Upload
        '''
        self.sesion.close()
        Upload(self._platform_code, self._created_at, testing=True, has_episodes=False)


import tkinter
import tkinter.ttk
import getpass
import uuid
import os
import time
import traceback

# XXX The file will be obsolete by tomorrow.

HOLD = 'Logos Storage'

################################################################################

class Logos(tkinter.ttk.Frame):

    @classmethod
    def main(cls):
        # Create and configure the root.
        tkinter.NoDefaultRoot()
        root = tkinter.Tk()
        root.title('Logos')
        root.minsize(200, 200)
        # Create Logos and setup for resizing.
        view = cls(root)
        view.grid(row=0, column=0, sticky=tkinter.NSEW)
        root.grid_rowconfigure(0, weight=1)
        root.grid_columnconfigure(0, weight=1)
        # Enter the main GUI event loop.
        root.mainloop()

    ########################################################################

    # These are all instance methods.

    def __init__(self, master):
        super().__init__(master)
        # Get the username and save list of found files.
        self.__user = getpass.getuser()
        self.__dirlist = set()
        # Create widgets.
        self.__log = tkinter.Text(self)
        self.__bar = tkinter.ttk.Scrollbar(self, orient=tkinter.VERTICAL,
                                           command=self.__log.yview)
        self.__ent = tkinter.ttk.Entry(self, cursor='xterm')
        # Configure widgets.
        self.__log.configure(state=tkinter.DISABLED, wrap=tkinter.WORD,
                             yscrollcommand=self.__bar.set)
        # Create binding.
        self.__ent.bind('<Return>', self.create_message)
        # Position widgets.
        self.__log.grid(row=0, column=0, sticky=tkinter.NSEW)
        self.__bar.grid(row=0, column=1, sticky=tkinter.NS)
        self.__ent.grid(row=1, column=0, columnspan=2, sticky=tkinter.EW)
        # Configure resizing.
        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)
        # Focus entry.
        self.__ent.focus_set()
        # Schedule message discovery.
        self.after_idle(self.get_messages)

    def get_messages(self):
        # Schedule method for one second from now.
        self.after(1000, self.get_messages)
        # Get a list of new files.
        files = set(os.listdir(HOLD))
        diff = files - self.__dirlist
        self.__dirlist = files
        # Load each new message.
        messages = []
        for name in diff:
            path = os.path.join(HOLD, name)
            try:
                with open(path) as file:
                    user, clock, message = self.load_message(file)
                messages.append((user, float(clock), message))
            except:
                # Print any error for debugging purposes.
                traceback.print_exc()
                os.remove(path)
        # Sort the messages according to time and display them.
        messages.sort(key=lambda m: m[1])
        for m in messages:
            self.display_message(m[0], m[2])

    def display_message(self, user, text):
        # Put a new message on the screen.
        self.__log['state'] = tkinter.NORMAL
        message = '{} - {}\n'.format(user, text)
        self.__log.insert('1.0', message)
        self.__log['state'] = tkinter.DISABLED

    def create_message(self, event):
        # Get the text, clear it, show on screen, and create file.
        text = event.widget.get()
        event.widget.delete(0, tkinter.END)
        self.display_message(self.__user, text)
        self.save_file(text)

    def save_file(self, message):
        # Save message in HOLD using a UUID for the name.
        name = uuid.uuid1().hex
        path = os.path.join(HOLD, name)
        self.__dirlist.add(name)
        with open(path, 'w') as file:
            self.save_message(file, message)

    ########################################################################

    # If one the format is changed, both methods must be altered.

    def load_message(self, file):
        # Read the file, splitting on newline, and get first three lines.
        user, clock, message = file.read().split('\n')[:3]
        return user, clock, message

    def save_message(self, file, message):
        # Save username, timestamp, and message on separate lines.
        print(self.__user, file=file)
        print(time.time(), file=file)
        print(message, file=file, end='')

################################################################################

if __name__ == '__main__':
    Logos.main()


# (1) https://openaccess.thecvf.com/content_ECCV_2018/papers/Rahaf_Aljundi_Memory_Aware_Synapses_ECCV_2018_paper.pdf
# (2) https://openaccess.thecvf.com/content_CVPR_2019/papers/Aljundi_Task-Free_Continual_Learning_CVPR_2019_paper.pdf

import torch
from tfm import ImgData
from torch.nn.functional import binary_cross_entropy_with_logits as bce
import torch.nn as nn

def compute_importance(model:nn.Module,
                      data:ImgData,
                      device:str,
                      normalize:bool = True) -> dict:
  """
  Importance estimation as described in the paper
  https://openaccess.thecvf.com/content_ECCV_2018/papers/Rahaf_Aljundi_Memory_Aware_Synapses_ECCV_2018_paper.pdf

  """

  grads = {name:torch.zeros(param.shape,device=device) \
        for name,param in model.named_parameters() if param.requires_grad}
  N = len(data)

  for X,y in data:
    X = X.unsqueeze(0).to(device)
    model.eval()
    output = torch.sigmoid(model(X)) # compute output of learned function
    model.zero_grad() # reset gradient to zero
    output.backward() # compute gradient of output
    # Gradients are accumulated over the given data points to obtain importance weight Ωij for parameter θij
    for name,param in model.named_parameters():
      if param.requires_grad:
        grads[name] += param.grad.abs() # update gradient for each param

  # average gradient is obtained for each parameter
  omega = {name:sum_grad/N for name,sum_grad in grads.items()} # calculate gradient mean

  # vector normalization with l2 norm
  if normalize:
    omega_norm = torch.sqrt(sum([mean_grad.pow(2).sum() for name,mean_grad in omega.items()]))
    omega = {name:mean_grad/omega_norm for name,mean_grad in omega.items()}

  return omega

def update_importance(prev_omega,
                      model:nn.Module,
                      data:ImgData,
                      device:str,
                      normalize:bool = True) -> dict:
  """
  Importance updating as described in the paper
  https://openaccess.thecvf.com/content_CVPR_2019/papers/Aljundi_Task-Free_Continual_Learning_CVPR_2019_paper.pdf

  """
  # compute Ω for new domain
  curr_omega = compute_importance(model,data,device,normalize=True)
  # cumulative moving average
  for name in curr_omega.keys():
    curr_omega[name] = (prev_omega[name] + curr_omega[name])/2

    return curr_omega

class MASLoss(nn.Module):
  """
  Complete loss function as described in the paper
  https://openaccess.thecvf.com/content_ECCV_2018/papers/Rahaf_Aljundi_Memory_Aware_Synapses_ECCV_2018_paper.pdf

  """
  def __init__(self,
              model:nn.Module,
              lambd:float,
              importance:dict,
              loss_function:nn.Module) -> None:

    super().__init__()
    self.model = model
    self.old_params = {name:param.data.detach().clone() for name,param in model.named_parameters() if param.requires_grad}
    self.lambd = lambd # regularization hyper-parameter λ
    self.omega = importance
    self.loss = loss_function

  def forward(self,
             input:torch.Tensor,
             target:torch.Tensor) -> torch.Tensor:

    reg = 0. # regularization term
    for name,param in self.model.named_parameters():
      if param.requires_grad:
        reg += (self.omega[name]*(param - self.old_params[name])**2).sum()

    return self.loss(input,target) + self.lambd*reg


import numpy as np
from pyevolver.ctrnn import BrainCTRNN
import matplotlib.pyplot as plt
from tqdm import tqdm

def run_ctrnn_and_get_states(brain, run_duration, input_func=None, plot=False):
    # simulate_plot_output brain
    step_size = brain.step_size
    num_steps = int(run_duration/step_size)
    num_states = len(brain.states)
    states_series = np.zeros((num_steps, num_states))
    state_derivative_series = np.zeros((num_steps, num_states))
    time_series = np.arange(step_size, run_duration+step_size, step_size)
    for step in range(num_steps):
        states_series[step] = brain.get_state()
        if input_func is not None:
            brain.input = input_func(brain.num_neurons)
        brain.euler_step()
        state_derivative_series[step] = brain.dy_dt
        step += 1

    # plot output
    if plot:
        for i in range(brain.num_neurons):
            plt.plot(np.arange(0,run_duration+step_size,step_size),states_series[:,i])
        plt.xlabel('Time')
        plt.ylabel('Neuron states')
        plt.show()
    return time_series, states_series, state_derivative_series

def plot_phase_space_traj():
    """ Plot the phase portrait
    We'll use matplotlib quiver function, which wants as arguments the grid of x and y coordinates,
    and the derivatives of these coordinates.
    In the plot we see the locations of stable and unstable equilibria,
    and can eyeball the trajectories that the system will take through
    the state space by following the arrows.
    """
    # Define the sample space (plotting ranges)
    # ymin = np.amin(net_history)
    # ymax = np.amax(net_history)
    ymin = -5
    ymax = 5
    num_steps = 10
    y1 = np.linspace(ymin, ymax, num_steps)
    y2 = np.linspace(ymin, ymax, num_steps)

    plt.figure(figsize=(10,6))

    pbar = tqdm(total=num_steps**2)
    input_func = np.zeros

    for i in y1:
        for j in y2:
            # print(i,j)
            pbar.update()
            brain = BrainCTRNN(
                num_neurons=2,
                step_size=0.01,
                states = np.array([i, j]),
                taus=np.array([1.0, 1.0]),
                gains=np.array([1.0, 1.0]),
                biases=np.array([-2.75, -1.75]),
                weights=np.array([4.5, -1, 1, 4.5]) # will be converted to np.array([[4.5, -1], [1, 4.5]])
            )
            # brain.input = np.array([1.,1.])
            brain.compute_output()
            # input_func = np.zeros
            _, states_series, _ = run_ctrnn_and_get_states(brain, 100, input_func)
            plt.plot(states_series[:, 0], states_series[:, 1], color='r')
            plt.scatter(states_series[0][0], states_series[0][1], color='orange', zorder=1)

    plt.xlabel('y1', fontsize=14)
    plt.ylabel('y2', fontsize=14)
    plt.title('Multi-trajectory for agent brain', fontsize=16)
    plt.show()

def test_control_phase_plot():
    from control.phaseplot import phase_plot

    state_ctrnn_brain = {} # state_tuple -> state_derivative_series of ctrnn_brain
    input_func = np.zeros

    step_size = 0.1
    run_duration = 1
    num_steps = int(run_duration/step_size)

    time_series = np.arange(0, run_duration, step_size)

    xmin = -5
    xmax = 5
    xsteps = 10

    x0 = np.linspace(xmin, xmax, xsteps)
    x1 = np.linspace(xmin, xmax, xsteps)

    def get_ctrnn_brain_dydt(state_tuple, t):
        if type(state_tuple) == np.ndarray:
            state_tuple = tuple(state_tuple.tolist())
        if state_tuple in state_ctrnn_brain:
            result =  state_ctrnn_brain[state_tuple]
        else:
            ctrnn = \
                BrainCTRNN(
                    num_neurons=2,
                    step_size=step_size,
                    states = np.array(state_tuple),
                    taus=np.array([1.0, 1.0]),
                    gains=np.array([1.0, 1.0]),
                    biases=np.array([-2.75, -1.75]),
                    weights=np.array([4.5, -1, 1, 4.5]), # will be converted to np.array([[4.5, -1], [1, 4.5]])
                )
            ctrnn.compute_output()
            _, _, state_derivative_series = run_ctrnn_and_get_states(ctrnn, run_duration, input_func)
            result = state_ctrnn_brain[state_tuple] = state_derivative_series
        idx = (np.abs(time_series - t)).argmin()
        return result[idx]

    phase_plot(
        get_ctrnn_brain_dydt,
        [-5, 5, 10],
        [-5, 5, 10],
        # X0=[(i,j) for i in x0 for j in x1],
        # scale=5,
        T=time_series,
        # timepts=[0,1]
    )
    plt.show()

if __name__ == "__main__":
    # run_test_params(250)
    # run_test_random(2,250)
    # run_test_random(5, 250)
    # plot_phase_space_traj()
    test_control_phase_plot()


from collections import namedtuple
from random import choice

import os

import scipy.spatial.distance
import spotipy
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

import pickle

TrackInfo = namedtuple('TrackInfo', ['id', 'track_href', 'danceability', 'energy', 'loudness', 'speechiness',
                                     'acousticness', 'instrumentalness', 'liveness', 'valence', 'tempo'])

PARAMETERS_DNN = ['danceability', 'energy', 'loudness', 'speechiness', 'acousticness',
                  'instrumentalness', 'liveness', 'valence']

train = True
training_epochs = 40000
hidden_layer_size = 150
display_times = 10
display_step = 2000
evaluation_step = 500
batch_size = 50

def load_data():
    with open('tracks.db', 'rb') as file:
        tracks = pickle.load(file)

    with open('playlists.db', 'rb') as file:
        playlists = pickle.load(file)

    return tracks, playlists

def generate_training_data(playlists, songs):
    x = []
    y = []

    for playlist in filter(lambda pl: len(pl) > 1, playlists.values()):
        for i in range(len(playlist) - 1):
            id = playlist[i]

            song = [songs[id]._asdict()[category] for category in PARAMETERS_DNN]
            next_song = [songs[id]._asdict()[category] for category in PARAMETERS_DNN]

            x.append(song)
            y.append(next_song)

    return np.array(x), np.array(y)

def get_closest_song(prediction, songs):
    nodes = np.asarray(songs)
    dist_2 = scipy.spatial.distance.cdist(np.array([prediction]), nodes, 'euclidean')
    return np.argmin(dist_2), np.min(dist_2)

input = tf.placeholder(tf.float32, shape=(None, len(PARAMETERS_DNN)))
correct_output = tf.placeholder(tf.float32, shape=(None, len(PARAMETERS_DNN)))

weight_1 = tf.Variable(tf.random_normal(shape=(len(PARAMETERS_DNN), hidden_layer_size)))
bias_1 = tf.Variable(tf.random_normal(shape=(1, hidden_layer_size)))

layer1 = tf.matmul(input, weight_1) + bias_1

h_weight_2 = tf.Variable(tf.random_normal(shape=(hidden_layer_size, hidden_layer_size)))
h_bias_2 = tf.Variable(tf.random_normal(shape=(1, hidden_layer_size)))

layer2 = tf.matmul(layer1, h_weight_2) + h_bias_2

h_weight_3 = tf.Variable(tf.random_normal(shape=(hidden_layer_size, len(PARAMETERS_DNN))))
h_bias_3 = tf.Variable(tf.random_normal(shape=(1, len(PARAMETERS_DNN))))

layer3 = tf.matmul(layer2, h_weight_3) + h_bias_3

loss = tf.div(tf.reduce_sum(tf.nn.l2_loss(layer3 - correct_output)), batch_size)
optimizer = tf.train.AdamOptimizer(learning_rate=0.0005, beta1=0.9, beta2=0.9999).minimize(loss)

init = tf.global_variables_initializer()
tracks, playlists = load_data()
train_x, train_y = generate_training_data(playlists, tracks)

with tf.Session() as sess:
    saver = tf.train.Saver()
    best_loss = float('inf')

    sess.run(init)

    if train:
        datapoints = []

        for epoch in range(training_epochs):
            random_ids = np.random.random_integers(0, len(train_x)-1, 50)

            training_input = train_x[random_ids]
            training_output = train_y[random_ids]

            sess.run(optimizer, feed_dict={input: training_input, correct_output: training_output})

            if epoch % evaluation_step == 0:
                cost = sess.run(loss, feed_dict={input: train_x, correct_output: train_y})
                datapoints.append(cost)

                if cost < best_loss:
                    saver.save(sess, os.getcwd() + '/best_model.ckpt')
                    best_loss = cost

            if epoch % display_step == 0:
                cost = sess.run(loss, feed_dict={input: train_x, correct_output: train_y})

                print('Epoch: {0}, loss: {1:.9f}'.format(epoch, cost))

        print('Optimization finished! Best loss: {}'.format(best_loss))

        plt.semilogy(datapoints)
        plt.show()

    spotify = spotipy.Spotify()
    saver.restore(sess, os.getcwd() + '/best_model.ckpt')
    tracks_modified = [[track._asdict()[category] for category in PARAMETERS_DNN] for track in tracks.values()]

    songs = choice(list(playlists.values()))
    previous_song = tracks[choice(songs)]
    print('Starting to create playlist out of {}'.format(spotify.track(previous_song.id)['name']))

    previous_songs = []

    for i in range(display_times):
        network_input = [previous_song._asdict()[category] for category in PARAMETERS_DNN]
        previous_songs.append(network_input)

        pred = sess.run(layer3, feed_dict={input: [network_input]})
        predicted_song, cost = get_closest_song(np.squeeze(pred), [x for x in tracks_modified if x not in previous_songs])

        track_key = list(tracks.keys())[np.asscalar(predicted_song)]

        predicted = spotify.track(track_key)
        previous_song = tracks[track_key]

        print('{}: {} (loss {:.9}) - {}'.format(i+1, predicted['name'], cost, predicted['external_urls']['spotify']))


"""
label encoder
"""
import pandas as pd
from sklearn.preprocessing import LabelEncoder

base = pd.read_csv('../data/kaggle_car/autos_tratado_sem_valores_null.csv', encoding='ISO-8859-1') # esse encod é pq tem acentos

"""
 0   price                359291 non-null  int64
 1   abtest               359291 non-null  object 0
 2   vehicleType          359291 non-null  object 1
 3   yearOfRegistration   359291 non-null  int64  2
 4   gearbox              359291 non-null  object 3
 5   powerPS              359291 non-null  int64  4
 6   model                359291 non-null  object 5
 7   kilometer            359291 non-null  int64  6
 8   monthOfRegistration  359291 non-null  int64  7
 9   fuelType             359291 non-null  object 8
 10  brand                359291 non-null  object 9
 11  notRepairedDamage    359291 non-null  object 10
"""

# a coluna 0 é o preço então vamos usar da coluna 1 a 11

previsores = base.iloc[:, 1:13].values # caracteristicas
preco_real = base.iloc[:, 0].values # respostas

"""
o LabelEncoder será usado para transformar texto em numeros para nossa classificação
"""

labelencoder_previsores = LabelEncoder()

# todas as colunas como object listadas do base.info()
print('ANTES\n',previsores[0])
previsores[:,0] = labelencoder_previsores.fit_transform(previsores[:,0])
previsores[:,1] = labelencoder_previsores.fit_transform(previsores[:,1])
previsores[:,3] = labelencoder_previsores.fit_transform(previsores[:,3])
previsores[:,5] = labelencoder_previsores.fit_transform(previsores[:,5])
previsores[:,8] = labelencoder_previsores.fit_transform(previsores[:,8])
previsores[:,9] = labelencoder_previsores.fit_transform(previsores[:,9])
previsores[:,10] = labelencoder_previsores.fit_transform(previsores[:,10])

print('DEPOIS\n',previsores[0])


"""RPA generator views"""

from django import forms
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.views.generic import DetailView
from django.views.generic.edit import DeleteView, CreateView
from django.urls import reverse, reverse_lazy
from django.views.generic.list import ListView
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.views.generic import TemplateView
from django.shortcuts import redirect, get_object_or_404

from django_weasyprint import WeasyTemplateResponseMixin

from extra_views import ModelFormSetView

from .models import (
    Rpa,
    ProcessingActivityName,
    DataController,
    JointController,
    DataProtectionOfficer,
    InternallyResponsibleDept,
    CategoryOfPersonalData,
    CategoriesOfPersonalDataOrigin,
    PurposeAndLegalBasis,
    DataSubject,
    TimeLimitForErasure,
    CategoryOfRecipients,
    TransferToThirdCountry,
    AccessGroup,
    Transparency,
    DataProcessor,
    PrivacyImpactAssessment,
    TOM,
    RPAAnnex,
)

from .forms import (
    RpaForm,
    ProcessingActivityNameForm,
    DataControllerForm,
    JointControllerForm,
    DataProtectionOfficerForm,
    InternallyResponsibleDeptForm,
    CategoryOfPersonalDataForm,
    CategoryOfPersonalDataFormSet,
    CategoriesOfPersonalDataOriginForm,
    PurposeAndLegalBasisForm,
    DataSubjectForm,
    TimeLimitForErasureForm,
    TimeLimitForErasureFormSet,
    CategoryOfRecipientsForm,
    CategoryOfRecipientsFormSet,
    TransferToThirdCountryForm,
    AccessGroupForm,
    AccessGroupFormSet,
    TransparencyForm,
    DataProcessorForm,
    PrivacyImpactAssessmentForm,
    TOMForm,
    RPAAnnexForm,
    RPAAnnexFormSet,
)

from .forms import (
    CpdModelMultipleChoiceField,
    CPD_CHOICES,
)

class RPAGenUserPassesMixin(UserPassesTestMixin):
    def test_func(self):
        """Override test_func() method to ensure proper access control
        over given Rpa object
        """
        is_allowed = False
        rpaslug = self.kwargs.get("slug")
        rpa = get_object_or_404(Rpa, slug=rpaslug)
        current_user = rpa.user or None
        if (
            self.request.user.is_staff
            and self.request.user.groups.filter(name="dpo").exists()
        ):
            is_allowed = True
        if self.request.user.is_superuser:
            is_allowed = True
        if self.request.user and self.request.user == current_user:
            is_allowed = True
        return is_allowed

class RPAHintsView(LoginRequiredMixin, TemplateView):
    """User information about records of processing activities (RPAs)
    and how to create them; view is accessible to authenticated users
    only
    """

    template_name = "rpa/rpa_hints.html"

class MyRPAsView(LoginRequiredMixin, ListView):
    """Allow authenticated users to view a list of their own RPAs, if
    any
    """

    model = Rpa
    template_name = "rpa/rpa_view.html"
    context_object_name = "rpa"
    paginate_by = 12

    def get_queryset(self):
        return Rpa.objects.filter(user=self.request.user).order_by("slug")

class AllRPAsView(LoginRequiredMixin, UserPassesTestMixin, ListView):
    """List of all RPAs in the database; view is accessible only to
    staff users that are also members of group "dpo" (and superusers)
    """

    model = Rpa
    template_name = "rpa/rpa_view_all.html"
    context_object_name = "rpa"
    # paginate_by = 12

    def test_func(self):
        is_allowed = False
        if (
            self.request.user.is_staff
            and self.request.user.groups.filter(name="dpo").exists()
        ):
            is_allowed = True
        if self.request.user.is_superuser:
            is_allowed = True
        return is_allowed

    def get_queryset(self):
        return Rpa.objects.all

class RPADetailView(LoginRequiredMixin, RPAGenUserPassesMixin, DetailView):
    """HTML document view of a single RPA
    (RPAGenUserPassesMixin-restricted)
    """

    model = Rpa
    template_name = "rpa/rpa_htmltemplate.html"
    context_object_name = "rpa"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        rpanm_dpoc = self.object.rpa_names.values_list("dpo_comment").exclude(
            dpo_comment__exact=""
        )
        dcon_dpoc = self.object.datacontrollers.values_list("dcon_dpo_comment").exclude(
            dcon_dpo_comment__exact=""
        )
        jcon_dpoc = self.object.jointcontrollers.values_list(
            "jcon_dpo_comment"
        ).exclude(jcon_dpo_comment__exact="")
        dpo_dpoc = self.object.dpos.values_list("dpo_dpo_comment").exclude(
            dpo_dpo_comment__exact=""
        )
        ird_dpoc = self.object.internally_resp_depts.values_list(
            "ird_dpo_comment"
        ).exclude(ird_dpo_comment__exact="")
        cpd_dpoc = self.object.datacategories.values_list("cpd_dpo_comment").exclude(
            cpd_dpo_comment__exact=""
        )
        cpdo_dpoc = self.object.datacategories_origin.values_list(
            "cpdo_dpo_comment"
        ).exclude(cpdo_dpo_comment__exact="")
        plb_dpoc = self.object.purposes_legalbases.values_list(
            "plb_dpo_comment"
        ).exclude(plb_dpo_comment__exact="")
        dsub_dpoc = self.object.datasubjects.values_list("dsub_dpo_comment").exclude(
            dsub_dpo_comment__exact=""
        )
        tle_dpoc = self.object.timelimits_erasure.values_list(
            "tle_dpo_comment"
        ).exclude(tle_dpo_comment__exact="")
        crec_dpoc = self.object.categories_of_rec.values_list(
            "crec_dpo_comment"
        ).exclude(crec_dpo_comment__exact="")
        ttc_dpoc = self.object.transfers_to_3rdc.values_list("ttc_dpo_comment").exclude(
            ttc_dpo_comment__exact=""
        )
        agrp_dpoc = self.object.accessgroups.values_list("agrp_dpo_comment").exclude(
            agrp_dpo_comment__exact=""
        )
        tran_dpoc = self.object.transparencies.values_list("tran_dpo_comment").exclude(
            tran_dpo_comment__exact=""
        )
        dpro_dpoc = self.object.dataprocessors.values_list("dpro_dpo_comment").exclude(
            dpro_dpo_comment__exact=""
        )
        pia_dpoc = self.object.pias.values_list("pia_dpo_comment").exclude(
            pia_dpo_comment__exact=""
        )
        tom_dpoc = self.object.toms.values_list("tom_dpo_comment").exclude(
            tom_dpo_comment__exact=""
        )
        annex_dpoc = self.object.rpa_annexes.values_list("annex_dpo_comment").exclude(
            annex_dpo_comment__exact=""
        )
        context["rpanm_dpoc"] = True if rpanm_dpoc else False
        context["dcon_dpoc"] = True if dcon_dpoc else False
        context["jcon_dpoc"] = True if jcon_dpoc else False
        context["dpo_dpoc"] = True if dpo_dpoc else False
        context["ird_dpoc"] = True if ird_dpoc else False
        context["cpd_dpoc"] = True if cpd_dpoc else False
        context["cpdo_dpoc"] = True if cpdo_dpoc else False
        context["plb_dpoc"] = True if plb_dpoc else False
        context["dsub_dpoc"] = True if dsub_dpoc else False
        context["tle_dpoc"] = True if tle_dpoc else False
        context["crec_dpoc"] = True if crec_dpoc else False
        context["ttc_dpoc"] = True if ttc_dpoc else False
        context["agrp_dpoc"] = True if agrp_dpoc else False
        context["tran_dpoc"] = True if tran_dpoc else False
        context["dpro_dpoc"] = True if dpro_dpoc else False
        context["pia_dpoc"] = True if pia_dpoc else False
        context["tom_dpoc"] = True if tom_dpoc else False
        context["annex_dpoc"] = True if annex_dpoc else False
        return context

class RPADetailPDFView(WeasyTemplateResponseMixin, RPADetailView):
    """Allow a single RPA to be downloaded as PDF file
    (RPAGenUserPassesMixin-restricted via RPADetailView)
    """

    template_name = "rpa/rpa_pdftemplate.html"
    pdf_attachment = False

    def get_pdf_filename(self):
        rpaname = _("rpa")
        if self.object:
            rpaname += "-" + str(self.object)
        return "{rpaname}-{at}.pdf".format(
            at=timezone.now().strftime("%Y%m%d"), rpaname=rpaname
        )

class RPADeleteView(LoginRequiredMixin, RPAGenUserPassesMixin, DeleteView):
    """Allow a single RPA to be deleted
    (RPAGenUserPassesMixin-restricted)
    """

    model = Rpa
    template_name = "rpa/rpa_delete_confirmation.html"
    success_url = reverse_lazy("rpa:my_rpas")

    def post(self, request, *args, **kwargs):
        if "cancel" in request.POST:
            return redirect("rpa:my_rpas")
        return super().post(request, *args, **kwargs)

class AllRPADeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
    """Allow superusers and staff users with dpo membership to delete
    any single breach report
    """

    model = Rpa
    template_name = "rpa/rpa_delete_confirmation.html"
    success_url = reverse_lazy("rpa:all_rpas")

    def test_func(self):
        is_allowed = False
        if (
            self.request.user.is_staff
            and self.request.user.groups.filter(name="dpo").exists()
        ):
            is_allowed = True
        if self.request.user.is_superuser:
            is_allowed = True
        return is_allowed

    def post(self, request, *args, **kwargs):
        if "cancel" in request.POST:
            return redirect("rpa:all_rpas")
        return super().post(request, *args, **kwargs)

class RPAEditView(LoginRequiredMixin, RPAGenUserPassesMixin, DetailView):
    """General edit overview page with links to all edit views of
    RPA-related objects (such as categories of personal data, technical
    and organisational measures, ...); also shows status of objects in
    terms of RPA completeness (RPAGenUserPassesMixin-restricted)
    """

    model = Rpa
    template_name = "rpa/rpa_edit.html"
    context_object_name = "rpa"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        rpanm_dpoc = self.object.rpa_names.values_list("dpo_comment").exclude(
            dpo_comment__exact=""
        )
        dcon_dpoc = self.object.datacontrollers.values_list("dcon_dpo_comment").exclude(
            dcon_dpo_comment__exact=""
        )
        jcon_dpoc = self.object.jointcontrollers.values_list(
            "jcon_dpo_comment"
        ).exclude(jcon_dpo_comment__exact="")
        dpo_dpoc = self.object.dpos.values_list("dpo_dpo_comment").exclude(
            dpo_dpo_comment__exact=""
        )
        ird_dpoc = self.object.internally_resp_depts.values_list(
            "ird_dpo_comment"
        ).exclude(ird_dpo_comment__exact="")
        cpd_dpoc = self.object.datacategories.values_list("cpd_dpo_comment").exclude(
            cpd_dpo_comment__exact=""
        )
        cpdo_dpoc = self.object.datacategories_origin.values_list(
            "cpdo_dpo_comment"
        ).exclude(cpdo_dpo_comment__exact="")
        plb_dpoc = self.object.purposes_legalbases.values_list(
            "plb_dpo_comment"
        ).exclude(plb_dpo_comment__exact="")
        dsub_dpoc = self.object.datasubjects.values_list("dsub_dpo_comment").exclude(
            dsub_dpo_comment__exact=""
        )
        tle_dpoc = self.object.timelimits_erasure.values_list(
            "tle_dpo_comment"
        ).exclude(tle_dpo_comment__exact="")
        crec_dpoc = self.object.categories_of_rec.values_list(
            "crec_dpo_comment"
        ).exclude(crec_dpo_comment__exact="")
        ttc_dpoc = self.object.transfers_to_3rdc.values_list("ttc_dpo_comment").exclude(
            ttc_dpo_comment__exact=""
        )
        agrp_dpoc = self.object.accessgroups.values_list("agrp_dpo_comment").exclude(
            agrp_dpo_comment__exact=""
        )
        tran_dpoc = self.object.transparencies.values_list("tran_dpo_comment").exclude(
            tran_dpo_comment__exact=""
        )
        dpro_dpoc = self.object.dataprocessors.values_list("dpro_dpo_comment").exclude(
            dpro_dpo_comment__exact=""
        )
        pia_dpoc = self.object.pias.values_list("pia_dpo_comment").exclude(
            pia_dpo_comment__exact=""
        )
        tom_dpoc = self.object.toms.values_list("tom_dpo_comment").exclude(
            tom_dpo_comment__exact=""
        )
        annex_dpoc = self.object.rpa_annexes.values_list("annex_dpo_comment").exclude(
            annex_dpo_comment__exact=""
        )
        context["rpanm_dpoc"] = True if rpanm_dpoc else False
        context["dcon_dpoc"] = True if dcon_dpoc else False
        context["jcon_dpoc"] = True if jcon_dpoc else False
        context["dpo_dpoc"] = True if dpo_dpoc else False
        context["ird_dpoc"] = True if ird_dpoc else False
        context["cpd_dpoc"] = True if cpd_dpoc else False
        context["cpdo_dpoc"] = True if cpdo_dpoc else False
        context["plb_dpoc"] = True if plb_dpoc else False
        context["dsub_dpoc"] = True if dsub_dpoc else False
        context["tle_dpoc"] = True if tle_dpoc else False
        context["crec_dpoc"] = True if crec_dpoc else False
        context["ttc_dpoc"] = True if ttc_dpoc else False
        context["agrp_dpoc"] = True if agrp_dpoc else False
        context["tran_dpoc"] = True if tran_dpoc else False
        context["dpro_dpoc"] = True if dpro_dpoc else False
        context["pia_dpoc"] = True if pia_dpoc else False
        context["tom_dpoc"] = True if tom_dpoc else False
        context["annex_dpoc"] = True if annex_dpoc else False
        return context

class RPACreateSimpleFormView(CreateView):
    """Used to create and edit RPA-related objects that require just a
    single form without data from other database objects (namely
    category of personal data objects)
    """

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        rpaslug = self.kwargs.get("slug")
        rpa = get_object_or_404(Rpa, slug=rpaslug)
        try:
            existing_instance = self.model.objects.get(rpa=rpa)
        except self.model.DoesNotExist:
            existing_instance = None
        if existing_instance:
            kwargs["instance"] = existing_instance
        return kwargs

    def form_valid(self, form):
        rpaslug = self.kwargs.get("slug")
        rpa = get_object_or_404(Rpa, slug=rpaslug)
        form.instance.rpa = rpa
        return super().form_valid(form)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        rpaslug = self.kwargs.get("slug")
        context["rpa"] = get_object_or_404(Rpa, slug=rpaslug)
        return context

    def get_success_url(self):
        return reverse("rpa:rpa_detail_edit", args=[self.kwargs["slug"]])

class RPACreateSimpleFormsetView(ModelFormSetView):
    """Used to create and edit RPA-related objects that require a
    formset without data from other database objects (namely category of
    personal data objects)
    """

    def get_queryset(self):
        rpaslug = self.kwargs.get("slug")
        rpa = get_object_or_404(Rpa, slug=rpaslug)
        return super().get_queryset().filter(rpa=rpa)

    def formset_valid(self, formset):
        rpaslug = self.kwargs.get("slug")
        rpa = get_object_or_404(Rpa, slug=rpaslug)
        for form in formset:
            form.instance.rpa = rpa
        return super().formset_valid(formset)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        rpaslug = self.kwargs.get("slug")
        context["rpa"] = get_object_or_404(Rpa, slug=rpaslug)
        return context

    def get_success_url(self):
        return reverse("rpa:rpa_detail_edit", args=[self.kwargs["slug"]])

class RPACreateChoiceFormsetView(ModelFormSetView):
    """Used to create and edit RPA-related objects that require a
    formset with data from other database objects (namely category of
    personal data) in every single form of the formset (currently data
    subject, time limit for erasure, category of recipients, and access
    group)
    """

    def construct_formset(self):
        formset = super().construct_formset()
        rpaslug = self.kwargs.get("slug")
        rpa = get_object_or_404(Rpa, slug=rpaslug)
        choice_field = self.kwargs.get("choice_field", None)
        for form in formset:
            form.fields[choice_field] = CpdModelMultipleChoiceField(
                queryset=CategoryOfPersonalData.objects.filter(rpa=rpa),
                widget=forms.CheckboxSelectMultiple,
                label=CPD_CHOICES,
                required=False,
            )
            if form.instance.id:
                previously_selected = []
                for i in form.instance.cpd.all():
                    previously_selected.append(i.pk)
                form.initial[choice_field] = previously_selected
        return formset

    def get_queryset(self):
        rpaslug = self.kwargs.get("slug")
        rpa = get_object_or_404(Rpa, slug=rpaslug)
        return super().get_queryset().filter(rpa=rpa)

    def formset_valid(self, formset):
        rpaslug = self.kwargs.get("slug")
        rpa = get_object_or_404(Rpa, slug=rpaslug)
        for form in formset:
            form.instance.rpa = rpa
        return super().formset_valid(formset)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        rpaslug = self.kwargs.get("slug")
        rpa = get_object_or_404(Rpa, slug=rpaslug)
        cpd = CategoryOfPersonalData.objects.filter(rpa=rpa)
        context["rpa"] = rpa
        context["cpd"] = cpd
        return context

    def get_success_url(self):
        return reverse("rpa:rpa_detail_edit", args=[self.kwargs["slug"]])

class RPACreateView(LoginRequiredMixin, CreateView):
    """Used to create an RPA object (basically an empty RPA, that is
    supposed to be completed afterwards); view is accessible for
    authenticated users only; redirects to MyRPAsView
    """

    form_class = RpaForm
    template_name = "rpa/rpa_create_slug.html"
    model = Rpa

    def form_valid(self, form):
        form.instance.user = self.request.user
        return super().form_valid(form)

    def get_success_url(self):
        return reverse("rpa:my_rpas")

class RPACreateRpanmView(
    LoginRequiredMixin, RPAGenUserPassesMixin, RPACreateSimpleFormView
):
    form_class = ProcessingActivityNameForm
    model = ProcessingActivityName
    template_name = "rpa/rpa_create_name.html"

class RPACreateDconView(
    LoginRequiredMixin, RPAGenUserPassesMixin, RPACreateSimpleFormView
):
    form_class = DataControllerForm
    model = DataController
    template_name = "rpa/rpa_create_dcon.html"

class RPACreateJconView(
    LoginRequiredMixin, RPAGenUserPassesMixin, RPACreateSimpleFormView
):
    form_class = JointControllerForm
    model = JointController
    template_name = "rpa/rpa_create_jcon.html"

class RPACreateDpoView(
    LoginRequiredMixin, RPAGenUserPassesMixin, RPACreateSimpleFormView
):
    form_class = DataProtectionOfficerForm
    model = DataProtectionOfficer
    template_name = "rpa/rpa_create_dpo.html"

class RPACreateIrdView(
    LoginRequiredMixin, RPAGenUserPassesMixin, RPACreateSimpleFormView
):
    form_class = InternallyResponsibleDeptForm
    model = InternallyResponsibleDept
    template_name = "rpa/rpa_create_ird.html"

class RPACreateCpdView(
    LoginRequiredMixin, RPAGenUserPassesMixin, RPACreateSimpleFormsetView
):
    model = CategoryOfPersonalData
    form_class = CategoryOfPersonalDataForm
    formset_class = CategoryOfPersonalDataFormSet
    factory_kwargs = {
        "min_num": 1,
        "max_num": 9,
        "extra": 8,
        "can_order": False,
        "can_delete": True,
    }
    template_name = "rpa/rpa_create_cpd.html"

class RPACreateCpdoView(
    LoginRequiredMixin, RPAGenUserPassesMixin, RPACreateSimpleFormView
):
    form_class = CategoriesOfPersonalDataOriginForm
    model = CategoriesOfPersonalDataOrigin
    template_name = "rpa/rpa_create_cpdo.html"

class RPACreatePlbView(
    LoginRequiredMixin, RPAGenUserPassesMixin, RPACreateSimpleFormView
):
    form_class = PurposeAndLegalBasisForm
    model = PurposeAndLegalBasis
    template_name = "rpa/rpa_create_plb.html"

class RPACreateDSubView(
    LoginRequiredMixin, RPAGenUserPassesMixin, RPACreateChoiceFormsetView
):
    model = DataSubject
    form_class = DataSubjectForm
    factory_kwargs = {
        "min_num": 1,
        "max_num": 9,
        "extra": 8,
        "can_order": False,
        "can_delete": True,
    }
    template_name = "rpa/rpa_create_dsub.html"

class RPACreateTleView(
    LoginRequiredMixin, RPAGenUserPassesMixin, RPACreateChoiceFormsetView
):
    model = TimeLimitForErasure
    form_class = TimeLimitForErasureForm
    formset_class = TimeLimitForErasureFormSet
    factory_kwargs = {
        "min_num": 1,
        "max_num": 5,
        "extra": 4,
        "can_order": False,
        "can_delete": True,
    }
    template_name = "rpa/rpa_create_tle.html"

class RPACreateCrecView(
    LoginRequiredMixin, RPAGenUserPassesMixin, RPACreateChoiceFormsetView
):
    model = CategoryOfRecipients
    form_class = CategoryOfRecipientsForm
    formset_class = CategoryOfRecipientsFormSet
    factory_kwargs = {
        "min_num": 1,
        "max_num": 5,
        "extra": 4,
        "can_order": False,
        "can_delete": True,
    }
    template_name = "rpa/rpa_create_crec.html"

class RPACreateTtcView(
    LoginRequiredMixin, RPAGenUserPassesMixin, RPACreateSimpleFormView
):
    form_class = TransferToThirdCountryForm
    model = TransferToThirdCountry
    template_name = "rpa/rpa_create_ttc.html"

class RPACreateAgrpView(
    LoginRequiredMixin, RPAGenUserPassesMixin, RPACreateChoiceFormsetView
):
    model = AccessGroup
    form_class = AccessGroupForm
    formset_class = AccessGroupFormSet
    factory_kwargs = {
        "min_num": 1,
        "max_num": 5,
        "extra": 4,
        "can_order": False,
        "can_delete": True,
    }
    template_name = "rpa/rpa_create_agrp.html"

class RPACreateTranView(
    LoginRequiredMixin, RPAGenUserPassesMixin, RPACreateSimpleFormView
):
    form_class = TransparencyForm
    model = Transparency
    template_name = "rpa/rpa_create_tran.html"

class RPACreateDproView(
    LoginRequiredMixin, RPAGenUserPassesMixin, RPACreateSimpleFormView
):
    form_class = DataProcessorForm
    model = DataProcessor
    template_name = "rpa/rpa_create_dpro.html"

class RPACreatePiaView(
    LoginRequiredMixin, RPAGenUserPassesMixin, RPACreateSimpleFormView
):
    form_class = PrivacyImpactAssessmentForm
    model = PrivacyImpactAssessment
    template_name = "rpa/rpa_create_pia.html"

class RPACreateTomView(
    LoginRequiredMixin, RPAGenUserPassesMixin, RPACreateSimpleFormView
):
    form_class = TOMForm
    model = TOM
    template_name = "rpa/rpa_create_tom.html"

class RPACreateAnnexView(
    LoginRequiredMixin, RPAGenUserPassesMixin, RPACreateSimpleFormsetView
):
    model = RPAAnnex
    form_class = RPAAnnexForm
    formset_class = RPAAnnexFormSet
    factory_kwargs = {
        "min_num": 0,
        "max_num": 9,
        "extra": 9,
        "can_order": False,
        "can_delete": True,
    }
    template_name = "rpa/rpa_create_annex.html"


import os
from os import path
from PIL import Image
import numpy as np
import json
from torchvision.transforms import ToTensor
from torch.utils.data import Dataset
from tqdm import tqdm
import pickle
import torch

torch.set_default_dtype(torch.float64)

class PlanarDatasetN(Dataset):
    width = 40
    height = 40
    action_dim = 2

    def __init__(self, dir):
        self.dir = dir
        self.n_steps = None
        with open(path.join(dir, 'data.json')) as f:
            self._data = json.load(f)
        self._process()

    def __len__(self):
        return len(self._data['samples'])

    def __getitem__(self, index):
        return self._processed[index]

    @staticmethod
    def _process_image(img):
        return ToTensor()((img.convert('L').
                           resize((PlanarDataset.width,
                                   PlanarDataset.height))))

    def _process(self):
        preprocessed_file = os.path.join(self.dir, 'processed.pkl')
        if True or not os.path.exists(preprocessed_file):
            processed = []
            self.n_steps = None
            for sample in tqdm(self._data['samples'], desc='processing data'):
                obs0 = Image.open(os.path.join(self.dir, sample['observation_files'][0]))

                processed_sample = [self._process_image(obs0)]
                n_steps = 0
                for obs_file, control in zip(sample['observation_files'][1:], sample['controls']):
                    obs = Image.open(os.path.join(self.dir, obs_file))
                    processed_sample += [np.asarray(control), self._process_image(obs)]
                    n_steps += 1

                if self.n_steps is None:
                    self.n_steps = n_steps
                assert self.n_steps == n_steps
                processed.append(tuple(processed_sample))

            with open(preprocessed_file, 'wb') as f:
                pickle.dump(processed, f)
            self._processed = processed
        else:
            with open(preprocessed_file, 'rb') as f:
                self._processed = pickle.load(f)


import requests
import pprint
from assertpy import assert_that
from config import BASE_URI
from Blog.blog_posts import get_token_login

def test_aboutus_list():
    r = list_aboutus()
    assert_that(r.status_code).is_equal_to(200)

def list_aboutus():
    list_URI = f'{BASE_URI}/cms/aboutus-list/'
    r = requests.get(list_URI)
    return r

def test_about_us_delete():
    id = id_of_aboutus()
    #pprint.pprint(id)
    delete_URI = f'{BASE_URI}/cms/aboutus-delete/{id}/'
    headers = {
        'Authorization': f'JWT {get_token_login()}'
    }
    r = requests.delete(delete_URI, headers=headers)
    assert_that(r.status_code).is_equal_to(204)

def id_of_aboutus():
    about_us = list_aboutus().json()
    id = about_us[0]['id']
    return id

def test_aboutus_create():
    create_URI = f'{BASE_URI}/cms/aboutus-create/'
    data = {
        'content': 'This is my first content'
    }
    headers = {

    }
    r = requests.post(create_URI, data=data, headers=headers)
    assert_that(r.status_code).is_equal_to(201)

def test_aboutus_detail():
    about_id = id_of_aboutus()
    headers = {
        'Authorization': f'JWT {get_token_login()}'
    }
    detail_URI = f'{BASE_URI}/cms/aboutus-detail/{about_id}/'
    r = requests.get(detail_URI, headers=headers)
    #pprint.pprint(r.json())
    assert_that(r.status_code).is_equal_to(200)

def test_aboutus_update():
    aboutus_id = id_of_aboutus()
    updated_URI = f'{BASE_URI}/cms/aboutus-update/{aboutus_id}/'
    headers = {
        'Authorization': f'JWT {get_token_login()}'
    }
    data = {
        'content': 'Here we see the changed content'
    }
    r = requests.patch(updated_URI, data=data, headers=headers)
    assert_that(r.status_code).is_equal_to(200)
    #pprint.pprint(list_aboutus().json())


# Python program to get week number from 16/06/2015
from datetime import date

week  = date(year = 2015,month = 6,day=16)

print("The date is : ",week)

weeknumber = week.strftime("%W")

print("The week number is : ",weeknumber)


import json
from datetime import date
import calendar

class Pizeria:
    def __init__(self):
        data = {"Monday": {"name": "Four seasons", "price": 100},
                "Tuesday": {"name": "Margarita", "price": 80},
                "Wednesday": {"name": "Gavaian", "price": 150},
                "Thursday": {"name": "Pineappled", "price": 50},
                "Friday": {"name": "Four cheeses", "price": 120},
                "Saturday": {"name": "Family-pizza", "price": 350},
                "Sunday": {"name": "Cono-pizza", "price": 115}
                }
        with open("pizzaoftheday.json", "w") as json_file:
            json.dump(data, json_file, indent=2)

    def __str__(self):
        with open("pizzaoftheday.json", "r") as json_file:
            json_object = json.load(json_file)
        data = "\n".join(list(map(str, json_object.items())))
        data = data.replace("{", " ")
        data = data.replace("}", " ")
        return data

class Pizzaoftheday():
    def __init__(self):
        today = date.today()
        self.day = calendar.day_name[today.weekday()]
        print(self.day)
        if self.day == "Monday":
            self.pizza = Monday()
        elif self.day == "Thursday":
            self.pizza = Thursday()
        elif self.day == "Tuesday":
            self.pizza = Tuesday()
        elif self.day == "Wednesday":
            self.pizza = Wednesday()
        elif self.day == "Friday":
            self.pizza = Friday()
        elif self.day == "Saturday":
            self.pizza = Saturday()
        else:
            self.pizza = Sunday()

    def get_price(self):
        return self.pizza.price

    def get_info(self):
        return self.pizza.name

class Monday(Pizzaoftheday):
    def __init__(self):
        with open("pizzaoftheday.json", "r") as json_file:
            json_object = json.load(json_file)
        self.day = "Monday"
        self.price = json_object["Monday"]["price"]
        self.name = json_object["Monday"]["name"]

    def __str__(self):
        return f'Monday pizza: {self.name}, price: {self.price}'

class Wednesday(Pizzaoftheday):
    def __init__(self):
        with open("pizzaoftheday.json", "r") as json_file:
            json_object = json.load(json_file)
        self.day = "Wednesday"
        self.price = json_object["Wednesday"]["price"]
        self.name = json_object["Wednesday"]["name"]

    def __str__(self):
        return f'Wednesday pizza: {self.name}, price: {self.price}'

class Tuesday(Pizzaoftheday):
    def __init__(self):
        with open("pizzaoftheday.json", "r") as json_file:
            json_object = json.load(json_file)
        self.day = "Tuesday"
        self.price = json_object["Tuesday"]["price"]
        self.name = json_object["Tuesday"]["name"]

    def __str__(self):
        return f'Tuesday pizza: {self.name}, price: {self.price}'

class Thursday(Pizzaoftheday):
    def __init__(self):
        with open("pizzaoftheday.json", "r") as json_file:
            json_object = json.load(json_file)
        self.day = "Thursday"
        self.price = json_object["Thursday"]["price"]
        self.name = json_object["Thursday"]["name"]

    def __str__(self):
        return f'Thursday pizza: {self.name}, price: {self.price}'

class Friday(Pizzaoftheday):
    def __init__(self):
        with open("pizzaoftheday.json", "r") as json_file:
            json_object = json.load(json_file)
        self.day = "Friday"
        self.price = json_object["Friday"]["price"]
        self.name = json_object["Friday"]["name"]

    def __str__(self):
        return f'Friday pizza: {self.name}, price: {self.price}'

class Saturday(Pizzaoftheday):
    def __init__(self):
        with open("pizzaoftheday.json", "r") as json_file:
            json_object = json.load(json_file)
        self.day = "Saturday"
        self.price = json_object["Saturday"]["price"]
        self.name = json_object["Saturday"]["name"]

    def __str__(self):
        return f'Saturday pizza: {self.name}, price: {self.price}'

class Sunday(Pizzaoftheday):
    def __init__(self):
        with open("pizzaoftheday.json", "r") as json_file:
            json_object = json.load(json_file)
        self.day = "Sunday"
        self.price = json_object["Sunday"]["price"]
        self.name = json_object["Sunday"]["name"]

    def __str__(self):
        return f'Sunday pizza: {self.name}, price: {self.price}'

class CustomPizza:

    def __init__(self):
        self.pizza = Pizzaoftheday()
        self.add_ingredients
        self.price = self.add_ingredients()

    def add_ingredients(self):
        with open("ingredients.json", "r") as json_file:
            json_object = json.load(json_file)
        total = self.pizza.get_price()
        print(json_object)
        while 1 == 1:
            data = input("Enter ingredient you want to add (enter 'x' for exit): ")
            if data in json_object.keys():
                total += json_object[str(data)]
                print(total)
            if data == "x":
                break
        return total

    def get_price(self):
        return self.price

    def get_info(self):
        return f'Custom pizza-of-the-day'

class Order():
    def __init__(self):
        self.make_order
        self.total_price = self.make_order()

    def make_order(self):

        order = {}
        number = input("How many pizzas u want to order? ")
        dayspizzas = input("How many of them is pizza-of-the-day? ")
        custompizzas = int(number) - int(dayspizzas)
        for item in range(int(dayspizzas)):
            order[item] = Pizzaoftheday()
        for value in range(int(custompizzas)):
            order[value + int(dayspizzas)] = CustomPizza()
        total = 0
        for item in order:
            total += order[item].get_price()

        return total

    def get_price(self):
        return f'Total price of order: {self.total_price}'

x = Pizeria()
z = Order()
print(z.get_price())


__author__ = 'Stephen Ramsey'
__copyright__ = 'Oregon State University'
__credits__ = ['Stephen Ramsey', 'Yao Yao', 'Zheng Liu']
__license__ = 'MIT'
__version__ = '0.1.0'
__maintainer__ = ''
__email__ = ''
__status__ = 'Prototype'

import pandas
import io
import math
import requests
import sys
import functools
import CachedMethods

class QueryDisGeNet:
    MAX_PROTS_FOR_GENE = 3   ## maybe we should make this a configurable class variable (SAR)
    MAX_GENES_FOR_DISEASE = 20  ## maybe we should make this a configurable class variable (SAR)
    SPARQL_ENDPOINT_URL = 'http://www.disgenet.org/oql'
    TIMEOUT_SEC = 120

    @staticmethod
    @CachedMethods.register
    @functools.lru_cache(maxsize=1024, typed=False)
    def query_mesh_id_to_uniprot_ids_desc(mesh_id):
        ent = 'disease'
        id = 'mesh'
        STR = "c1.MESH = '"
        intfield = mesh_id
        seq = ( """
        DEFINE
        c0='/data/gene_disease_summary',
	c1='/data/diseases',
	c2='/data/genes',
	c4='/data/sources'
        ON
           'http://www.disgenet.org/web/DisGeNET'
        SELECT
        c1 (diseaseId, name, diseaseClassName, STY, MESH, OMIM, type ),
	c2 (geneId, symbol,   uniprotId, description, pantherName ),
	c0 (score, EI, Npmids, Nsnps)

        FROM
            c0
        WHERE
            (
                """ + STR +  mesh_id+"""'
            AND
                c4 = 'ALL'
            )
        ORDER BY
            c0.score DESC""" ); #

        binary_data = seq.encode('utf-8')
        url_str = QueryDisGeNet.SPARQL_ENDPOINT_URL

        try:
            res = requests.post(url_str, data=binary_data, timeout=QueryDisGeNet.TIMEOUT_SEC)
        except requests.exceptions.Timeout:
            print(url_str, sys.stderr)
            print('Timeout in QueryDisGeNet for URL: ' + url_str, file=sys.stderr)
            return dict()

        status_code = res.status_code

        if status_code != 200:
            print(url_str, sys.stderr)
            print('Status code ' + str(status_code) + ' for url: ' + url_str, file=sys.stderr)
            return dict()

        if len(res.content) == 0:
            print(url_str, file=sys.stderr)
            print('Empty response from URL!', file=sys.stderr)
            return dict()

        ret_data_df = pandas.read_csv(io.StringIO(res.content.decode('utf-8')), sep='\t').head(QueryDisGeNet.MAX_GENES_FOR_DISEASE)
        uniprot_ids_list = ret_data_df['c2.uniprotId'].tolist()
        gene_names_list = ret_data_df['c2.symbol'].tolist()
        ret_dict = dict(list(zip(uniprot_ids_list, gene_names_list)))
        for prot in ret_dict.copy().keys():
            if type(prot)==str:
                if '.' in prot or ';' in prot:
                    gene = ret_dict[prot]
                    del ret_dict[prot]
                    prot.replace('.', '')
                    prots_to_add = prot.split(';')
                    if len(prots_to_add) > QueryDisGeNet.MAX_PROTS_FOR_GENE:
                        prots_to_add = prots_to_add[0:QueryDisGeNet.MAX_PROTS_FOR_GENE]
                        dict_add = dict()
                        for prot_name in prots_to_add:
                            if type(prot_name) == str:
                                dict_add[prot_name] = gene
                        ret_dict.update(dict_add)
            else:  ## this is a math.nan
                del ret_dict[prot]
        return(ret_dict)

if __name__ == '__main__':
    print(QueryDisGeNet.query_mesh_id_to_uniprot_ids_desc('D016779'))
    print(QueryDisGeNet.query_mesh_id_to_uniprot_ids_desc('D004443'))


from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/user/<int:user_id>', methods=['GET'])
def get_user(user_id):
    return jsonify({
        "user_id": user_id,
        "name": "John Doe"
    })

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=8080)


import json
import os
import unittest
from typing import Optional, List, Callable

import requests

from exasol_integration_test_docker_environment.lib.docker import ContextDockerClient

INTEGRATION_TEST_DOCKER_ENVIRONMENT_DEFAULT_BIN = "./start-test-env"

def close_environments(*args):
    for env in args:
        try:
            if env is not None:
                env.close()
        except Exception as e:
            print(e)

def check_db_version_from_env() -> Optional[str]:
    retval = None
    if "EXASOL_VERSION" in os.environ and os.environ["EXASOL_VERSION"] != "default":
        retval = os.environ["EXASOL_VERSION"]
    return retval

def multiassert(assert_list: List[Callable], unit_test: unittest.TestCase):
    failure_log: List[str] = []
    for assert_fn in assert_list:
        try:
            assert_fn()
        except AssertionError as e:
            failure_log.append(f"\nFailure {len(failure_log)}: {str(e)}")

    if len(failure_log) != 0:
        res_failure_log = '\n'.join(failure_log)
        unit_test.fail(f"{len(failure_log)} failures within test.\n {res_failure_log}")


import pytest

from equivalence import db, checker
from tests.calcite import CASES

@pytest.fixture
def checker_fixture():
    plan_generator = db.PlanGenerator(
        db.ConnectionParameters("postgres", "postgres", "demo")
    )

    return checker.Checker(plan_generator)

@pytest.mark.parametrize("case", CASES, ids=str)
def test_calcite(case, checker_fixture):
    # skip = [
    #     "testAddRedundantSemiJoinRule",
    #     "testAggregateConstantKeyRule3",
    #     "testCastInAggregateExpandDistinctAggregatesRule",
    #     "testDecorrelateTwoExists",
    #     "testDecorrelateTwoIn",
    # ]
    #
    # if case.name in skip:
    #     return

    skip = [
        # "testAddRedundantSemiJoinRule",
        # "testCastInAggregateExpandDistinctAggregatesRule"
    ]
    if case.name in skip:
        return

    assert checker_fixture.check(case.query1, case.query2)