import torch
import torchvision
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Function
from model.keypointspooling import LeftPool, TopPool, BottomPool,RightPool
from utilis.featurevisualization import FeatureVisualization
j=0

class ConvBnRelu(nn.Module):
    """docstring for BnReluConv"""
    def __init__(self, inChannels, outChannels, kernelSize=1, stride=1, padding=0):
        super(ConvBnRelu, self).__init__()
        self.inChannels = inChannels
        self.outChannels = outChannels
        self.kernelSize = kernelSize
        self.stride = stride
        self.padding = padding

        self.conv = nn.Conv2d(self.inChannels, self.outChannels, self.kernelSize, self.stride, self.padding)
        self.bn = nn.BatchNorm2d(self.outChannels)
        self.relu = nn.ReLU(inplace=True)

    def forward(self, x):
        x = self.conv(x)
        x = self.bn(x)
        x = self.relu(x)
        return x

class BnReluConv(nn.Module):
        """docstring for BnReluConv"""
        def __init__(self, inChannels, outChannels, kernelSize = 1, stride = 1, padding = 0):
                super(BnReluConv, self).__init__()
                self.inChannels = inChannels
                self.outChannels = outChannels
                self.kernelSize = kernelSize
                self.stride = stride
                self.padding = padding

                self.bn = nn.BatchNorm2d(self.inChannels)
                self.conv = nn.Conv2d(self.inChannels, self.outChannels, self.kernelSize, self.stride, self.padding)
                self.relu = nn.ReLU(inplace=True)

        def forward(self, x):
                x = self.bn(x)
                x = self.relu(x)
                x = self.conv(x)
                return x

class ConvBlock(nn.Module):
        """docstring for ConvBlock"""
        def __init__(self, inChannels, outChannels):
                super(ConvBlock, self).__init__()
                self.inChannels = inChannels
                self.outChannels = outChannels
                self.outChannelsby2 = outChannels//2

                self.cbr1 = BnReluConv(self.inChannels, self.outChannelsby2, 1, 1, 0)
                self.cbr2 = BnReluConv(self.outChannelsby2, self.outChannelsby2, 3, 1, 1)
                self.cbr3 = BnReluConv(self.outChannelsby2, self.outChannels, 1, 1, 0)

        def forward(self, x):
                x = self.cbr1(x)
                x = self.cbr2(x)
                x = self.cbr3(x)
                return x

class SkipLayer(nn.Module):
        """docstring for SkipLayer"""
        def __init__(self, inChannels, outChannels):
                super(SkipLayer, self).__init__()
                self.inChannels = inChannels
                self.outChannels = outChannels
                if (self.inChannels == self.outChannels):
                        self.conv = None
                else:
                        self.conv = nn.Conv2d(self.inChannels, self.outChannels, 1)

        def forward(self, x):
                if self.conv is not None:
                        x = self.conv(x)
                return x

class Residual(nn.Module):
        """docstring for Residual"""
        def __init__(self, inChannels, outChannels):
                super(Residual, self).__init__()
                self.inChannels = inChannels
                self.outChannels = outChannels
                self.cb = ConvBlock(inChannels, outChannels)
                self.skip = SkipLayer(inChannels, outChannels)

        def forward(self, x):
                out = 0
                out = out + self.cb(x)
                out = out + self.skip(x)
                return out

class FeaEnhance(nn.Module):
        """docstring for Residual"""
        def __init__(self, inChannels, outChannels):
                super(FeaEnhance, self).__init__()
                super(FeaEnhance, self).__init__()
                self.inChannels = inChannels
                self.outChannels = outChannels
                self.outChannelsby2 = outChannels // 2

                # s1
                self.atrousconv1 = nn.Conv2d(self.inChannels, self.outChannelsby2, 3, stride=2, dilation=2, padding=2)
                self.maxp1 = nn.MaxPool2d(2, 2)
                self.conv1 = nn.Conv2d(self.inChannels, self.outChannelsby2, 1, 1, 0)
                self.bnrc1 = BnReluConv(self.inChannels, self.outChannelsby2, 1, 1, 0)

                # s2
                self.maxp2 = nn.MaxPool2d(2, 2)
                self.upsampling1 = nn.Upsample(scale_factor=2)
                self.maxp3 = nn.MaxPool2d(2, 2)
                self.upsampling2 = nn.Upsample(scale_factor=2)

                self.bnrc2 = BnReluConv(self.outChannelsby2, self.outChannelsby2, 3, 1, 1)
                self.atrousconv2 = nn.Conv2d(self.outChannelsby2, self.outChannelsby2, 3, stride=4, dilation=2,
                                             padding=2)
                self.maxp4 = nn.MaxPool2d(4, 4)

                # s3
                self.upsampling4 = nn.Upsample(scale_factor=4)
                self.conv2 = nn.Conv2d(self.outChannelsby2, self.outChannels, 1, 1, 0)
                self.upsampling5 = nn.Upsample(scale_factor=4)
                self.conv3 = nn.Conv2d(self.outChannelsby2, self.outChannels, 1, 1, 0)

                self.bnrc3 = BnReluConv(self.outChannelsby2, self.outChannels, 1, 1, 0)

                self.skip = SkipLayer(inChannels, outChannels)

        def forward(self, x):
            # s1
            out1 = self.atrousconv1(x)  # 240*320*128
            out2 = self.maxp1(x)  # 120*160*128
            out2 = self.conv1(out2)
            out3 = self.bnrc1(x)

            # s2
            out1s2_1 = self.maxp2(out1)
            out1s2_2 = self.upsampling1(out1)

            out2s2_1 = self.maxp3(out2)
            out2s2_2 = self.upsampling2(out2)

            out3s2_1 = self.atrousconv2(out3)
            out3s2_2 = self.maxp4(out3)
            out3s2_3 = self.bnrc2(out3)

            out1s2 = out1s2_1 + out3s2_1
            out2s2 = out2s2_1 + out3s2_2
            out3s2 = out3s2_3 + out1s2_2 + out2s2_2

            # s3
            out1s3 = self.upsampling4(out1s2)
            out1s3 = self.conv2(out1s3)

            out2s3 = self.upsampling5(out2s2)
            out2s3 = self.conv3(out2s3)

            out3s3 = self.bnrc3(out3s2)

            out = out1s3 + out3s3 + out2s3
            out = out + self.skip(x)
            return out

class Feaenhance_2(nn.Module):
        """docstring for Feaenhance"""
        def __init__(self, inChannels, outChannels):
                super(Feaenhance_2, self).__init__()
                self.inChannels = inChannels
                self.outChannels = outChannels
                # self.outChannelsby2 = outChannels // 2

                #s1
                self.bnrc1 = BnReluConv(self.inChannels, self.outChannels, 1, 1, 0)

                #s2
                self.bnrc2 = BnReluConv(self.outChannels, self.outChannels, 3, 1, 1)
                self.maxp1 = nn.MaxPool2d(2, 2)
                self.maxp2 = nn.MaxPool2d(4, 4)

                #s3
                self.bnrc3 = BnReluConv(self.outChannels, self.outChannels, 1, 1, 0)
                self.maxp3 = nn.MaxPool2d(2, 2)
                self.maxp4 = nn.MaxPool2d(4, 4)

                self.bnrc4 = BnReluConv(self.outChannels, self.outChannels, 3, 1, 1)
                self.conv1 = nn.Conv2d(self.outChannels, self.outChannels, 1, 1, 0)
                self.upsampling1 = nn.Upsample(scale_factor=2)
                self.maxp5 = nn.MaxPool2d(2, 2)

                self.bnrc5 = BnReluConv(self.outChannels, self.outChannels, 3, 1, 1)
                self.conv2 =  nn.Conv2d(self.outChannels, self.outChannels, 1, 1, 0)
                self.upsampling2= nn.Upsample(scale_factor=4)
                self.upsampling3 = nn.Upsample(scale_factor=2)

                self.upsampling4 = nn.Upsample(scale_factor=2)
                self.upsampling5 = nn.Upsample(scale_factor=4)

                self.conv3 =  nn.Conv2d(self.outChannels * 3, self.outChannels, 1, 1, 0)

        def forward(self, x):
            out1 = self.bnrc1(x)

            out2 = self.bnrc2(out1)
            out2_1 = self.maxp1(out1)
            out2_2 = self.maxp2(out1)
            # out2_1 = F.max_pool2d(out1, (2,2))
            # out2_2 =  F.max_pool2d(out1, (4,4))

            out3 = self.bnrc3(out2)
            out3_1 = self.maxp3(out2)
            out3_2 = self.maxp4(out2)

            out4 = self.bnrc4(out2_1)
            out4_1 = self.upsampling1(self.conv1(out2_1))
            out4_2 = self.maxp5(self.conv1(out2_1))

            out5 = self.bnrc5(out2_2)
            out5_1 = self.upsampling2(self.conv2(out2_2))
            out5_2 = self.upsampling3(self.conv2(out2_2))

            out3 = out3 + out4_1 + out5_1
            out4 = out4 + out3_1 + out5_2
            out5 = out5 + out3_2 + out4_2

            out4 = self.upsampling4(out4)
            out5 = self.upsampling5(out5)

            out = torch.cat((out3, out4), dim=1)
            out = torch.cat((out, out5), dim=1)

            out = self.conv3(out)
            return out

class MeanFieldUpdate(nn.Module):
    """
    Meanfield updating

    """

    def __init__(self, inchannels, outchannels): #512，512，512
        super(MeanFieldUpdate, self).__init__()

        self.attenmap = nn.Conv2d(in_channels=inchannels, out_channels=outchannels, kernel_size=3, stride=1, padding=1)# K
        self.attenmap_2 = nn.Conv2d(in_channels=inchannels, out_channels=outchannels, kernel_size=3, stride=1, padding=1)#K

        self.attenmap_g = nn.Conv2d(in_channels=inchannels, out_channels=outchannels, kernel_size=3, stride=1, padding=1)
        self.attenmap_a = nn.Conv2d(in_channels=inchannels, out_channels=outchannels, kernel_size=3, stride=1, padding=1)

        self.norm_atten_a = nn.Sigmoid()
        self.norm_atten_g = nn.Sigmoid()

        self.message_f = nn.Conv2d(in_channels=inchannels, out_channels=outchannels, kernel_size=3,
                                   stride=1, padding=1)

        self.message_f_2 = nn.Conv2d(in_channels=inchannels, out_channels=outchannels, kernel_size=3,
                                   stride=1, padding=1)
        #update y_s
        self.update3 = nn.Conv2d(in_channels=inchannels, out_channels=outchannels, kernel_size=3,
                                   stride=1, padding=1)

        self.update3_2 = nn.Conv2d(in_channels=inchannels, out_channels=outchannels, kernel_size=3,  stride=1, padding=1)
    def forward(self, x_s, x_S):   # s and S scale
        # update attention map
        # a_s = torch.cat((x_s, x_S), dim=1)
        # a_s = self.atten_f(a_s)
        # a_s = self.norm_atten_f(a_s)
        ori_x_S = x_S

        ori_x_S = self.attenmap(ori_x_S)
        g_s = ori_x_S.mul(x_s)

        x_S = self.attenmap_2(x_S)
        a_s_0 = x_S.mul(x_s)

        g_s_1 = self.attenmap_g(a_s_0) #(A,G)
        a_s_1 = self.attenmap_a(g_s) #(A,G)

        g_s = self.norm_atten_g(g_s+g_s_1)
        a_s = self.norm_atten_a(a_s_0+a_s_1)

        # update the last scale feature map y_S
        y_s = self.message_f(x_s)
        y_S = y_s.mul(g_s)

        y_s_a = self.message_f_2(x_s)
        y_S_a = y_s_a.mul(a_s)

        y_S = x_S + y_S + y_S_a # eltwise sum

        #update the y_s
        y_S_1 = self.update3(y_S)
        y_s = y_S_1.mul(g_s)  # production

        y_S_a = self.update3_2(y_S)
        y_s_a = y_S_a.mul(a_s)

        y_s = x_s + y_s + y_s_a # eltwise sum

        return y_S, y_s

class attentionCRF(nn.Module):
    def __init__(self, inChannels, outChannels):
        super(attentionCRF, self).__init__()
        # the first meanfield updating

        self.meanFieldUpdate1_1 = MeanFieldUpdate(inChannels, outChannels)
        self.meanFieldUpdate1_2 = MeanFieldUpdate(inChannels, outChannels)
        self.meanFieldUpdate1_3 = MeanFieldUpdate(inChannels, outChannels)
        self.meanFieldUpdate1_4 = MeanFieldUpdate(inChannels, outChannels)

    def forward(self, lpool, tpool, rpool, bpool, p):
        # five meanfield updating

        y_S, y_s_1 = self.meanFieldUpdate1_1(lpool, p)
        y_S, y_s_2 = self.meanFieldUpdate1_2(tpool, y_S)
        y_S, y_s_3 = self.meanFieldUpdate1_3(rpool, y_S)
        y_S, y_s_4 = self.meanFieldUpdate1_4(bpool, y_S)

        for i  in range(1):
            y_S, y_s_1 = self.meanFieldUpdate1_1(y_s_1, y_S)
            y_S, y_s_2 = self.meanFieldUpdate1_2(y_s_2, y_S)
            y_S, y_s_3 = self.meanFieldUpdate1_3(y_s_3, y_S)
            y_S, y_s_3 = self.meanFieldUpdate1_4(y_s_4, y_S)

        return y_S

class keypointspool(nn.Module):
    def __init__(self, inChannels, outChannels):
        super(keypointspool, self).__init__()
        self.p1_conv1 = ConvBnRelu(inChannels, outChannels, 1) #3*3con,bn,relu
        self.p2_conv1 = ConvBnRelu(inChannels, outChannels, 1)
        self.p3_conv1 = ConvBnRelu(inChannels, outChannels, 1) #3*3con,bn,relu
        self.p4_conv1 = ConvBnRelu(inChannels, outChannels, 1)

        self.p_conv1 = nn.Conv2d(outChannels, outChannels, (3, 3), padding=(1, 1), bias=False)
        self.p_bn1   = nn.BatchNorm2d(outChannels)

        self.conv1 = nn.Conv2d(outChannels, outChannels, (1, 1), bias=False)
        self.bn1   = nn.BatchNorm2d(outChannels)
        self.relu1 = nn.ReLU(inplace=True)

        self.conv2 = ConvBnRelu(outChannels, outChannels, 1)

        self.pool1 = LeftPool()
        self.pool2 = TopPool()
        self.pool3 = RightPool()
        self.pool4 = BottomPool()

        self.atCRF = attentionCRF(inChannels, outChannels)

    def forward(self, x):

        # pool 1
        p1_conv1 = self.p1_conv1(x)
        pool1    = self.pool1(p1_conv1)

        # pool 2
        p2_conv1 = self.p2_conv1(x)
        pool2    = self.pool2(p2_conv1)

        # pool 3
        p3_conv1 = self.p3_conv1(x)
        pool3 = self.pool3(p1_conv1)

        # pool 4
        p4_conv1 = self.p4_conv1(x)
        pool4 = self.pool4(p2_conv1)

		# attenionCRF
        confusionfea = self.atCRF(pool1, pool2, pool3, pool4)
        p_conv1 = self.p_conv1(confusionfea)
        p_bn1   = self.p_bn1(p_conv1)

        # pool 1 + pool 2
        # p_conv1 = self.p_conv1(pool1 + pool2)
        # p_bn1   = self.p_bn1(p_conv1)

        conv1 = self.conv1(x)
        bn1   = self.bn1(conv1)
        relu1 = self.relu1(p_bn1 + bn1)

        conv2 = self.conv2(relu1)
        return conv2

class SSMixer(nn.Module):
    def __init__(self, inChannels, outChannels):
        super(SSMixer, self).__init__()
        self.p1_conv1 = ConvBnRelu(inChannels, outChannels, 1) #3*3con,bn,relu
        self.p2_conv1 = ConvBnRelu(inChannels, outChannels, 1)
        self.p3_conv1 = ConvBnRelu(inChannels, outChannels, 1) #3*3con,bn,relu
        self.p4_conv1 = ConvBnRelu(inChannels, outChannels, 1)
        self.p5_conv1 = ConvBnRelu(inChannels, outChannels, 1)

        self.conv2 = ConvBnRelu(inChannels, outChannels, 1)

        self.pool1 = LeftPool()
        self.pool2 = TopPool()
        self.pool3 = RightPool()
        self.pool4 = BottomPool()

        self.atCRF = attentionCRF(inChannels, outChannels)

    def forward(self, x):
        global j
        # pool 1
        p1_conv1 = self.p1_conv1(x)
        pool1    = self.pool1(p1_conv1)

        # pool 2
        p2_conv1 = self.p2_conv1(x)
        pool2    = self.pool2(p2_conv1)

        # pool 3
        p3_conv1 = self.p3_conv1(x)
        pool3 = self.pool3(p1_conv1)

        # pool 4
        p4_conv1 = self.p4_conv1(x)
        pool4 = self.pool4(p2_conv1)

        p5 = self.p5_conv1(x)

        # feavis = FeatureVisualization(pool1, j)  # visualize enhanced structure-context features for each point
        # feavis.save_feature_to_img()
        # j=j+1

		# attenionCRF
        confusionfea = self.atCRF(pool1, pool2, pool3, pool4,p5)

        conv2 = self.conv2(confusionfea)
        return conv2

        # return conv2, pool1, pool2, pool3, pool4, p5

class myUpsample(nn.Module):
     def __init__(self):
         super(myUpsample, self).__init__()
         pass
     def forward(self, x):
         return x[:, :, :, None, :, None].expand(-1, -1, -1, 2, -1, 2).reshape(x.size(0), x.size(1), x.size(2)*2, x.size(3)*2)


import logging
import spotipy
import spotipy.util as util

import requests
from io import BytesIO
from PIL import Image

from transferImage import display

def getSongInfo(username):
  scope = 'user-read-currently-playing'
  token = util.prompt_for_user_token(username, scope)

  if token:
      sp = spotipy.Spotify(auth=token)
      result = sp.current_user_playing_track()

      if result is None:
        logging.warning("No song is currently playing")
      else:
        song = result["item"]["name"]
        artist = result["item"]["album"]["artists"][0]["name"]
        imageURL = result["item"]["album"]["images"][0]["url"]
        # Remaining seconds in the song
        timeLeft = (result["item"]["duration_ms"]/1000) - (result["progress_ms"]/1000)
        response = requests.get(imageURL)
        image = Image.open(BytesIO(response.content))

        logging.info("Song: %s ", song)
        logging.info("Artist: %s", artist)
        logging.info("Image URL: %s ", imageURL)
        logging.info("Time Left: %ss ", timeLeft)
        display(image, timeLeft)
  else:
      print("Can't get token for", username)


import numpy as np
import matplotlib
matplotlib.use('WXAgg')
import pylab as pl
import time
import equipment.LabJack.u3 as u3

lj = u3.U3()

N = 100
REFRESH_MS = 100
CLOCK_PER_MS = 4000 # clock is 4MHz

try:

    lj.configIO(EnableCounter0=True, EnableCounter1=True, NumberOfTimersEnabled = 2, TimerCounterPinOffset=6, FIOAnalog=0x0F)
    #timer 0 on FIO6
    #timer 1 on FIO7
    #counter0 on EIO0
    #counter1 on EIO2
    lj.getFeedback(u3.TimerConfig(timer = 0, TimerMode = 10)) # system timer LSW
    lj.getFeedback(u3.TimerConfig(timer = 1, TimerMode = 11)) # system timer MSW

    feedback_req = [
        u3.Timer(timer=0, UpdateReset = False, Value = 0, Mode = None),
        u3.Timer(timer=1, UpdateReset = False, Value = 0, Mode = None),
        u3.Counter(counter = 0, Reset=True),
        u3.Counter(counter = 1, Reset=False)
        ]

    fig = pl.figure(1)
    ax  = fig.add_subplot(111)

    ax.set_xlabel("time (ms)")
    ax.set_ylabel("Counts (Hz)")

    T  = np.zeros(N, dtype=np.uint64) # clock times
    C0 = np.zeros(N, dtype=np.uint32) # raw counts between measurements
    C0_rate = np.zeros(N, dtype=np.float) # rate in Hz

    c0 = 0
    c1 = 0
    t  = 0 # in clock ticks
    t_prev = -1*REFRESH_MS*CLOCK_PER_MS # in clock ticks

    ii = 0

    plot_line, = ax.plot(np.arange(0,N)*REFRESH_MS, C0_rate)
    plot_current_pos = ax.axvline(ii)

    def update_graph(ax):
        global T, C0, ii, t, t_prev

        ii += 1
        ii %= N

        tLSW, tMSW, c0, c1 = lj.getFeedback(feedback_req)

        #t = tMSW << 32 + tLSW
        t_prev = t
        t = tLSW

        dt = np.abs(t - t_prev) #% 0xFFFF

        #c0_rate = c0*1e3/REFRESH_MS
        c0_rate = c0 * CLOCK_PER_MS * 1.0e3 / dt  # Hz

        #T[ii] = t
        C0[ii] = c0
        C0_rate[ii] = c0_rate

        plot_line.set_ydata(C0_rate)
        plot_current_pos.set_xdata( (ii*REFRESH_MS,ii*REFRESH_MS) )
        #self.hist_i += 1
        #self.hist_i %= HIST_LEN

        ax.set_title("%i, %i, %e, dt=%g ms (%i ticks)" % (t, c0, c0_rate, dt*1.0/CLOCK_PER_MS, dt))

        if (ii % 10) == 0:
            ax.relim()
            ax.autoscale_view(scalex=False, scaley=True)

        fig.canvas.draw()

    timer = fig.canvas.new_timer(interval=REFRESH_MS)
    #timer.set_interval(REFRESH_MS)
    #._timer_set_interval(REFRESH_MS)
    timer.add_callback(update_graph, ax)
    timer.start()

    pl.show()

finally:
    lj.close()


import pygame

from GUI_Components.button import Button
from GUI_Components.square import square
from GUI_Components.image import image

class mainMenu():
    def __init__(self, rpg):
        #LoadButton Settings
        self.loadButton = Button(rpg, "Load")
        self.loadButton.startDefault(rpg, 75, 0)

        #New game button
        self.newGameButton = Button(rpg, "New Game")
        self.newGameButton.startDefault(rpg, 0, 0)

        #Quit Button
        self.quitButton = Button(rpg, "Quit")
        self.quitButton.startDefault(rpg, 150, 0)

        #Project Logo
        self.logo = image(rpg, 'CREATE Task Folder\Image Assets\GUI_images\ProjectLogo.png', "")#pylint: disable = anomalous-backslash-in-string
        self.logo.top = (rpg.settings.screen_height*.5) - (self.logo.height/2) - 200
        self.logo.left = (rpg.settings.screen_width*.5) - (self.logo.width/2)

    def draw(self):
        self.loadButton.draw()

        self.newGameButton.draw()

        self.quitButton.draw()

        self.logo.draw()

class choiceButtons():
    def __init__(self, rpg):
        self.choice1 = Button(rpg, "")
        self.choice1.choiceDefault(rpg, 0)

        self.choice2 = Button(rpg, "")
        self.choice2.choiceDefault(rpg, -70)

        self.choice3 = Button(rpg, "")
        self.choice3.choiceDefault(rpg, -140)

        self.choice4 = Button(rpg, "")
        self.choice4.choiceDefault(rpg, -210)

        self.choice5 = Button(rpg, "")
        self.choice5.choiceDefault(rpg, -280)

        self.choice6 = Button(rpg, "")
        self.choice6.choiceDefault(rpg, -350)

    def draw(self):
        self.choice1.draw()

        self.choice2.draw()

        self.choice3.draw()

        self.choice4.draw()

        self.choice5.draw()

        self.choice6.draw()

    def editChoices(self, choice1Text, choice2Text, choice3Text, choice4Text, choice5Text, choice6Text):
        self.choice1.msg = choice1Text
        self.choice2.msg = choice2Text
        self.choice3.msg = choice3Text
        self.choice4.msg = choice4Text
        self.choice5.msg = choice5Text
        self.choice6.msg = choice6Text

    def mouseEvents(self, rpg, mous_pos):
        if self.choice1.rect.collidepoint(mous_pos):
            rpg.playerConsole.newSlot = 1
            rpg.playerConsole.showNextText("", "No")
            rpg.playerConsole.newSlot = 0

class statSheet():
    def __init__(self, rpg):
        self.hpStat = Button(rpg, "HP: {}/{}".format(rpg.player.hp, rpg.player.maxhp))
        self.hpStat.statDefault(rpg, -420, 0)

        self.stamStat = Button(rpg, "Stamina: {}/{}".format(rpg.player.stamina, rpg.player.stamina_max))
        self.stamStat.statDefault(rpg, -350, 0)

        self.manaStat = Button(rpg, "Mana: {}/{}".format(rpg.player.mana, rpg.player.mana_max))
        self.manaStat.statDefault(rpg, -280, 0)

        self.speedStat = Button(rpg, "Speed: {}".format(rpg.player.speed))
        self.speedStat.statDefault(rpg, -210, 0)

        self.physAtckStat = Button(rpg, "Physical Attack: {}".format(rpg.player.physical_attack))
        self.physAtckStat.statDefault(rpg, -140, 0)

        self.magicAtckStat = Button(rpg,  "Magic Attack: {}".format(rpg.player.magic_attack))
        self.magicAtckStat.statDefault(rpg, -70, 0)

        self.physDefStat = Button(rpg, "Physical Defense: {}".format(rpg.player.physical_defense))
        self.physDefStat.statDefault(rpg, -420, 350)

        self.magicDefStat = Button(rpg, "Magic Defense: {}".format(rpg.player.magic_defense))
        self.magicDefStat.statDefault(rpg, -350, 350)

        self.fireResist = Button(rpg, "Fire Resistance: {}".format(rpg.player.fire_resist))
        self.fireResist.statDefault(rpg, -280, 350)

        self.poisonResist = Button(rpg, "Poison Resistance: {}".format(rpg.player.poison_resist))
        self.poisonResist.statDefault(rpg, -210, 350)

        self.waterResist = Button(rpg, "Water Resistance: {}".format(rpg.player.water_resist))
        self.waterResist.statDefault(rpg, -140, 350)

        self.earthResist = Button(rpg, "Earth Resistance: {}".format(rpg.player.earth_resist))
        self.earthResist.statDefault(rpg, -70, 350)

        self.windResist = Button(rpg, "Wind Resistance: {}".format(rpg.player.wind_resist))
        self.windResist.statDefault(rpg, -420, 700)

        self.evasion = Button(rpg, "Evasion: {}".format(rpg.player.evasion))
        self.evasion.statDefault(rpg, -350, 700)

        self.accuracyStat = Button(rpg, "Accuracy: {}".format(rpg.player.accuracy))
        self.accuracyStat.statDefault(rpg, -280, 700)

        self.critStat = Button(rpg, "Crit Chance: {}".format(rpg.player.crit_chance))
        self.critStat.statDefault(rpg, -210, 700)

        self.critMult = Button(rpg, "Crit Multiplier: {}".format(rpg.player.crit_mult))
        self.critMult.statDefault(rpg, -140, 700)

        self.luckStat = Button(rpg, "Luck: {}".format(rpg.player.luck))
        self.luckStat.statDefault(rpg, -70, 700)

    def updateStats(self, rpg):
        self.hpStat.msg = "HP: {}/{}".format(rpg.player.hp, rpg.player.maxhp)
        self.stamStat.msg = "Stamina: {}/{}".format(rpg.player.stamina, rpg.player.stamina_max)
        self.manaStat.msg = "Mana: {}/{}".format(rpg.player.mana, rpg.player.mana_max)
        self.speedStat.msg = "Speed: {}".format(rpg.player.speed)
        self.physAtckStat.msg = "Physical Attack: {}".format(rpg.player.physical_attack)
        self.magicAtckStat.msg = "Magic Attack: {}".format(rpg.player.magic_attack)
        self.physDefStat.msg = "Physical Defense: {}".format(rpg.player.physical_defense)
        self.magicDefStat.msg = "Magic Defense: {}".format(rpg.player.magic_defense)
        self.fireResist.msg = "Fire Resistance: {}".format(rpg.player.fire_resist)
        self.poisonResist.msg = "Poison Resistance: {}".format(rpg.player.poison_resist)
        self.waterResist.msg = "Water Resistance: {}".format(rpg.player.water_resist)
        self.earthResist.msg = "Earth Resistance: {}".format(rpg.player.earth_resist)
        self.windResist.msg = "Wind Resistance: {}".format(rpg.player.wind_resist)
        self.evasion.msg = "Evasion: {}".format(rpg.player.evasion)
        self.accuracyStat.msg = "Accuracy: {}".format(rpg.player.accuracy)
        self.critStat.msg = "Crit Chance: {}".format(rpg.player.crit_chance)
        self.critMult.msg = "Crit Multiplier: {}".format(rpg.player.crit_mult)
        self.luckStat.msg = "Luck: {}".format(rpg.player.luck)

    def showStats(self, rpg):
        self.updateStats(rpg)
        self.hpStat.draw()
        self.stamStat.draw()
        self.manaStat.draw()
        self.speedStat.draw()
        self.physAtckStat.draw()
        self.magicAtckStat.draw()
        self.physDefStat.draw()
        self.magicDefStat.draw()
        self.fireResist.draw()
        self.poisonResist.draw()
        self.waterResist.draw()
        self.earthResist.draw()
        self.windResist.draw()
        self.evasion.draw()
        self.accuracyStat.draw()
        self.critStat.draw()
        self.critMult.draw()
        self.luckStat.draw()

class borders:
    def __init__(self, rpg):
        #OuterBorder
        self.borderSquare = square(rpg)

        #MapBorder
        self.mapSquare = square(rpg)
        self.mapSquare.height = self.borderSquare.height - 420

        #TextBorder
        self.textSquare = square(rpg)
        self.textSquare.height = self.textSquare.height - 420
        self.textSquare.width = 1050

    def draw(self):
        self.borderSquare.draw()
        self.mapSquare.draw()
        self.textSquare.draw()

class swapButton:
    def __init__(self, rpg):
        self.swapButton = image(rpg, 'CREATE Task Folder\Image Assets\GUI_images\Bag.png', "Player Inventory")#pylint: disable = anomalous-backslash-in-string
        self.swapButton.width = (rpg.settings.screen_width - 1600)
        self.swapButton.height = 210
        self.swapButton.top = (rpg.settings.screen_height) - self.swapButton.height
        self.swapButton.left = 1050
        self.swapButton.border = True
        self.swapButton.clickable = True
        self.inventoryShow = False
        self.statsShow = True

    def mouseEvents(self, mous_pos):
        if self.swapButton.rect.collidepoint(mous_pos):
            if self.inventoryShow == True:
                self.inventoryShow = False
            else:
                self.inventoryShow = True
            self.swap()

    def swap(self):
        if self.swapButton.msg == "Player Inventory":
            self.stats()
        elif self.swapButton.msg == "Stat Sheet":
            self.inventory()

    def stats(self):
        self.swapButton.image = pygame.image.load('CREATE Task Folder\Image Assets\GUI_images\Stat Sheet.gif')#pylint: disable = anomalous-backslash-in-string
        self.swapButton.msg = "Stat Sheet"

    def inventory(self):
        self.swapButton.image = pygame.image.load('CREATE Task Folder\Image Assets\GUI_images\Bag.png')#pylint: disable = anomalous-backslash-in-string
        self.swapButton.msg = "Player Inventory"

    def draw(self):
        self.swapButton.draw()

class combatGUI:
    def __init__(self, rpg):

        self.playerIcon = image(rpg, rpg.player.icon, rpg.player.name)#pylint: disable = anomalous-backslash-in-string
        self.playerIcon.iconDefault(rpg, -315)
        self.playerSquare = square(rpg)
        self.playerSquare.combatDefault(rpg, -315)
        self.playerAttack = Button(rpg, "Attack")
        self.playerAttack.combatDefault(rpg, -367.5, 0)
        self.playerDefend = Button(rpg, "Defend")
        self.playerDefend.combatDefault(rpg, -367.5, 205)
        self.playerRest = Button(rpg, "Rest")
        self.playerRest.combatDefault(rpg, -315, 0)
        self.playerUse = Button(rpg, "Use Item")
        self.playerUse.combatDefault(rpg, -315, 205)

        self.equipped_allies = rpg.player.equipped_allies

        try:
            if self.equipped_allies[0]:
                #self.ally1Icon = image(rpg, rpg.player.equipped_allies[0].icon, rpg.player.equipped_allies[0].name)
                #self.ally1Icon.iconDefault(rpg, -210)
                self.ally1Square = square(rpg)
                self.ally1Square.combatDefault(rpg, -210)
                self.ally1Attack = Button(rpg, "Attack")
                self.ally1Attack.combatDefault(rpg, -262.5, 0)
                self.ally1Defend = Button(rpg, "Defend")
                self.ally1Defend.combatDefault(rpg, -262.5, 205)
                self.ally1Rest = Button(rpg, "Rest")
                self.ally1Rest.combatDefault(rpg, -210, 0)
                self.ally1Use = Button(rpg, "Use Item")
                self.ally1Use.combatDefault(rpg, -210, 205)

            if self.equipped_allies[1]:
                #self.ally2Icon = image(rpg, rpg.player.equipped_allies[1].icon, rpg.player.equipped_allies[1].name)
                #self.ally2Icon.iconDefault(rpg, -105)
                self.ally2Square = square(rpg)
                self.ally2Square.combatDefault(rpg, -105)
                self.ally2Attack = Button(rpg, "Attack")
                self.ally2Attack.combatDefault(rpg, -157.5, 0)
                self.ally2Defend = Button(rpg, "Defend")
                self.ally2Defend.combatDefault(rpg, -157.5, 205)
                self.ally2Rest = Button(rpg, "Rest")
                self.ally2Rest.combatDefault(rpg, -105, 0)
                self.ally2Use = Button(rpg, "Use Item")
                self.ally2Use.combatDefault(rpg, -105, 205)

            if self.equipped_allies[2]:
                #self.ally3Icon = image(rpg, rpg.player.equipped_allies[2].icon, rpg.player.equipped_allies[2].name)
                #self.ally3Icon.iconDefault(rpg, 0)
                self.ally3Square = square(rpg)
                self.ally3Square.combatDefault(rpg, 0)
                self.ally3Attack = Button(rpg, "Attack")
                self.ally3Attack.combatDefault(rpg, -52.5, 0)
                self.ally3Defend = Button(rpg, "Defend")
                self.ally3Defend.combatDefault(rpg, -52.5, 205)
                self.ally3Rest = Button(rpg, "Rest")
                self.ally3Rest.combatDefault(rpg, 0, 0)
                self.ally3Use = Button(rpg, "Use Item")
                self.ally3Use.combatDefault(rpg, 0, 205)
        except:
            pass

        self.background = image(rpg, "CREATE Task Folder\Image Assets\Transparent.png", "")
        self.background.left, self.background.top = 0, 0
        self.background.width, self.background.height = 1050, 660

        self.enemyImage = image(rpg, self.enemy.image, "")
        self.enemyImage.left, self.enemyImage.top = 250, 220
        self.enemyImage.width, self.enemyImage.height = 550, 420
        self.enemyImage.transparent = True

        self.enemyInfo = Button(rpg, "{} - Level: {}".format(self.enemy.name, self.enemy.level))
        self.enemyInfo.width, self.enemyInfo.height = 550, 35
        self.enemyInfo.left, self.enemyInfo.top = 250, 80
        self.enemyInfo.clickable = False

        self.enemyHP = Button(rpg, "HP: {}/{}".format(self.enemy.hp, self.enemy.maxhp))
        self.enemyHP.width, self.enemyHP.height = 275, 35
        self.enemyHP.left, self.enemyHP.top = 250, 115
        self.enemyHP.transparent = True
        self.enemyHP.clickable = False

        self.enemyHPbar = Button(rpg, "")
        self.enemyHPbar.width, self.enemyHPbar.height = 275, 35
        self.enemyHPbar.left, self.enemyHPbar.top = 250, 115
        self.enemyHPbar.button_color = (200, 0, 0)
        self.enemyHPbar.text_color = (200, 0, 0)
        self.enemyHPbar.clickable = False

        self.enemyStamina = Button(rpg, "Stamina: {}/{}".format(self.enemy.stamina, self.enemy.stamina_max))
        self.enemyStamina.width, self.enemyStamina.height = 275, 35
        self.enemyStamina.left, self.enemyStamina.top = 525, 115
        self.enemyStamina.transparent = True
        self.enemyStamina.clickable = False

        self.enemyStaminaBar = Button(rpg, "")
        self.enemyStaminaBar.width, self.enemyStaminaBar.height = 275, 35
        self.enemyStaminaBar.left, self.enemyStaminaBar.top = 525, 115
        self.enemyStaminaBar.button_color = (0, 200, 0)
        self.enemyStaminaBar.text_color = (0, 200, 0)
        self.enemyStaminaBar.clickable = False

        self.enemyMana = Button(rpg, "Mana: {}/{}".format(self.enemy.mana, self.enemy.mana_max))
        self.enemyMana.width, self.enemyMana.height = 550, 35
        self.enemyMana.left, self.enemyMana.top = 250, 150
        self.enemyMana.transparent = True
        self.enemyMana.clickable = False

        self.enemyManaBar = Button(rpg, "")
        self.enemyManaBar.width, self.enemyManaBar.height = 550, 35
        self.enemyManaBar.left, self.enemyManaBar.top = 250, 150
        self.enemyManaBar.button_color = (0, 0, 200)
        self.enemyManaBar.text_color = (0, 0, 200)
        self.enemyManaBar.clickable = False

        self.enemyStats = False

    def mouseEvents(self, mous_pos):
        if self.enemyImage.rect.collidepoint(mous_pos):
            if self.enemyStats == False:
                self.enemyStats = True
            else:
                self.enemyStats = False

    def update(self):
        self.enemyMana.msg = "Mana: {}/{}".format(self.enemy.mana, self.enemy.mana_max)
        try:
            self.enemyManaBar.width = 275 * ((self.enemy.mana/self.enemy.mana_max))
        except Exception:
            self.enemyManaBar.width = 0
            self.enemyMana.transparent = False

        self.enemyStamina.msg = "Stamina: {}/{}".format(self.enemy.stamina, self.enemy.stamina_max)
        try:
            self.enemyStaminaBar.width = 275 * ((self.enemy.stamina/self.enemy.stamina_max))
        except Exception:
            self.enemyStaminaBar.width = 0
            self.enemyStamina.transparent = False

        self.enemyHP.msg = "HP: {}/{}".format(self.enemy.hp, self.enemy.maxhp)
        try:
            self.enemyHPbar.width = 275 * ((self.enemy.hp/self.enemy.maxhp))
        except Exception:
            self.enemyHPbar.width = 0
            self.enemyHP.transparent = False

    def draw(self):
        self.update()
        self.background.draw()
        self.enemyImage.draw()
        self.playerIcon.draw()
        self.playerAttack.draw()
        self.playerDefend.draw()
        self.playerRest.draw()
        self.playerUse.draw()
        self.playerSquare.draw()
        try:
            if self.equipped_allies[0]:
                self.ally1Attack.draw()
                self.ally1Defend.draw()
                self.ally1Rest.draw()
                self.ally1Use.draw()
                self.ally1Square.draw()

            if self.equipped_allies[1]:
                self.ally2Attack.draw()
                self.ally2Defend.draw()
                self.ally2Rest.draw()
                self.ally2Use.draw()
                self.ally2Square.draw()

            if self.equipped_allies[2]:
                self.ally3Attack.draw()
                self.ally3Defend.draw()
                self.ally3Rest.draw()
                self.ally3Use.draw()
                self.ally3Square.draw()
        except:
            pass

        if self.enemyStats == True:
            self.enemyInfo.draw()
            self.enemyHPbar.draw()
            self.enemyHP.draw()
            self.enemyStaminaBar.draw()
            self.enemyStamina.draw()
            self.enemyManaBar.draw()
            self.enemyMana.draw()

class profilePic:
    def __init__(self, rpg):
        self.profilePic = image(rpg, 'CREATE Task Folder\Image Assets\Player_Images\Commoner.png', rpg.player.profession + " EXP: {}/{}".format(rpg.player.exp, rpg.player.exp_cap))#pylint: disable = anomalous-backslash-in-string
        self.profilePic.font.set_bold(True)
        self.profilePic.width = (rpg.settings.screen_width - 1600)
        self.profilePic.height = 210
        self.profilePic.top = (rpg.settings.screen_height) - (self.profilePic.height*2)
        self.profilePic.left = 1050
        self.profilePic.border = True
        self.profilePic.textMidBottom = True

    def swapImage(self, path):
        self.profilePic.image = pygame.image.load(path)

    def draw(self):
        self.profilePic.draw()

class playerConsole:
    def __init__(self, rpg):
        self.clicked = False
        self.newSlot = 0
        self.slot1Taken = 0
        self.slot2Taken = 0
        self.slot3Taken = 0
        self.slot4Taken = 0
        self.slot5Taken = 0
        self.icon5 = image(rpg, "CREATE Task Folder\Image Assets\Transparent.png", "")
        self.icon5.consoleDefault(rpg, 0)
        self.slot5 = Button(rpg, "")
        self.slot5.consoleTextDefault(rpg, 0)
        self.icon4 = image(rpg, "CREATE Task Folder\Image Assets\Transparent.png", "")
        self.icon4.consoleDefault(rpg, 132)
        self.slot4 = Button(rpg, "")
        self.slot4.consoleTextDefault(rpg, 132)
        self.icon3 = image(rpg, "CREATE Task Folder\Image Assets\Transparent.png", "")
        self.icon3.consoleDefault(rpg, 264)
        self.slot3 = Button(rpg, "")
        self.slot3.consoleTextDefault(rpg, 264)
        self.icon2 = image(rpg, "CREATE Task Folder\Image Assets\Transparent.png", "")
        self.icon2.consoleDefault(rpg, 396)
        self.slot2 = Button(rpg, "")
        self.slot2.consoleTextDefault(rpg, 396)
        self.icon1 = image(rpg, "CREATE Task Folder\Image Assets\Transparent.png", "")
        self.icon1.consoleDefault(rpg, 528)
        self.slot1 = Button(rpg, "")
        self.slot1.consoleTextDefault(rpg, 528)

        self.arrow = image(rpg, "CREATE Task Folder\Image Assets\Transparent.png", "")
        self.arrow.width, self.arrow.height = 80, 60
        self.arrow.top, self.arrow.left = 600, 970
        self.arrow.transparent = True

    def drawConsole(self):
        self.slot1.draw()
        self.icon1.draw()
        self.slot2.draw()
        self.icon2.draw()
        self.slot3.draw()
        self.icon3.draw()
        self.slot4.draw()
        self.icon4.draw()
        self.slot5.draw()
        self.icon5.draw()
        if self.clicked == False:
            self.arrow.draw()

    def showNextText(self, rpg, nextText, nextTextPart2, nextIcon):
        self.slot5.msg = self.slot4.msg
        self.slot5.msg2 = self.slot4.msg2
        self.icon5.image = self.icon4.image
        self.slot4.msg = self.slot3.msg
        self.slot4.msg2 = self.slot3.msg2
        self.icon4.image = self.icon3.image
        self.slot3.msg = self.slot2.msg
        self.slot3.msg2 = self.slot2.msg2
        self.icon3.image = self.icon2.image
        self.slot2.msg = self.slot1.msg
        self.slot2.msg2 = self.slot1.msg2
        self.icon2.image = self.icon1.image
        self.slot1.msg = nextText
        self.slot1.msg2 = nextTextPart2
        self.icon1.image = nextIcon

        while self.clicked == False:
            self.mouseEvents(rpg)
            rpg._update_screen()
        self.clicked = False

    def mouseEvents(self, rpg):
        for event in pygame.event.get():
            if event.type == pygame.MOUSEBUTTONDOWN:
                mous_pos = pygame.mouse.get_pos()
                if rpg.borders.mapSquare.rect.collidepoint(mous_pos):
                    self.clicked = True

    def resetConsole(self):
        self.slot5.msg = ""
        self.slot4.msg = ""
        self.slot3.msg = ""
        self.slot2.msg = ""
        self.slot1.msg = ""
        self.slot5.msg2 = ""
        self.slot4.msg2 = ""
        self.slot3.msg2 = ""
        self.slot2.msg2 = ""
        self.slot1.msg2 = ""


import math
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np

class EquationsMixin:
    def leonard_jones_potential(self, distance):
        """
        eq (1) in paper, error in paper? Following cited paper.
        Possibly lennard jones.
        """
        # ignore divide by 0 and nan subtraction
        with np.errstate(divide='ignore', invalid='ignore'):
            div = (self.SIGMA / distance)
            div6 = div ** 6
            result = self.e * (div6 ** 6 - 2 * div6)
            return np.nan_to_num(result, 0)

    def bond_stretching_potential(self, distance):
        """
        eq (2) in paper, only applies if the atoms are neighbors
        is_next should be 0-1 matrix
        """
        return self.BETA * (distance - self.bond_length) ** 2

    def total_potential(self, distance, is_next):
        """
        total potential in terms of distance
        """
        lj = self.leonard_jones_potential(distance)
        bond = self.bond_stretching_potential(distance, is_next)
        return np.nan_to_num(bond, 0)

    def potential_from_indices(self, i, j, k, l):
        # j and l are the spot index, change to coordinates
        j_loc = self.index_to_location(j)
        l_loc = self.index_to_location(l)

        # distance between j and l
        distance = self.distance(j_loc, l_loc)

        # boolean matrices or different properties
        is_adjacent_atom = (np.abs(k - i) == 1)
        is_the_same_atom = i == k

        full_lj = self.leonard_jones_potential(distance)
        full_bond = self.bond_stretching_potential(distance)

        bond = (1 * is_adjacent_atom) * full_bond
        lj = 1 * np.logical_not(is_adjacent_atom | is_the_same_atom) * full_lj
        return lj + bond

    def objective_value(self, solution):
        total = 0
        ones = filter(lambda t: t[1] == 1, enumerate(solution))
        for (ij, one) in ones:
            [i, j] = self.q_to_ij(ij)
            for (kl, one) in ones:
                [k, l] = self.q_to_ij(kl)
                total += self.potential_from_indices(i, j, k, l)
        return total

class UtilsMixin:
    def distance(self, x1, x2):
        """
        Computes the euclidean distance between points in R^3
        """
        return self.CELL_LENGTH * np.sum((x1 - x2) ** 2, 0) ** 0.5

    def ij_to_q(self, i, j):
        """
        Returns the corresponding index in the hamiltonian of the binary variable
        corresponding to atom i being in spot j
        """
        # flattens matrix of binary vars to array
        return i * self.N_CELLS + j

    def q_to_ij(self, q_index):
        """
        Given a binary variable index returns i, j corresponding to atom i being in spot j
        """
        return (np.floor(q_index / self.N_CELLS), q_index % self.N_CELLS)

    def index_to_location(self, i):
        """
        Returns the euclidean coordinates for spot i
        """
        div = np.array([i / self.LATTICE_LENGTH ** d for d in range(3)])
        mod = np.floor(div) % self.LATTICE_LENGTH
        return mod

    def is_solution_valid(self, X):
        """
        Input: np solution matrix
        Returns a boolean if the solution fulfills basic
        problem constraints
        """
        every_atom_in_one_spot = (np.sum(X, 1) == 1).all()
        spot_has_zero_or_one_atoms = (np.sum(X, 0) <= 1).all()
        correct_number_of_atoms = np.sum(X) == self.N_ATOMS
        return every_atom_in_one_spot and spot_has_zero_or_one_atoms and correct_number_of_atoms

    def sample_to_x_ij_matrix(self, sample):
        """
        Turns a sample from the form of a dict {(i,j): 0|1, ...} into a np
        0-1 matrix of size N_ATOMS x N_CELLS
        """
        X = np.zeros([self.N_ATOMS, self.N_CELLS])
        ones = filter(lambda i: i[1] == 1, dict(sample).items())
        for qi, _ in ones:
            (i, j) = self.q_to_ij(qi)
            X[math.floor(i), j] = 1
        return X

    def sample_to_positions(self, sample):
        """
        Turns a sample from the form of a dict {(i,j): 0|1, ...} into a np
        matrix of size N_ATOMS x 3 which is a list of the grid positions in R^3
        """
        positions = np.zeros([self.N_ATOMS, 3])
        ones = filter(lambda i: i[1] == 1, dict(sample).items())
        for qi, _ in ones:
            (i, j) = self.q_to_ij(qi)
            positions[math.floor(i), :] = self.index_to_location(j)
        return positions

    def plot_3d(self, positions):
        fig = plt.figure()
        ax = fig.add_subplot(111, projection='3d')

        ax.scatter(positions[:, 0], positions[:, 1],
                   positions[:, 2], s=250, c='r')
        ax.plot(positions[:, 0], positions[:, 1], positions[:, 2])

        print("DISTANCES:")
        for i in range(self.N_ATOMS - 1):
            print(f"{i} to {i+1}",
                  self.distance(positions[i, :], positions[i + 1, :]))

        atoms = f'{self.N_ATOMS} atoms'
        lattice = f'{self.LATTICE_LENGTH}x{self.LATTICE_LENGTH} lattice'
        plt.title(f'{atoms} in a {lattice}')
        plt.show()


import json
import scrapy
from locations.items import GeojsonPointItem
from locations.hours import OpeningHours

DAY_MAPPING = {
    'MONDAY': 'Mo',
    'TUESDAY': 'Tu',
    'WEDNESDAY': 'We',
    'THURSDAY': 'Th',
    'FRIDAY': 'Fr',
    'SATURDAY': 'Sa',
    'SUNDAY': 'Su',
}

COOKIES = {
            "bm_sz": "04B124C1C96D68082A9F61BAAAF0B6D5~YAAQdjsvF22E8Xl6AQAACr1VfAxPEt+enarZyrOZrBaNvyuX71lK5QPuDR/FgDEWBZVMRhjiIf000W7Z1PiAjxobrz2Y5LcYMH3CvUNvpdS3MjVLUMGwMEBCf9L5nD5Gs9ho2YL8T7Tz7lYvpolvaOlJnKrHyhCFxxk/uyBZ2G/0QrGKLwSaCQShDsz7ink=",
            "_abck": "440E40C406E69413DCCC08ABAA3E9022~-1~YAAQdjsvF26E8Xl6AQAACr1VfAYznoJdJhX7TNIZW1Rfh6qRhzquXg+L1TWoaL7nZUjXlNls2iPIKFQrCdrWqY/CNXW+mHyXibInMflIXJi5VVB/Swq53kABYJDuXYSlCunYvJAzMSr1q12NOYswz134Y8HRNzVWhkb2jMS5whmHxS/v0vniIvS1TQtKjEQlMGzQYmN41CmLX0JobipQhDtUB4VyNwztb2DCAZiqDX8BLwWg7h/DtPd4158qU69hNhayFTgWmD76/MiR8/T536tMmcoRyWLl4fEtP/XUmKOcksuZO7dbfNxXBffTxIXPYwf1eO77LNuZTCQq5kfsGZLJX8ODju2KSjnIF1vdnyHAe98FDIm+hw==~-1~-1~-1"
        }

HEADERS = {
    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
    'accept-encoding': 'gzip, deflate, br',
    'cache-control': 'max-age=0',
    'referer': 'https://www.tesco.com/store-locator/?q=london&qp=london&l=en',
    'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"',
    'sec-ch-ua-mobile': '?0',
    'sec-fetch-dest': 'document',
    'sec-fetch-mode': 'navigate',
    'sec-fetch-site': 'same-origin',
    'sec-fetch-user': '?1',
    'upgrade-insecure-requests': '1',
    'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36',
    }

class TescoSpider(scrapy.Spider):
    name = "tesco"
    item_attributes = {'brand': "Tesco"}
    allowed_domains = ["www.tesco.com"]
    download_delay = 0.3
    custom_settings = {
        'USER_AGENT': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36',
    }

    def store_hours(self, store_hours):
        opening_hours = OpeningHours()
        store_hours = json.loads(store_hours)

        for day in store_hours:
            closed = day['isClosed']
            if not closed:
                opening_hours.add_range(day=DAY_MAPPING[day['day']],
                                        open_time=str(day['intervals'][0]['start']).zfill(4),
                                        close_time=str(day['intervals'][0]['end']).zfill(4),
                                        time_format='%H%M')

        return opening_hours.as_opening_hours()

    def start_requests(self):
        url = 'https://www.tesco.com/store-locator/sitemap.xml'

        yield scrapy.http.FormRequest(
            url=url,
            method='GET',
            dont_filter=True,
            cookies=COOKIES,
            headers=HEADERS,
            callback=self.parse
            )

    def parse(self, response):
        response.selector.remove_namespaces()
        urls = response.xpath('//url/loc/text()').extract()

        # Exclude location subpages for at-store services
        service_paths = ['petrol-filling-station', 'cafe', 'travel-money', 'f-f-clothing', 'pharmacy']

        for url in urls:
            if not any(service_path in url for service_path in service_paths):

                yield scrapy.http.FormRequest(
                    url=url,
                    method='GET',
                    dont_filter=True,
                    cookies=COOKIES,
                    headers=HEADERS,
                    callback=self.parse_store
                )

    def parse_store(self, response):
        city_page = response.xpath('//span[@class="Hero-title Hero-title--top"]/text()').extract_first()

        if not city_page:  # and is a store page
            store_details = response.xpath('//script[@type="application/json" and contains(text(),"storeID")]/text()').extract_first()
            if store_details:
                store_data = json.loads(store_details)
                ref = store_data['storeID']
                name = store_data['pageName']
                addr_1 = response.xpath('//div[@class="Core-infoWrapper"]//span[@class="Address-field Address-line1"]/text()').extract_first()
                addr_2 = response.xpath('//div[@class="Core-infoWrapper"]//span[@class="Address-field Address-line2"]/text()').extract_first()
                if addr_2:
                    addr_full = ', '.join([addr_1.strip(), addr_2.strip()])
                else:
                    addr_full = addr_1

                properties = {
                    'ref': ref,
                    'name': name,
                    'addr_full': addr_full,
                    'city': response.xpath('//div[@class="Core-infoWrapper"]//span[@class="Address-field Address-city"]/text()').extract_first(),
                    'postcode': response.xpath('//div[@class="Core-infoWrapper"]//span[@class="Address-field Address-postalCode"]/text()').extract_first(),
                    'country': 'GB',
                    'lat': response.xpath('//div[@class="Core-infoWrapper"]//span[@class="Address-coordinates"]/meta[@itemprop="latitude"]/@content').extract_first(),
                    'lon': response.xpath('//div[@class="Core-infoWrapper"]//span[@class="Address-coordinates"]/meta[@itemprop="longitude"]/@content').extract_first(),
                    'phone': response.xpath('//div[@class="Core-infoWrapper"]//span[@itemprop="telephone"]/text()').extract_first(),
                    'website': response.url
                }

                hours = response.xpath('//div[@class="Core-infoWrapper"]//@data-days').extract_first()
                if hours:
                    properties['opening_hours'] = self.store_hours(hours)

                yield GeojsonPointItem(**properties)


from django import test
from django.core import urlresolvers
from django.template import response

from loja.vitrine import forms, views

class ContatoViewTestCase(test.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.factory = test.RequestFactory()

    def test_deve_responder_pela_url_contato(self):
        r = urlresolvers.resolve("/contato")
        expected_func = views.Contato.as_view()
        got_func = r.func
        self.assertEqual(expected_func.func_name, got_func.func_name)

    def test_deve_renderizar_template_contato_html(self):
        self.assertEqual("contato.html", views.Contato.template_name)

    def test_get_deve_retornar_template_response(self):
        request = self.factory.get("/contato")
        v = views.Contato()
        resp = v.get(request)
        self.assertIsInstance(resp, response.TemplateResponse)
        self.assertEqual(v.template_name, resp.template_name)

    def test_get_deve_incluir_instancia_do_formulario_de_contato_no_contexto(self):
        request = self.factory.get("/contato")
        v = views.Contato()
        resp = v.get(request)
        self.assertIsInstance(resp.context_data["form"], forms.Contato)


#!/usr/bin/env python3

"""python vast module

Disclaimer: `await` does not work in the python3.7 repl,
use either python3.8 or ipython.

Example:

    Create a connector to a VAST server:
    > from pyvast import VAST
    > vast = VAST(binary="/opt/tenzir/bin/vast")
    Test if the connector works:
    > await vast.test_connection()
    Extract some Data:
    > data = await vast.export(max_events=10).json(":addr == 192.168.1.104").exec()

"""

import asyncio
import logging

class VAST:
    """A VAST node handle"""

    def __init__(self, binary="vast", endpoint="localhost:42000"):
        self.logger = logging.getLogger("vast")
        self.binary = binary
        self.endpoint = endpoint
        self.call_stack = []
        self.logger.debug(f"VAST client configured to use endpoint {self.endpoint}")

    async def __spawn(self, *args, stdin=None):
        """Spawns a process asynchronously."""
        return await asyncio.create_subprocess_exec(
            self.binary,
            "-e",
            self.endpoint,
            *args,
            stdin=stdin,
            stdout=asyncio.subprocess.PIPE,
            stderr=asyncio.subprocess.PIPE,
        )

    async def test_connection(self):
        """Checks if the configured endpoint is reachable"""
        proc = await self.__spawn("status")
        await proc.wait()
        return proc.returncode == 0

    async def exec(self, stdin=None):
        self.logger.debug(f"Executing call stack: {self.call_stack}")
        if not stdin:
            proc = await self.__spawn(*self.call_stack)
        else:
            self.logger.debug(f"Forwarding stdin {stdin}")
            proc = await self.__spawn(*self.call_stack, stdin=asyncio.subprocess.PIPE)
            proc.stdin.write(str(stdin).encode())
            await proc.stdin.drain()
            proc.stdin.close()
        self.call_stack = []
        return proc

    def __getattr__(self, name, **kwargs):
        """Chains every unknown method call to the internal call stack."""
        if name.endswith("_"):
            # trim trailing underscores to overcome the 'import' keyword
            name = name[:-1]
        self.call_stack.append(name)

        def method(*args, **kwargs):
            if kwargs:
                for k, v in kwargs.items():
                    if v is True:
                        self.call_stack.append(f"--{k.replace('_','-')}")
                    else:
                        self.call_stack.append(f"--{k.replace('_','-')}={v}")
            if args:
                self.call_stack.extend(args)
            return self

        return method


import torch
from torch import nn

def backward_hook(module, grad_input, grad_output):
    #print(module, gradInput, gradOutput)
    #print(copy.deepcopy('{0}'.format(str(i))), module)
    # for i in grad_input:
    #     print(i.shape)
    #print(module, grad_input[0].shape, grad_input[1].shape, grad_output[0].shape)
    module.grad_inputs = grad_input[0].data.clone()
    module.grad_outputs = grad_output[0].data.clone()

def forward_hook(module, m_input, m_output):
    #print(module, gradInput, gradOutput)
    #print(copy.deepcopy(name.format()), module)
    module.m_inputs = m_input[0].data.clone()
    module.m_outputs = m_output[0].data.clone()

def add_hooks(net):
    for name, module in net.named_modules():
        if 'layer' in name and 'conv' in name:
            module.register_forward_hook(forward_hook)
            module.register_backward_hook(backward_hook)

def init_cond_stats(net):
    stats = {
        'forwards_cond': {},
        'backwards_cond': {},
        'forwards_fbnorm': {},
        'backwards_fbnorm': {},
        'forwards_shape': {},
        'backwards_shape': {}
    }
    for name, _ in net.named_modules():
        if 'layer' in name and 'conv' in name:
            for key in stats:
                stats[key][name] = []

    return stats

import numpy as np
from collections import OrderedDict

def init_grad_stats(net):
    stats = OrderedDict()
    stats['forwards_cond'] = OrderedDict()
    stats['backwards_cond'] = OrderedDict()

    for name, _ in net.named_modules():
        if 'layer' in name and 'conv' in name:
            for key in stats:
                stats[key][name] = []

    return stats

def add_grad_stats(net, stats):
    with torch.no_grad():
        for name, module in net.named_modules():
            if 'layer' in name and 'conv' in name:
                stats['forwards_cond'][name] += module.forwards_cond
                stats['backwards_cond'][name] += module.backwards_cond

                # g = module.weight.grad1.flatten(1)
                # g = (g - g.mean(dim=1, keepdim=True)) / (g.std(dim=1, keepdim=True) + 1e-5)
                # corr = g.mm(g.T) / g.shape[-1]
                # lower_corr = []
                # for i in range(corr.shape[0]):
                #     lower_corr.append(corr[i][i + 1:])

                # lower_corr = torch.cat(lower_corr)

                # results['corr'] = lower_corr

def add_cond_stats(net, stats):
    with torch.no_grad():
        for name, module in net.named_modules():
            if 'layer' in name and 'conv' in name and module.kernel_size == (1, 1):
                inputs = module.m_inputs.flatten(2)
                grads = module.grad_outputs.flatten(2)

                # I = inputs.bmm(inputs.transpose(1, 2))
                # G = grads.bmm(grads.transpose(1, 2))

                _, s1, _ = inputs.svd(compute_uv=False)
                _, s2, _ = grads.svd(compute_uv=False)

                forward_cond_nums = (
                    s1[:, 0].log() - s1[:, -1].log()).detach().cpu()
                backward_cond_nums = (
                    s2[:, 0].log() - s2[:, -1].log()).detach().cpu()
                forwards_fbnorm = torch.norm(inputs, p='fro', dim=(1, 2))
                backwards_fbnorm = torch.norm(grads, p='fro', dim=(1, 2))

                #     for g in grads:
                #         _, s, _ = g.svd(compute_uv=False)
                #         s = s.detach().cpu()
                #         backward_cond_nums.append(s[0].log() - s[-1].log())

                stats['forwards_cond'][name].append(forward_cond_nums)
                stats['backwards_cond'][name].append(backward_cond_nums)
                stats['forwards_fbnorm'][name].append(forwards_fbnorm)
                stats['backwards_fbnorm'][name].append(backwards_fbnorm)
                stats['forwards_shape'][name] = inputs.size()[1:]
                stats['backwards_shape'][name] = grads.size()[1:]


import requests
import json
import pandas
from pandas.io.json import json_normalize
from tabulate import tabulate
from datetime import datetime

try:
    # API configurations are stored in separate JSON file. Read that json to extract the details
    f = open('config.json',)
    config = json.load(f)

    headers = config["headers"]

    # Get the response from API url
    response = requests.request("GET", config["api_name"]["url"], headers=headers, params=config["api_name"]["querystring"])
    data = response.text

    # Parse the response text
    parsed_data = json.loads(data)

    # Extract the method name from url
    file_name=config["api_name"]["url"].split('/')[-1]

    # Convert the json response to dataframe
    df_result = json_normalize(parsed_data['finance']['result'])

    # Convert epoch timestamp to Datetime
    convert = lambda x: datetime.fromtimestamp(x / 1e3)
    df_result['startDateTime'] = df_result['startDateTime'].apply(convert)

    # Display dataframe in tabular format
    print(tabulate(df_result, headers='keys', tablefmt='psql'))
    print("Creating file....")
    # Create a CSV from dataframe
    df_result.to_csv(file_name+'.csv',index=False)
    print("File has been created..!!")

    # Raise error in case of failure
    response.raise_for_status()

except requests.exceptions.HTTPError as httpErr:
    print ("Http Error:", httpErr)
except requests.exceptions.ConnectionError as connErr:
    print ("Error Connecting:", connErr)
except requests.exceptions.Timeout as timeOutErr:
    print ("Timeout Error:", timeOutErr)
except requests.exceptions.RequestException as reqErr:
    print ("Something Else:", reqErr)


from .backends import Backend, PickleBackend
from .utils import *
from collections import Iterable
from abc import ABC
from inspect import signature
from PIL import Image

import scvelo as scv
import scanpy as sc
import anndata

import numpy as np
import matplotlib as mpl
import re
import traceback
import warnings

class Module(ABC):

    _backends = dict(pickle=PickleBackend)
    _extensions = dict(pickle='.pickle')

    def __init__(self, backend, **kwargs):
        if isinstance(backend, Backend):
            self._backend = backend
        else:
            assert isinstance(backend, str)
            backend_type = self._backends.get(backend, None)
            if backend_type is None:
                raise ValueError(f'Unknown backend type: `{backend}`.'
                                  ' Supported backends are: `{", ".join(self._backends.keys())}`.')
            if 'ext' not in kwargs:
                kwargs['ext'] = self._extensions.get(backend, '.scdata')
            self._backend = backend_type(**kwargs)

        for k, fn in self._functions.items():
            setattr(self, k, fn)

    @property
    def backend(self):
        return self._backend

    @backend.setter
    def backend(self, _):
        raise RuntimeError('Setting backend is disallowed. To change the directory, try `dir` attribute of `backend.`')

    def _clear(self, verbose=1, *, separator=None):
        self.backend._clear(verbose, self._type, separator=separator)

    def clear(self, verbose=1):
        self._clear(verbose)

    def __iter__(self):  # to list available functions
        return iter(self._functions.keys())

    def __repr__(self):
        return f'<{self.__module__}.{self._type}>'

    def _create_cache_fn(self, *args, default_fname=None):

        def wrapper(adata, fname=None, recache=False, verbose=True, skip=False, *args, **kwargs):
            try:
                if fname is None:
                    fname = default_fname
                if not fname.endswith(self.backend.ext):
                    fname += self.backend.ext

                if recache:
                    possible_vals = set(args) | set(kwargs.values())
                    return self.backend.save(adata, fname, attrs, keys,
                                             skip=skip, is_optional=is_optional,
                                             possible_vals=possible_vals, verbose=verbose)

                if (self.backend.dir / fname).is_file():
                    if verbose:
                        print(f'Loading data from: `{fname}`.')

                    return self.backend.load(adata, fname, verbose=verbose, skip=skip)

                return False

            except Exception as e:
                if not isinstance(e, FileNotFoundError):
                    if recache:
                        print(traceback.format_exc())
                else:
                    print(f'No cache found in `{self.backend.dir / fname}`.')

                return False

        # if you're here because of the doc, you're here correctly
        if len(args) == 1:
            collection = args[0]
            if isinstance(collection, dict):
                attrs = tuple(collection.keys())
                keys = tuple(collection.values())
            elif isinstance(collection, Iterable) and len(next(iter(collection))) == 2:
                attrs, keys = tuple(zip(*collection))
            else:
                raise RuntimeError('Unable to decode the args of length 1.')
        elif len(args) == 2:
            attrs, keys = args
            if isinstance(attrs, str):
                attrs = (attrs, )
            if isinstance(keys, str):
                keys = (keys, )
        else:
            raise RuntimeError('Expected the args to be of length 1 or 2.')

        pat = re.compile(r'.*_opt')
        is_optional = tuple(pat.match(a) is not None for a in attrs)

        # strip the postfix
        pat = re.compile(r'(:?_opt)|(?:_cache\d+)')
        attrs = tuple(pat.sub('', a) for a in attrs)

        return wrapper

    def cache(self, *args, **kwargs):
        '''
        Create a caching function.

        Params
        --------
        args: Dict[Str, Union[Str, Iterable[Union[Str, re._pattern_type]]]]
            attributes are supplied as dictionary keys and
            values as dictionary values (need not be an `Iterable`)
            for caching multiple attributes of the same name,
            append to them postfixes of the following kind: `_cache1, _cache2, ...`
            there are also other ways of specifying this, please
            refer the source code of `_create_cache_fn`
        default_fname: Str
            default filename where to save the data
        default_fn: Callable, optional (default: `None`)
            function to call before caching the values

        Returns
        --------
        caching_function: Callable
            caching function accepting as the first argument either
            `anndata.AnnData` object or a `callable` and `anndata.AnnData`
            object as the second argument
            the `callable` either needs to return an `anndata.AnnData` object
            (if `copy=True`) or just modify it inplace
        '''

        def wrapper(*args, **kwargs):
            fname = kwargs.pop('fname', None)
            force = kwargs.pop('force', False)
            verbose = kwargs.pop('verbose', True)
            call = kwargs.pop('call', True)  # if we do not wish to call the callback
            skip = kwargs.pop('skip', False)
            # leave it in kwargs
            copy = kwargs.get('copy', False) and not is_plot

            assert fname is not None or def_fname is not None, f'No filename or default specified.'

            callback = None
            if len(args) > 1 and callable(args[0]):
                callback, *args = args

            is_raw = False
            if len(args) > 0 and isinstance(args[0], (anndata.AnnData, anndata.Raw)):
                if isinstance(args[0], anndata.Raw):
                    # get rid of the raw type
                    args = (args[0]._adata, *args[1:])
                    is_raw = True
                adata = args[0]
            elif 'adata' in kwargs:
                if isinstance(kwargs['adata'], anndata.Raw):
                    # get rid of the raw type
                    kwargs['adata'] = kwargs['adata']._adata
                    is_raw = True
                adata = kwargs['adata']
            else:
                raise ValueError(f'Unable to locate adata object in `*args` or `**kwargs`.')

            # at this point, it's impossible for adata to be of type anndata.Raw
            # but the message should tell it's possible for it to be an input
            assert isinstance(adata, (anndata.AnnData, )), f'Expected `{adata}` to be of type `anndata.AnnData` or `anndata.Raw`, found `{type(adata)}`.'

            # forcing always forces the callback
            if (call or force) and callback is None:
                if default_fn is None:
                    raise RuntimeError('No callback specified and default is None; specify it as a 1st argument. ')
                callback = default_fn
                assert callable(callback), f'`{callback}` is not callable.'

            if force:
                if verbose:
                    print('Computing values (forced).')
                if not call:
                    warnings.warn('Specifying `call=False` and `force=True` still forces the computation.')
                res = callback(*args, **kwargs)
                ret = cache_fn(res if copy else adata, fname, True, verbose, skip, *args, **kwargs)
                assert ret, 'Caching failed, horribly.'

                if is_plot:
                    # callback will show the plot
                    if adata.uns.pop(UNS_PLOT_KEY, None) is None:
                        # bad callback
                        warnings.warn(f'Plotting callbacks require the `adata` object to have `.uns[\'{UNS_PLOT_KEY}\']`' \
                                      ' containing the np.ndarray to plot (not found). You are likely seeing this because `skip=True`.')
                    return

                return anndata.Raw(res) if is_raw and res is not None else res

            # when loading to cache and copy is true, modify the copy
            if copy:
                adata = adata.copy()

            # we need to pass the *args and **kwargs in order to
            # get the right field when using regexes
            if not cache_fn(adata, fname, False, verbose, skip, *args, **kwargs):
                if verbose:
                    f = fname if fname is not None else def_fname
                    print(f'No cache found in `{str(f) + self.backend.ext}`, ' + ('computing values.' if call else 'searching for values.'))
                res = callback(*args, **kwargs) if call else adata if copy else None
                ret = cache_fn(res if copy else adata, fname, True, False, skip, *args, **kwargs)
                assert ret, 'Caching failed, horribly.'

                if is_plot:
                    # callback will show the plot
                    if adata.uns.pop(UNS_PLOT_KEY, None) is None:
                        # bad callback
                        warnings.warn(f'Plotting callbacks require the `adata` object to have `.uns[\'{UNS_PLOT_KEY}\']`' \
                                      ' containing the np.ndarray to plot (not found). You are likely seeing this because `skip=True`.')
                    return

                return anndata.Raw(res) if is_raw and res is not None else res

            if is_plot:
                data = adata.uns.pop(UNS_PLOT_KEY, None)
                if data is None:
                    # bad data loading
                    raise RuntimeError('Unable to load plot. No data found in `adata.uns[\'{UNS_PLOT_KEY}\']`.')

                return Image.fromarray(data)

            # if cache was found and not modifying inplace
            if not copy:
                return

            if is_raw:
                return anndata.Raw(adata)

            return adata

        def_fname = kwargs.get('default_fname', None)  # keep in in kwargs
        default_fn = kwargs.pop('default_fn', lambda *_x, **_y: None)
        is_plot = kwargs.pop('is_plot', False)  # plotting fuctions are treated as special
        cache_fn = self._create_cache_fn(*args, **kwargs)

        return FunctionWrapper(wrapper, default_fn)

class PpModule(Module):

    def __init__(self, backend, **kwargs):
        self._type = 'pp'
        self._functions = {
            'pcarr': wrap_as_adata(self.cache(dict(obsm='X_pca'),
                                              default_fname='pca_arr',
                                              default_fn=sc.pp.pca),
                                   ret_attr=dict(obsm='X_pca')),
            'expression': self.cache(dict(X=None), default_fname='expression'),
            'moments': self.cache(dict(uns_opt='pca',
                                       uns_opt_cache1='neighbors',
                                       obsm_opt='X_pca',
                                       varm_opt='PCs',
                                       layers='Ms',
                                       layers_cache1='Mu'),
                                  default_fn=scv.pp.moments,
                                  default_fname='moments'),
             'pca': self.cache(dict(obsm='X_pca',
                                    varm='PCs',
                                    uns=['pca', 'variance_ratio'],
                                    uns_cache1=['pca', 'variance']),
                               default_fname='pca',
                               default_fn=sc.pp.pca),
             'neighbors': self.cache(dict(uns='neighbors'),
                                     default_fname='neighs',
                                     default_fn=sc.pp.neighbors)
        }
        super().__init__(backend, **kwargs)

class TlModule(Module):

    def __init__(self, backend, **kwargs):
        self._type = 'tl'
        self._functions = {
            'louvain': self.cache(dict(obs='louvain'),
                                  default_fname='louvain',
                                  default_fn=sc.tl.louvain),
            'tsne': self.cache(dict(obsm='X_tsne'),
                               default_fname='tsne',
                               default_fn=sc.tl.tsne),
            'umap': self.cache(dict(obsm='X_umap'),
                               default_fname='umap',
                               default_fn=sc.tl.umap),
            'diffmap': self.cache(dict(obsm='X_diffmap',
                                       uns='diffmap_evals',
                                       uns_cache1='iroot'),
                                  default_fname='diffmap',
                                  default_fn=sc.tl.diffmap),
            'paga': self.cache(dict(uns='paga'),
                               default_fn=sc.tl.paga,
                               default_fname='paga'),
            'velocity': self.cache(dict(var='velocity_gamma',
                                        var_cache1='velocity_r2',
                                        var_cache2='velocity_genes',
                                        layers='velocity'),
                                   default_fn=scv.tl.velocity,
                                   default_fname='velo'),
            'velocity_graph': self.cache(dict(uns=re.compile(r'(.+)_graph$'),
                                              uns_cache1=re.compile('(.+)_graph_neg$')),
                                         default_fn=scv.tl.velocity_graph,
                                         default_fname='velo_graph'),
            'velocity_embedding': self.cache(dict(obsm=re.compile(r'^velocity_(.+)$')),
                                             default_fn=scv.tl.velocity_embedding,
                                             default_fname='velo_emb'),
            'draw_graph': self.cache(dict(obsm=re.compile(r'^X_draw_graph_(.+)$'),
                                          uns='draw_graph'),
                                     default_fn=sc.tl.draw_graph,
                                     default_fname='draw_graph')
        }
        super().__init__(backend, **kwargs)

class PlModule(Module):

    def __init__(self, backend, **kwargs):
        self._type = 'pl'
        self._functions = {
            fn.__name__:self.cache(dict(uns=UNS_PLOT_KEY),
                                   default_fname=f'{fn.__name__}_plot',
                                   default_fn=plotting_wrapper(fn),
                                   is_plot=True)

            for fn in filter(lambda fn: np.in1d(['return_fig', 'save'],  # only this works (wanted to  have with 'show')
                                                list(signature(fn).parameters.keys())).any(),
                             filter(callable, map(lambda name: getattr(sc.pl, name), dir(sc.pl))))
        }
        super().__init__(backend, **kwargs)


import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((1920,1080))
clock = pygame.time.Clock()

class board():
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('res/board.png')
        self.rect = self.image.get_rect()
        self.rect.left, self.rect.top = [0,0]
while True:
    board()
#    clock.tick(60)
    screen.blit(pygame.image.load('res/board.png'), (0, 0))
    #screen.blit(board,(0,0))
    allsprites = pygame.sprite.RenderPlain(board)
    allsprites.draw(screen)
    pygame.display.flip()


import a1_task1 as a1t1
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import os
import scipy.stats as stats
from pyfinance.ols import *

def ff_3factor_rolling_beta(tmp_etf_daily_ret, tmp_ff_daily, window):
    new_beta_dict = {}
    new_alpha_dict = {}
    new_residual_dict = {}

    if window != tmp_etf_daily_ret.shape[0]:
        for tmp_ff in list(tmp_ff_daily):
            new_beta_dict[tmp_ff] = pd.DataFrame()

        for tmp_etf in list(tmp_etf_daily_ret):
            tmp_roll_beta = PandasRollingOLS(y=tmp_etf_daily_ret[tmp_etf], x=tmp_ff_daily, window=window)

            for tmp_ff in list(tmp_ff_daily):
                new_beta_dict[tmp_ff][tmp_etf] = tmp_roll_beta.beta[tmp_ff]

            new_alpha_dict[tmp_etf] = tmp_roll_beta.alpha
            new_residual_dict[tmp_etf] = tmp_roll_beta.resids

    else:
        for tmp_ff in list(tmp_ff_daily):
            new_beta_dict[tmp_ff] = {}

        for tmp_etf in list(tmp_etf_daily_ret):
            tmp_roll_beta = OLS(y=tmp_etf_daily_ret[tmp_etf], x=tmp_ff_daily)

            for tmp_ff in list(tmp_ff_daily):
                new_beta_dict[tmp_ff][tmp_etf] = tmp_roll_beta.beta[list(tmp_ff_daily).index(tmp_ff)]

            new_alpha_dict[tmp_etf] = tmp_roll_beta.alpha
            new_residual_dict[tmp_etf] = tmp_roll_beta.resids

    return new_beta_dict, new_alpha_dict, new_residual_dict

if __name__ == '__main__':

    # (a)

    print()
    print("Task 1(a)\n")

    ff_daily = pd.read_csv("data/F-F_Research_Data_Factors_daily.CSV")
    ff_daily.rename(columns={'Unnamed: 0': 'Date'}, inplace=True)
    num = ff_daily.isna().sum()
    print("Empty value number:")
    print(num)
    ff_daily["Date"] = pd.to_datetime(ff_daily["Date"], format="%Y%m%d")
    ff_daily.dropna(axis=0, how='any', inplace=True)
    ff_daily.set_index(["Date"], inplace=True)
    ff_daily = ff_daily.loc[pd.to_datetime("2010-01-01", format="%Y-%m-%d"):, ]
    print("Total Day Number: ", ff_daily.shape[0])

    work_dir = os.getcwd()
    data_path = work_dir + "/data/ETF"

    index_dic = a1t1.clean_data(data_path)
    index_name = list(index_dic.keys())
    index_num = len(index_dic.keys())

    for tmp_index_name in index_name:
        index_dic[tmp_index_name] = index_dic[tmp_index_name].loc[
                                    pd.to_datetime("2010-01-01", format="%Y-%m-%d"):ff_daily.index[-1], ]
        print(index_dic[tmp_index_name].shape[0])

    print()

    # (b)

    print("Task 1(b)\n")

    ff_regress_name = ["Mkt-RF", "SMB", "HML"]

    etf_daily_adj_close = pd.DataFrame()
    for tmp_index_name, tmp_index_data in index_dic.items():
        etf_daily_adj_close[tmp_index_name] = tmp_index_data["Adj Close"]

    etf_daily_ret = a1t1.gen_daily_ret(etf_daily_adj_close)
    etf_name = list(etf_daily_ret)

    ff_daily = ff_daily.iloc[1:, ]
    ff_cov = np.cov(np.mat(ff_daily[ff_daily.columns[:-1]]).T)
    sns.set(font_scale=0.5)
    # a1t1.plot_sns(ff_cov, "Task1(b) Covariance Matrix of FF Factors", ff_daily.columns[:-1])
    # plt.savefig("a2_report/t1(b)_cov_ff.pdf")
    # plt.show()

    ff_corr = ff_daily[ff_daily.columns[:-1]].corr()
    # a1t1.plot_sns(ff_corr, "Task1(b) Correlation Matrix of FF Factors", ff_daily.columns[:-1])
    # plt.savefig("a2_report/t1(b)_corr_ff.pdf")
    # plt.show()

    print()

    # (c)

    print("Task 1(c)\n")

    # ninety_fac_corr = pd.DataFrame()
    # ninety_fac_corr["Mkt-RF VS SMB"] = ff_daily["Mkt-RF"].rolling(90).corr(ff_daily["SMB"]).dropna()
    # ninety_fac_corr["Mkt-RF VS HML"] = ff_daily["Mkt-RF"].rolling(90).corr(ff_daily["HML"]).dropna()
    # ninety_fac_corr["SMB VS HML"] = ff_daily["SMB"].rolling(90).corr(ff_daily["HML"]).dropna()

    ninety_fac_corr_dict={}

    for tmp_fac in ff_regress_name:
        ninety_fac_corr_dict[tmp_fac]=ff_daily[tmp_fac].rolling(90).corr(etf_daily_ret).dropna()
        ninety_fac_corr_dict[tmp_fac].plot()
        plt.ylabel("Correlation")
        plt.title("Task1(c) 90 Day Rolling Correlation between ETFs and "+tmp_fac)
        plt.savefig("a2_report/t1(c)_90roll_fac_corr_"+tmp_fac+".pdf")
        plt.show()
        print("Curve plot of 90 Day rolling correlation of factor returns successfully "
              "saved as 't1(c)_90roll_fac_corr_"+tmp_fac+".pdf' under directory 'a2_report'")

    # ninety_fac_corr.plot()
    # plt.legend(prop={'size': 6})
    # plt.ylabel("Correlation")
    # plt.title("Task1(c) 90 Day Rolling Correlation of Factor Returns")
    # plt.savefig("a2_report/t1(c)_90roll_fac_corr.pdf")
    # plt.show()
    # print("Curve plot of 90 Day rolling correlation of factor returns successfully "
    #       "saved as 't1(c)_90roll_fac_corr.pdf' under directory 'a2_report'")

    print()

    # (d)

    print("Task 1(d)\n")

    kstest_pval_dict = {}
    for tmp_factor_name in list(ff_daily):
        if tmp_factor_name != "RF":
            tmp_normaltest_pval = stats.normaltest(ff_daily[tmp_factor_name])[1]
            kstest_pval_dict[tmp_factor_name] = tmp_normaltest_pval

    print(kstest_pval_dict)
    print()

    # (e)

    print("Task 1(e)\n")

    ff_daily["Mkt"] = ff_daily["Mkt-RF"] + ff_daily["RF"]
    for tmp_etf_name in list(etf_daily_ret):
        etf_daily_ret[tmp_etf_name] -= ff_daily["RF"]
    entire_beta_dict, entire_alpha_dict, entire_residual_dict = ff_3factor_rolling_beta(etf_daily_ret,
                                                                                ff_daily[ff_regress_name],
                                                                                etf_daily_ret.shape[0])

    roll_beta_dict, roll_alpha_dict, roll_residual_dict = ff_3factor_rolling_beta(etf_daily_ret,
                                                                                ff_daily[ff_regress_name], 90)

    # alpha_plus_RF = roll_alpha_dict["XLI"] + ff_daily["RF"]
    # alpha_plus_RF.dropna(axis=0, how='any', inplace=True)
    # alpha_plus_RF.plot(ylim=[-0.05, 0.05])

    # roll_residual_dict["XLI"].plot()
    # plt.show()

    for tmp_new_ff in list(ff_regress_name):
        print(tmp_new_ff)
        print(entire_beta_dict[tmp_new_ff])

    for tmp_beta_df_name in roll_beta_dict.keys():
        roll_beta_dict[tmp_beta_df_name].plot()
        plt.ylabel("beta")
        plt.title("Task1(e) 90 Day Rolling Beta "+tmp_beta_df_name)
        plt.legend(prop={'size': 3})
        plt.savefig("a2_report/t1(e)_90roll_beta_"+tmp_beta_df_name+".pdf")
        plt.show()
        # plt.show()

    print()

    # (f)

    print("Task 1(f)\n")

    residual_mean_dict = {}
    residual_var_dict = {}
    residual_normaltest_pval_dict = {}

    for tmp_etf_name in etf_name:
        residual_mean_dict[tmp_etf_name] = np.mean(entire_residual_dict[tmp_etf_name])
        residual_var_dict[tmp_etf_name] = np.var(entire_residual_dict[tmp_etf_name])
        residual_normaltest_pval_dict[tmp_etf_name] = stats.normaltest(entire_residual_dict[tmp_etf_name])[1]

    print(residual_mean_dict)
    print(residual_var_dict)
    print(residual_normaltest_pval_dict)


from datetime import datetime
from urllib.parse import urlparse

from legistar.events import LegistarEventsScraper

from .spider import CityScrapersSpider

LINK_TYPES = ["Agenda", "Minutes", "Video", "Summary", "Captions"]

class LegistarSpider(CityScrapersSpider):
    link_types = []

    def parse(self, response):
        events = self._call_legistar()
        return self.parse_legistar(events)

    def _call_legistar(self, since=None):
        les = LegistarEventsScraper()
        les.BASE_URL = self.base_url
        les.EVENTSPAGE = "{}/Calendar.aspx".format(self.base_url)
        if not since:
            since = datetime.today().year
        return les.events(since=since)

    def legistar_start(self, item):
        start_date = item.get("Meeting Date")
        start_time = item.get("Meeting Time")
        if start_date and start_time:
            try:
                return datetime.strptime(
                    "{} {}".format(start_date, start_time), "%m/%d/%Y %I:%M %p"
                )
            except ValueError:
                return datetime.strptime(start_date, "%m/%d/%Y")

    def legistar_links(self, item):
        links = []
        for link_type in LINK_TYPES + self.link_types:
            if isinstance(item.get(link_type), dict) and item[link_type].get("url"):
                links.append({"href": item[link_type]["url"], "title": link_type})
        return links

    def legistar_source(self, item):
        default_url = "{}/Calendar.aspx".format(self.base_url)
        if isinstance(item.get("Name"), dict):
            return item["Name"].get("url", default_url)
        if isinstance(item.get("Meeting Details"), dict):
            return item["Meeting Details"].get("url", default_url)
        return default_url

    @property
    def base_url(self):
        parsed_url = urlparse(self.start_urls[0])
        return "{}://{}".format(parsed_url.scheme, parsed_url.netloc)