import pygame, math, sys, random
from pygame.locals import *

def pointInWedge(wedge, wedgeX, wedgeY, pointX, pointY):
    blockSize = 20
    if pointX >= wedgeX and pointX <= wedgeX+blockSize and pointY >= wedgeY and pointY <= wedgeY+blockSize:
        if wedge == 2:
            return pointX+pointY > wedgeX+wedgeY+blockSize
        elif wedge == 3:
            return pointX-wedgeX < pointY-wedgeY
        elif wedge == 4:
            return pointX+pointY < wedgeX+wedgeY+blockSize
        elif wedge == 5:
            return pointX-wedgeX > pointY-wedgeY
        else:
            return True
    else:
        return False

class Player:

    def __init__(this, x, y, teamColor, player, **kwargs):
        this.x = x
        this.y = y
        this.w = kwargs.get("width", 20)
        this.h = kwargs.get("height", 20)
        this.hat = kwargs.get("hat", 0)
        this.gunOn = kwargs.get("gun", 0)
        this.gun = guns[this.gunOn]
        this.speed = kwargs.get("speed", 2.5)
        this.gravity = kwargs.get("gravity", 0.1)
        this.jumpHeight = kwargs.get("jumpHeight", 5)
        this.maxSpeed = kwargs.get("maxSpeed", 4)
        this.teamColor = teamColor
        this.cursor = [0,0]
        this.yVel = 0
        this.theKey = 0
        this.delay = random.randint(0, this.gun.firerate)
        this.dir = random.randint(0,4)
        if this.dir == 2:
            this.dir = 0
        this.id = player
        this.health = 100
        this.inBlock = False
        this.outOfBlock = True
        this.lastShot = player
        this.you = False
        this.kills = 0

    def loopInfo(this, key, value):
        if key[0] == this.id:
            if key[1] == "damage":
                this.health -= key[2]
                this.lastShot = key[3]
            elif key[1] == "kill":
                this.gunOn += 1
                if this.gunOn > len(guns)-1:
                    this.gunOn = len(guns)-1
                this.gun = guns[this.gunOn]
                this.health += 20
                this.kills += 1
            return False
        return True

    def draw(this, surface, playerInfo):
        pygame.draw.rect(surface, this.teamColor, (this.x,this.y,this.w,this.h))
        this.gun.draw(surface, 0.03, [this.x+this.w/2,this.y+this.h/2], math.atan2(this.cursor[1]-this.y, this.cursor[0]-this.x))
        return playerInfo.filter(this.loopInfo)

    def playPlayer(this, mouseState, mouseX, mouseY, keys, blocks):
        this.cursor = [mouseX, mouseY]
        if keys[K_a] or keys[K_LEFT]:
            this.x -= this.speed
            this.theKey = K_LEFT
        if keys[K_d] or keys[K_RIGHT]:
            this.x += this.speed
            this.theKey = K_RIGHT
        blocks.loop(this.Xcol)
        if (keys[K_w] or keys[K_UP]) and this.yVel == 0:
            this.yVel = -this.jumpHeight-0.001
        this.yVel += this.gravity
        if this.yVel > this.maxSpeed:
            this.yVel = this.maxSpeed
        this.y += this.yVel
        blocks.loop(this.Ycol)
        this.delay -= 1
        if mouseState and this.delay < 0:
            this.delay = this.gun.firerate
            returnArray = []
            for i in range(this.gun.shots):
                angle = math.atan2(this.cursor[1]-this.y-this.h/2, this.cursor[0]-this.x-this.w/2)
                spread = random.randrange(-this.gun.spread, this.gun.spread)*math.pi/180
                velX = math.cos(angle + spread)
                velY = math.sin(angle + spread)
                offsetX = math.cos(angle)
                offsetY = math.sin(angle)
                returnArray.append([this.x+offsetX*30+this.w/2, this.y+offsetY*30+this.h/2, velX*this.gun.bulletspeed, velY*this.gun.bulletspeed, this.gun.damage*100, this.id])
            return returnArray
        else:
            return []

    def playAI(this, blocks, aiTrigger, players):
        this.outOfBlock = True
        aiTrigger.loop(this.changeDir)
        this.inBlock = not this.outOfBlock
        this.closestPlayer = 1000000
        players.loop(this.shootClosestPlayer)
        if this.dir == 0 or this.dir == 1:
            this.x -= this.speed
            this.theKey = K_LEFT
        elif this.dir == 3 or this.dir == 4:
            this.x += this.speed
            this.theKey = K_RIGHT
        blocks.loop(this.Xcol)
        if (this.dir == 1 or this.dir == 2 or this.dir == 3) and this.yVel == 0:
            this.yVel = -this.jumpHeight-0.001
        this.yVel += this.gravity
        if this.yVel > this.maxSpeed:
            this.yVel = this.maxSpeed
        this.y += this.yVel
        blocks.loop(this.Ycol)
        this.delay -= 1
        if this.delay < 0:
            this.delay = this.gun.firerate
            returnArray = []
            for i in range(this.gun.shots):
                angle = math.atan2(this.cursor[1]-this.y-this.h/2, this.cursor[0]-this.x-this.w/2)
                spread = random.randrange(-this.gun.spread, this.gun.spread)*math.pi/180
                velX = math.cos(angle + spread)
                velY = math.sin(angle + spread)
                offsetX = math.cos(angle)
                offsetY = math.sin(angle)
                returnArray.append([this.x+offsetX*30+this.w/2, this.y+offsetY*30+this.h/2, velX*this.gun.bulletspeed, velY*this.gun.bulletspeed, this.gun.damage, this.id])
            return returnArray
        else:
            return []

    def shootClosestPlayer(this, key, value):
        if key.id != this.id:
            d = math.dist((this.x, this.y), (key.x, key.y))
            if d < this.closestPlayer:
                this.closestPlayer = d
                this.cursor[0] = key.x+key.w/2
                this.cursor[1] = key.y+key.h/2

    def changeDir(this, key, value):
        blockSize = 20
        row = key[1]
        col = key[2]
        if this.x+this.w > row*blockSize and this.x < row*blockSize+blockSize and this.y+this.h > col*blockSize and this.y < col*blockSize+blockSize:
            this.outOfBlock = False
            if not this.inBlock:
                options = key[0]
                dirOptions = []
                for option in options:
                    if option == 1:
                        dirOptions.append(2)
                    elif option == 2:
                        dirOptions.append(0)
                        dirOptions.append(1)
                    elif option == 3:
                        dirOptions.append(3)
                        dirOptions.append(4)
                this.dir = dirOptions[random.randint(0, len(dirOptions)-1)]
                this.inBlock = True

    def pointInBlock(this, blockX, blockY, pointX, pointY):
        blockSize = 20
        return pointX > blockX and pointX < blockX+blockSize and pointY > blockY and pointY < blockY+blockSize

    def Xcol(this, key, value):
        blockSize = 20
        row = key[1]
        col = key[2]
        if key[0] == 1:
            if this.x+this.w > row*blockSize and this.x < row*blockSize+blockSize and this.y+this.h > col*blockSize and this.y < col*blockSize+blockSize:
                if this.theKey == K_RIGHT:
                    this.x = row*blockSize-this.w
                elif this.theKey == K_LEFT:
                    this.x = row*blockSize+blockSize
        elif key[0] == 2:
            if pointInWedge(2, row*blockSize, col*blockSize, this.x, this.y) or pointInWedge(2, row*blockSize, col*blockSize, this.x+this.w, this.y) or pointInWedge(2, row*blockSize, col*blockSize, this.x, this.y+this.h):
                if this.theKey == K_LEFT:
                    this.x += this.speed
                elif this.theKey == K_RIGHT:
                    this.x -= this.speed
            elif pointInWedge(2, row*blockSize, col*blockSize, this.x+this.w, this.y+this.h):
                this.y -= this.speed
                this.yVel = 0
            elif this.pointInBlock(row*blockSize, col*blockSize, this.x+this.w, this.y):
                if this.theKey == K_LEFT:
                    this.x += this.speed
                elif this.theKey == K_RIGHT:
                    this.x -= this.speed
        elif key[0] == 3:
            if pointInWedge(3, row*blockSize, col*blockSize, this.x, this.y) or pointInWedge(3, row*blockSize, col*blockSize, this.x+this.w, this.y) or pointInWedge(3, row*blockSize, col*blockSize, this.x+this.w, this.y+this.h):
                if this.theKey == K_LEFT:
                    this.x += this.speed
                elif this.theKey == K_RIGHT:
                    this.x -= this.speed
            elif pointInWedge(3, row*blockSize, col*blockSize, this.x, this.y+this.h):
                this.y -= this.speed
                this.yVel = 0
            elif this.pointInBlock(row*blockSize, col*blockSize, this.x, this.y):
                if this.theKey == K_LEFT:
                    this.x += this.speed
                elif this.theKey == K_RIGHT:
                    this.x -= this.speed
        elif key[0] == 4:
            if pointInWedge(4, row*blockSize, col*blockSize, this.x, this.y+this.h) or pointInWedge(4, row*blockSize, col*blockSize, this.x+this.w, this.y) or pointInWedge(4, row*blockSize, col*blockSize, this.x+this.w, this.y+this.h):
                if this.theKey == K_LEFT:
                    this.x += this.speed
                elif this.theKey == K_RIGHT:
                    this.x -= this.speed
            elif pointInWedge(4, row*blockSize, col*blockSize, this.x, this.y):
                this.y += this.speed
            elif this.pointInBlock(row*blockSize, col*blockSize, this.x, this.y+this.h):
                if this.theKey == K_LEFT:
                    this.x += this.speed
                elif this.theKey == K_RIGHT:
                    this.x -= this.speed
        elif key[0] == 5:
            if pointInWedge(5, row*blockSize, col*blockSize, this.x, this.y) or pointInWedge(5, row*blockSize, col*blockSize, this.x, this.y+this.h) or pointInWedge(5, row*blockSize, col*blockSize, this.x+this.w, this.y+this.h):
                if this.theKey == K_LEFT:
                    this.x += this.speed
                elif this.theKey == K_RIGHT:
                    this.x -= this.speed
            elif pointInWedge(5, row*blockSize, col*blockSize, this.x+this.w, this.y):
                this.y += this.speed
            elif this.pointInBlock(row*blockSize, col*blockSize, this.x+this.w, this.y+this.h):
                if this.theKey == K_LEFT:
                    this.x += this.speed
                elif this.theKey == K_RIGHT:
                    this.x -= this.speed
    def Ycol(this, key, value):
        blockSize = 20
        row = key[1]
        col = key[2]
        if key[0] == 1:
            if this.x+this.w > row*blockSize and this.x < row*blockSize+blockSize and this.y+this.h > col*blockSize and this.y < col*blockSize+blockSize:
                if this.yVel > 0:
                    this.y = col*blockSize-this.h
                    this.yVel = 0
                else:
                    this.y -= this.yVel*1.1
                    this.yVel = 0.5
        elif key[0] != 0:
            onCorner = False
            if key[0] == 2:
                if pointInWedge(4, row*blockSize, col*blockSize, this.x, this.y+this.h):
                    onCorner = True
            if key[0] == 3:
                if pointInWedge(5, row*blockSize, col*blockSize, this.x+this.w, this.y+this.h):
                    onCorner = True
            if key[0] == 4:
                if pointInWedge(2, row*blockSize, col*blockSize, this.x+this.w, this.y):
                    onCorner = True
            if key[0] == 5:
                if pointInWedge(3, row*blockSize, col*blockSize, this.x, this.y):
                    onCorner = True
            if pointInWedge(key[0], row*blockSize, col*blockSize, this.x, this.y) or pointInWedge(key[0], row*blockSize, col*blockSize, this.x+this.w, this.y) or pointInWedge(key[0], row*blockSize, col*blockSize, this.x, this.y+this.h) or pointInWedge(key[0], row*blockSize, col*blockSize, this.x+this.w, this.y+this.h) or onCorner:
                if this.yVel > 0:
                    this.y -= this.yVel*1.1
                    this.yVel = 0
                else:
                    this.y -= this.yVel*1.1
                    this.yVel = 0.5

class Gun:

    def __init__(this, name, scale, translation, **kwargs):
        this.scale = scale
        this.translation = translation
        this.damage = kwargs.get("damage", 10)
        this.firerate = kwargs.get("firerate", 10)
        this.bulletspeed = kwargs.get("bulletspeed", 3)
        this.spread = kwargs.get("spread", 0)
        this.shots = kwargs.get("shots", 1)
        this.name = name
        this.shapes = pygame.image.load("guns/" + this.name + ".png")

    def draw(this, surface, scale, translation, rotation):
        while rotation > math.pi:
            rotation -= 2*math.pi
        while rotation < -math.pi:
            rotation += 2*math.pi
        originalRect = this.shapes.get_rect()
        if (rotation > -math.pi/2 and rotation < math.pi/2):
            flip = 1
            gunImage = pygame.transform.rotate(pygame.transform.flip(pygame.transform.scale(this.shapes, (round(originalRect.width*this.scale*scale), round(originalRect.height*this.scale*scale))), 0, 0), -rotation*180/math.pi)
        else:
            flip = -1
            gunImage = pygame.transform.rotate(pygame.transform.flip(pygame.transform.scale(this.shapes, (round(originalRect.width*this.scale*scale), round(originalRect.height*this.scale*scale))), 0, 1), -rotation*180/math.pi)
        gunRect = gunImage.get_rect()
        gunRect.center = (translation[0] + (math.cos(rotation)*this.translation[0]+math.cos(rotation+math.pi/2)*this.translation[1]*flip)*scale*this.scale, translation[1] + (math.sin(rotation)*this.translation[0]+math.sin(rotation+math.pi/2)*this.translation[1]*flip)*scale*this.scale)
        surface.blit(gunImage, gunRect)

guns = [
    Gun("Glock 19", 0.8, [300, 50], damage=5, firerate=20, bulletspeed=7, spread=3),
    Gun("Spas 12", 1, [300, -10], damage=4, firerate=40, bulletspeed=6, spread=10, shots=10),
    Gun("Howa 1500", 1.2, [300, -10], damage=20, firerate=30, bulletspeed=10, spread=1),
    Gun("PLR-16", 1, [300, -10], damage=3, firerate=1, bulletspeed=7, spread=20),
    Gun("AWM", 1.2, [300, -10], damage=45, firerate=80, bulletspeed=15, spread=1),
    Gun("AK-47", 0.9, [300, 100], damage=2, firerate=2, bulletspeed=7, spread=6),
]


import logging
from logging import debug as d
from itertools import product

logging.basicConfig(level=logging.DEBUG, format=('%(funcName)s(%(lineno)d):  %(message)s'))

def p(**kwargs):
    printstr = ''
    for (key, var) in kwargs.items():
        printstr += ("%s=%s\t" % (key, var))

    return printstr

def doSolve(filename, solver, log=False):
    with open(filename) as infile:
        with open(filename + ".out", 'w') as outfile:
            numCases = int(infile.readline())

            for i in range(numCases):
                inputs = parseTestCase(infile)
                result = solver(*inputs)
                if log:
                    print(inputs)
                    print(result)
                    print(" ")

                outfile.write("Case #%d: %s\n" % (i + 1, str(result)))

###=================================== =END TEMPLATE
# logging: d(p(varname=var, varname=var))

def parseTestCase(file):
    prob = file.readline().strip()
    prob = prob.split()
    return (prob[0], prob[1])

def solver(num1, num2):
    n1d = []
    n2d = []

    for x in num1:
        if x == "?":
            n1d.append("0123456789")
        else:
            n1d.append(x)

    for x in num2:
        if x == "?":
            n2d.append("0123456789")
        else:
            n2d.append(x)

    n1s = map(''.join, product(*n1d))
    n2s = map(''.join, product(*n2d))

    n1s = [int(x) for x in n1s]
    n2s = [int(x) for x in n2s]

    diff = 1000
    n1min = 1000
    n2min = 1000
    for n1 in n1s:
        for n2 in n2s:
            newdiff = abs(n1 - n2)
            if newdiff == 0:
                i = 0
            if diff == newdiff:
                if n1min == n1:
                    if n2 < n2min:
                        n2min = n2
                        n1min = n1
                        diff = newdiff
                elif n1 < n1min:
                    n2min = n2
                    n1min = n1
                    diff = newdiff
            elif newdiff < diff:
                n2min = n2
                n1min = n1
                diff = newdiff

    formatstr = "%0" + str(len(num1)) + "d"
    n1str = formatstr % n1min
    n2str = formatstr % n2min

    return n1str + " " + n2str

    pass

FILENAME = r"B-small-attempt0.in"
doSolve(FILENAME, solver, True)


from natsort import natsorted
import cv2
from os.path import join as osp
import os
import matplotlib.pyplot as plt
from PIL import Image
import torch
from torchvision import transforms

import torch.nn as nn
from torch.utils.data import DataLoader
from torch.utils.data import Dataset
from torch.optim.lr_scheduler import StepLR
import torch.optim as optim

from sklearn.model_selection import train_test_split

from unet import UNet

import shutil

class MyDataManager(Dataset):
  def __init__(self, ds, ls):
    super(MyDataManager, self).__init__()
    self.ds = ds
    self.ls = ls
    self.scale = 0.33

    self.transform = transforms.Compose([
      transforms.Resize((480, 640)),
      transforms.ToTensor()
    ])

  def __getitem__(self, idx):
    data_img = Image.open(self.ds[idx])
    data_img = self.transform(data_img)

    target_img = Image.open(self.ls[idx])
    target_img = self.transform(target_img)

    return data_img, target_img

  def __len__(self):
    return len(self.ds)

def visualize(ds, ls, idx):
  img_data = Image.open(ds[idx])
  target_data = Image.open(ls[idx])
  x = transforms.ToTensor()(img_data)

  fig, ax = plt.subplots(1, 2)

  ax[0].imshow(img_data)
  ax[1].imshow(target_data)

  #plt.imshow(img)
  plt.show()

def train(model, train_loader, device, epochs, log_interval, criterion, optimizer):
  model.train()
  for e in range(epochs):
    for i, (data, target) in enumerate(train_loader):
      data= data.to(device=device, dtype=torch.float32)
      target = target.to(device=device, dtype=torch.float32)
      optimizer.zero_grad()
      output = model(data)

      loss = criterion(output, target)
      loss.backward()
      optimizer.step()

      if i % log_interval:
        print(
          "train epoch: {} [{}/{} ({:.0f}%] \tLoss: {:.6f}".format(
           e,
           i * len(data),
           len(train_loader.dataset),
           100.0*i/len(train_loader),
           loss.item()
          )
        )

def test(model, test_loader, device, criterion):
  model.eval()
  test_loss = 0
  correct = 0

  with torch.no_grad():
    for data, target in test_loader:
      data = data.to(device, dtype=torch.float32)
      target = target.to(device, dtype=torch.float32)
      output = model(data)
      test_loss += criterion(output, target)

      prediction = output.argmax(dim=1, keepdim=True)

      correct += prediction.eq(target.view_as(prediction)).sum().item()

    test_loss /= len(test_loader.dataset)

    print(
      "\nTest set: average loss: {:.4f}, accuracy: {}/{} ({:.0f}%)\n".format(
        test_loss,
        correct,
        len(test_loader.dataset),
        100.0 * correct /len(test_loader.datset)
      )
    )

def save_model(model, dir_checkpoint, epoch_num):
  torch.save(model.state_dict(), osp(dir_checkpoint, f'CP_epoch{epoch_num}.pth'))

def create_dataset(folder_data, folder_target):

  data_list= os.listdir(folder_data)
  target_list = os.listdir(folder_target)

  data_list = natsorted(data_list)
  target_list = natsorted(target_list)

  ds = [osp(folder_data, img) for img in data_list]
  ls = [osp(folder_target, img) for img in target_list]

  train_x, test_x, train_y, test_y = train_test_split(ds, ls, test_size=0.2)

  return train_x, test_x, train_y, test_y

def create_data_loader(train_x, test_x, train_y, test_y):

  train_dataset = MyDataManager(train_x, train_y)
  test_dataset = MyDataManager(test_x, test_y)

  train_kwargs = dict(
    batch_size=4,
    shuffle=True
  )

  test_kwargs = dict(
    batch_size=4,
  )

  train_loader = DataLoader(train_dataset, **train_kwargs)
  test_loader = DataLoader(test_dataset, **test_kwargs)

  return train_loader, test_loader

if __name__ == "__main__":
  folder_data = "/home/kmihara/Downloads/carvana/train"
  folder_target = "/home/kmihara/Downloads/carvana/train_masks"

  train_x, test_x, train_y, test_y  = create_dataset(folder_data=folder_data, folder_target=folder_target)

  print(f'created dataset')

  train_loader, test_loader = create_data_loader(train_x, test_x, train_y, test_y)

  print(f'created data loader')

  dir_checkpoint = "checkpoint_test"
  if os.path.exists(dir_checkpoint):
    shutil.rmtree(dir_checkpoint)
    os.mkdir(dir_checkpoint)
  else:
    os.mkdir(dir_checkpoint)

  epochs = 5
  device = torch.device('cpu')
  batch_size = 12
  lr = 0.1
  log_interval = 5

  criterion = nn.BCEWithLogitsLoss()

  model = UNet(n_channels=3, n_classes=1)
  optimizer = optim.SGD(model.parameters(), lr=lr)
  #optimizer = optim.RMSprop(model.parameters(), lr=lr, weight_decay=1e-8, modentum=0.9)
  scheduler = StepLR(optimizer, step_size=1, gamma=0.1)

  scheduler = StepLR(optimizer, step_size=1, gamma = 0.1)

  print(f'start training')
  for e in range(epochs):
    train(model, train_loader, device, epochs, log_interval, criterion, optimizer)
    test(model, test_loader, device, criterion)
    scheduler.step()
    print(f'save model for checkpoint')
    save_model(model, dir_checkpoint, e)

  print(f'finished training')


import sys
import pygame
from settings import Settings
from ship import Ship
from bullet import Bullet
from alien import Alien
class AlienInvasion:
    """Overall class to manage game assets and behavior."""

    def __init__(self):
        """Initialize the game, and create game resources."""
        pygame.init()
        self.settings = Settings()
        self.screen = pygame.display.set_mode(
            (0,0),pygame.FULLSCREEN
        )
        pygame.display.set_caption("Alien Invasion")
        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()

        self._create_fleet()
        self.settings.screen_height = self.screen.get_rect().height
        self.settings.screen_width = self.screen.get_rect().width

    def run_game(self):
        """Start the main loop of the game"""
        while True:
            self._check_events()
            self.ship.update()
            self._update_bullets()
            self._update_alien()
            self._update_screen()

    def _check_events(self):
        """Respond to mouse and keyboard events"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)

            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)

    def _check_keydown_events(self,event):
        """Respond to keypresess."""
        if event.key ==pygame.K_RIGHT:
                    self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
                    self.ship.moving_left = True
        elif event.key == pygame.K_q:
            sys.exit()
        elif event.key == pygame.K_SPACE:
            self._fire_bullet()

    def _check_keyup_events(self,event):
        if event.key == pygame.K_RIGHT:
                    self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
                    self.ship.moving_left = False

    def _fire_bullet(self):
        if len(self.bullets) <self.settings.bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _update_bullets(self):
        #Update bullet
        self.bullets.update()

        #Remove the bullets that have dissapiared from the screen
        for bullet in self.bullets.copy():
                if bullet.rect.bottom <= 0:
                    self.bullets.remove(bullet)
        self._check_bullet_alien_collision()

    def _check_bullet_alien_collision(self):
        #Check if any bullets have hit an alien
        collision = pygame.sprite.pygame.sprite.groupcollide(self.bullets, self.aliens, True, True)

        #if there is no more aliens destroy all the remaining bullets and create new aliens
        if not self.aliens:
            self.bullets.empty()
            self._create_fleet()

    def _create_alien(self,alien_number,row_number):
            """Create alien and place it in the row"""
            alien = Alien(self)
            alien_width,alien_height = alien.rect.size
            alien.x = alien_width + 2 * alien_width *alien_number
            alien.rect.x = alien.x
            alien.rect.y = alien_height + 2 * alien.rect.height * row_number
            self.aliens.add(alien)

    def _update_alien(self):
        self._check_flee_edges()
        self.aliens.update()

    def _check_flee_edges(self):
        """Respond if any alien has reach the edge """
        for alien in self.aliens.sprites():
            if alien.check_edges():
                self._change_flee_diraction()
                break

    def _change_flee_diraction(self):
        """Drop the entire flee and change the direction """
        for alien in self.aliens.sprites():
            alien.rect.y += self.settings.flee_drop_speed
        self.settings.fleet_direction*=-1

    def _create_fleet(self):
        """ Create fleet of aliens """

        #Instance of new Alien()
        alien = Alien(self)
        self.aliens.add(alien)

        alien_width,alien_height = alien.rect.size
        available_space_x = self.settings.screen_width - (2 * alien_width)
        number_of_aliens_x = available_space_x // (2 * alien_width)

        #Determine the number of rows of aliens that fit into the screen

        ship_height =self.ship.rect.height
        available_space_y = (self.settings.screen_height - (3 * alien_height) - ship_height)
        number_rows = available_space_y // (2 * alien_height)
        #Create the first row of aliens
        for row_number in range(number_rows+1):
            for alien_number in range(number_of_aliens_x+2):
                self._create_alien(alien_number,row_number )

    def _update_screen(self):
        """on every change update the screen"""
        self.screen.fill(self.settings.bg_color)
        #Drawing the ship
        self.ship.blitme()

        for bullet in self.bullets.sprites():
            bullet.draw_bullet()

        self.aliens.draw(self.screen)
        """ Make the most recently drawn screen visible"""
        pygame.display.flip()

if __name__ == '__main__':
    # Make a game instance, and run the game.
    ai =AlienInvasion()
    ai.run_game()


import sqlite3

conn = sqlite3.connect("db.db")
cursor = conn.cursor()
# Задача 4.1
cursor.execute("""
SELECT * FROM customer a
JOIN city b
on a.cod = b.cod;
               """)
print(cursor.fetchall())
# Задача 4.2
cursor.execute("""
SELECT a.name as person, b.name as city FROM customer a
LEFT JOIN city b
on a.cod = b.cod;
               """)
print(cursor.fetchall())
# Задача 4.3
cursor.execute("""
SELECT a.name as person, b.name as city FROM city b
LEFT JOIN customer a
on a.cod = b.cod;
               """)
print(cursor.fetchall())


from eocharging.Helpers import eo_base_url as base_url
import requests
import time

class Session:
    """Class that defines what a Session is"""

    def __init__(self, access_token=None, cpid=None, start_date=None, end_date=None):
        if access_token is None:
            raise Exception("No access_token provided")
        if cpid is None:
            raise Exception("No cpid provided")
        if start_date is None:
            raise Exception("No start_date provided")
        if end_date is None:
            raise Exception("No end_date provided")

        self.cpid = cpid
        self.start_date = start_date
        self.end_date = end_date

        # Fetch data from API
        url = base_url + "api/session/detail"
        payload = {
            "id": self.cpid,
            "startDate": self.start_date,
            "endDate": self.end_date,
        }
        headers = {"Authorization": "Bearer " + access_token}

        response = requests.post(url, data=payload, headers=headers)
        if response.status_code != 200:
            raise Exception("Response was not OK")

        data = response.json()

        # Calculate kWh used and cost
        self.session_kwh = 0
        self.session_cost = 0
        for point in data:
            kwh = ((point["CT2"] / 1000) * 230) / 1000 / 60
            self.session_kwh += kwh
            self.session_cost += kwh * point["Cost"]

class LiveSession:
    def __init__(self, access_token=None):
        if access_token is None:
            raise Exception("No access_token provided")
        self.access_token = access_token

        url = base_url + "api/session"
        headers = {"Authorization": "Bearer " + access_token}

        response = requests.get(url, headers=headers)
        if response.status_code != 200:
            raise Exception("Response was not OK")

        data = response.json()

        self.session_start_time = data["PiTime"]
        self.voltage = data["Voltage"]
        self.cpid = data["CPID"]

        self.update()

    def pause(self):
        """Used for pausing a session
        Similar to disabling/locking but also not"""
        url = base_url + "api/session/pause"
        response = requests.post(url, headers=self.headers)
        if response.status_code != 200:
            raise Exception("Response was not OK")

    def unpause(self):
        """Used for unpausing a paused session
        Similar to enabling/unlocking but also not"""
        url = base_url + "api/session/unpause"
        response = requests.post(url, headers=self.headers)
        if response.status_code != 200:
            raise Exception("Response was not OK")

    def update(self):
        # Get current charging rate
        url = base_url + "api/session/detail"
        payload = {
            "id": self.cpid,
            "startDate": self.session_start_time,
            "endDate": int(time.time()),
        }
        headers = {"Authorization": "Bearer " + self.access_token}

        live_data = requests.post(url, data=payload, headers=headers)
        live_data = live_data.json()

        self.current_amps = live_data[-1]["CT2"] / 1000
        self.current_wattage = self.current_amps * self.voltage

        self.session_kwh = 0
        self.session_cost = 0
        for point in live_data:
            kwh = ((point["CT2"] / 1000) * 230) / 1000 / 60
            self.session_kwh += kwh
            self.session_cost += kwh * point["Cost"]


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import django.db.models.deletion
from django.db import migrations, models

import parler

class Migration(migrations.Migration):
    dependencies = [
        ("foirequest", "0002_auto_20150728_1829"),
        ("publicbody", "0003_auto_20160123_1336"),
    ]

    operations = [
        migrations.CreateModel(
            name="Campaign",
            fields=[
                (
                    "id",
                    models.AutoField(
                        verbose_name="ID",
                        serialize=False,
                        auto_created=True,
                        primary_key=True,
                    ),
                ),
                ("title", models.CharField(max_length=255)),
                ("slug", models.SlugField()),
                ("template", models.TextField()),
            ],
            bases=(parler.models.TranslatableModelMixin, models.Model),
        ),
        migrations.CreateModel(
            name="InformationObject",
            fields=[
                (
                    "id",
                    models.AutoField(
                        verbose_name="ID",
                        serialize=False,
                        auto_created=True,
                        primary_key=True,
                    ),
                ),
                ("ident", models.CharField(max_length=255)),
                ("title", models.CharField(max_length=1000)),
                ("slug", models.SlugField()),
                ("context", models.JSONField()),
                (
                    "campaign",
                    models.ForeignKey(
                        to="froide_campaign.Campaign",
                        on_delete=django.db.models.deletion.CASCADE,
                    ),
                ),
                ("documents", models.ManyToManyField(to="foirequest.FoiAttachment")),
                (
                    "foirequest",
                    models.ForeignKey(
                        to="foirequest.FoiRequest",
                        null=True,
                        on_delete=django.db.models.deletion.SET_NULL,
                    ),
                ),
                (
                    "publicbody",
                    models.ForeignKey(
                        to="publicbody.PublicBody",
                        null=True,
                        on_delete=django.db.models.deletion.SET_NULL,
                    ),
                ),
            ],
            bases=(parler.models.TranslatableModelMixin, models.Model),
        ),
    ]


from flask import render_template, flash, redirect,request
from app import app
from app.models import User
from .forms import LoginForm
from app import db
import os
from werkzeug import secure_filename
import tinys3
from sqlalchemy.exc import IntegrityError

@app.route('/')
@app.route('/index',methods=['GET', 'POST'])
def index():
    form = LoginForm()
    error = None
    return render_template('index.html',
                           title='Index',
                           form=form,
                           error=error)

def allowed_file(filename):
    return '.' in filename and \
        filename.rsplit('.', 1)[1] in app.config['ALLOWED_EXTENSIONS']

@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm(request.form)
    error = None
    success = None
    if form.validate_on_submit():
        user = User(first_name=form.first_name.data,last_name=form.last_name.data,email=form.email.data)
        fileName = form.email.data + ".pdf"
        file = request.files['resume']
        if file and allowed_file(file.filename):
            file.save(fileName)
            conn = tinys3.Connection(app.config['FILESTOREK'],app.config['FILESTOREKS'],tls=True,endpoint="s3-us-west-2.amazonaws.com")
            f = open(fileName,'rb')
            conn.upload("resumes/"+fileName,f,'tigerbuilds')
            os.remove(fileName)
            try:
              db.session.add(user)
              db.session.commit()
              success = "Application Complete, Thank You"
            except IntegrityError:
              error = "The email you entered already exists"
            return render_template('index.html',
                           title='Index',
                           form=form,
                           error=error,
                           success=success)
        error = "Resume must be a pdf"
    else:
        error = "Information not correct. You must fill everything out"
    return render_template('index.html',
                           title='Index',
                           form=form,
                           error=error)


import streamlit as st
import numpy as np
from . import spearman_data as dt

def present_spearman():
    st.markdown(
        """
        # Análise de correlação de Spearman

        Para determinar a relação das diversas doenças com o suicídio nas cidades, foi realizada uma correlação de Spearman
        entre as taxas de internações correspondentes a cada uma delas e a taxa de suicídio por município, no período de 2008 a 2018.

        """
    )

    st.markdown(
        """
        ## Coeficiente de correlação de Spearman

        O coeficiente de **correlação de Spearman** é uma medida da intensidade e direção da associação monotônica entre duas variáveis.
        Em outras palavras, ele avalia o quão bem a relação entre duas variáveis pode ser descrita por meio de uma relação monotônica.

        O cálculo do coeficiente é feito através de uma correlação de Pearson entre os **rankings** das variáveis. O valor obtido é $r_s$, que é
        tal que $-1 \leq r_s \leq 1$:
        - $r_s = 1$ indica uma associação perfeita e positiva entre as váriáveis
        - $r_s = 0$ indica que não há nenhuma associação entre as variáveis
        - $r_s = -1$ indica uma associação perfeita e negativa entre as variávels

        """
    )

    st.markdown(
        """
        ## Tabela de correlações com suicídio

        A tabela abaixo contém os coeficientes de correlações de Spearman (bem como seus respectivos _p-values_) entre a média da taxa de internações referentes a diferentes doenças do DATASUS e a média da taxa de suicídios, no período de 2008-2018.

        A coluna "Qtd Municípios" indica a quantidade de municípios com dados não nulos presentes no conjunto de dados de cada doença.
        Foram excluídas as doenças cuja quantidade de municípios é inferior à metade do número total de municípios no Brasil, ou seja, $< 2785$.

        """
    )

    st.write(dt.get_top_correlations())

    st.markdown(
        """
        ## Gráfico de Doenças vs Suicídio

        """
    )

    disease_names = dt.get_diseases_select_names()
    if len(disease_names) > 0:
        options = np.append(['Selecione uma doença'], disease_names)
        selected_disease = st.selectbox('Selecione uma doença:', options)

        st.markdown(
            '
Para mais informações sobre uma doença, acesse o DATASUS.
', unsafe_allow_html=True
        )

        if (selected_disease != 'Selecione uma doença'):
            dt.plot_disease_vs_suicide(selected_disease)
    else:
        st.markdown(
            """
            ### **_Erro ao carregar nomes das doenças._**
            """
        )


"""
===================================================================
                            MorE3d
===================================================================
A class for higher usability of the ball tree representation.
Based on code by Zachi Shtain

"""

from functools import partial

import numpy as np
from numpy import nonzero, logical_and, unique, zeros, array, hstack
from sklearn.neighbors import BallTree

class BallTreePointSet(object):

    def __init__(self, points, leaf_size=40, **kwargs):
        r"""
        A ball tree representation

        :param points: the points to represent as ball tree
        :param leaf_size: minimal number of points in a leaf, with the maximal :math:`2\cdot` leaf_size

        :type points: PointSet, np.array
        :type leaf_size: int

          :type inputPoints: np.ndarray, o3D.PointCloud, PointSet

        """
        import open3d as O3D

        if isinstance(points, np.ndarray):
            self.data = BallTree(points, leaf_size)

        elif isinstance(points, O3D.PointCloud):
            pts = np.asarray(points.points)
            self.data = BallTree(pts, leaf_size)
        else:
            print("Given type: " + str(type(points)) + " as input. Points type should be numpy array or open3d PointCloud")
            raise ValueError("Wrong input object.")

        ballTreeData = self.data.get_arrays()  # Getting the data out of the ballTree object
        self.__ballTreePointIndexes = ballTreeData[1]  # Storing the internal indexes of the points
        self.__ballTreeNodes = ballTreeData[2]  # Storing the nodes data (mx4, ndarray)
        # self.__ballTreeNodeCenters = ballTreeData[3]  # Storing the centers of each node
        self.__numNodes = self.__ballTreeNodes.shape[0]  # Number of nodes in the tree
        self.__relations = []  # A list to define the tree hierarchy structure
        self.__ballTreeNodeHierarchy()  # Reconstructing the hierarchy of the tree
        self.__levels = zeros((self.__numNodes,), dtype=int)  # Array for storing the level of each node
        self.__ComputeNodeLevel(0)  # Computing the levels for all nodes
        # self.__numPnts = points.shape[0]

    # ---------------- PRIVATES-------------
    def __findChildNodes(self, i):
        """
        Finds the child nodes of the i-th node in the tree

        :param i: The index of the node to search for its child nodes

        :type i: int

        :return: A dictionary with the indexes of the left and right child nodes, if they exist

        :rtype: dict
        """
        childNodes = {'nodeId': i}

        if self.__ballTreeNodes['is_leaf'][i] == 0:  # Checking if node is not a leaf
            startIdx = self.__ballTreeNodes['idx_start'][i]  # The index of the first point in the node
            endIdx = self.__ballTreeNodes['idx_end'][i]  # The index of the last point in the node
            midIdx = int((startIdx + endIdx) / 2)  # The index of the middle point of the node

            # Finding the index of the left child of the node
            left = nonzero(logical_and(self.__ballTreeNodes['idx_start'][i + 1:] == startIdx,
                                       self.__ballTreeNodes['idx_end'][i + 1:] == midIdx))[0]

            # Finding the index of the right child of the node
            right = nonzero(logical_and(self.__ballTreeNodes['idx_start'][i + 1:] == midIdx,
                                        self.__ballTreeNodes['idx_end'][i + 1:] == endIdx))[0]

            if len(left) != 0:  # Checking if the left child node exists
                childNodes['leftChild'] = left[0] + i + 1  # Saving the index of left child node

            if len(right) != 0:  # Checking if the right child node exists
                childNodes['rightChild'] = right[0] + i + 1  # Saving the index of right child node

        return childNodes  # Return the dictionary with indexes of the child nodes

    def __setParent(self, i):
        """
        Sets ths i-th node as the parent of its child nodes

        :param i: The index of the node to set as parent

        :type i: int
        """
        left = False
        right = False

        if 'leftChild' in self.__relations[i]:  # Checking if the node has a left child
            left = True
            # Setting i as the parent of the left child node
            if not ('parent' in self.__relations[self.__relations[i]['leftChild']]):
                self.__relations[self.__relations[i]['leftChild']]['parent'] = i

        if 'rightChild' in self.__relations[i]:  # Checking if the node has a right child
            right = True
            # Setting i as the parent of the right child node
            if not ('parent' in self.__relations[self.__relations[i]['rightChild']]):
                self.__relations[self.__relations[i]['rightChild']]['parent'] = i

        if left and right:
            self.__relations[self.__relations[i]['leftChild']]['sibling'] = self.__relations[i]['rightChild']
            self.__relations[self.__relations[i]['rightChild']]['sibling'] = self.__relations[i]['leftChild']

    def __ballTreeNodeHierarchy(self):
        """
        Reconstruct the tree hierarchy based on the internal indexes of the points in each node

        """
        self.__relations = list(
            map(self.__findChildNodes, range(self.__numNodes)))  # Finding the children for each node
        list(map(self.__setParent, range(self.__numNodes)))  # Setting the parent for each node

    def __getFirstNodeOfSize(self, index, radius, startingNode='root'):
        """
        Get the first node along one of the tree branches whose radius is larger than a given one

        :param index: The index of the node to begin the search by
        :param radius: The minimal required size of the node

        :type index: int
        :type radius: float

        :return: The index of the first node with a radius larger than the given one

        :rtype: int
        """
        if startingNode == 'root':
            if self.__ballTreeNodes['radius'][index] < radius or self.__ballTreeNodes['is_leaf'][index] == 1:
                return index
            else:
                return hstack([self.__getFirstNodeOfSize(self.getLeftChildOfNode(index), radius, 'root'),
                               self.__getFirstNodeOfSize(self.getRightChildOfNode(index), radius, 'root')])

        elif startingNode == 'leaves':
            if self.__ballTreeNodes['radius'][index] < radius:

                while self.__ballTreeNodes['radius'][self.__relations[index]['parent']] < radius:
                    index = self.__relations[index]['parent']

            return index
        else:
            return None

    def __ComputeNodeLevel(self, index):
        """
        Compute the level of a node in the tree defined by its index.

        If the node has child nodes, the computation is done for them as well. The levels of the node and its children
        are updated in the internal array of levels.

        :param index: The index of the node

        :type index: int
        """
        if not ('parent' in self.__relations[index]):  # Checking if the node is the root
            self.__levels[index] = 0
        else:
            self.__levels[index] = self.__levels[self.__relations[index]['parent']] + 1

        if 'leftChild' in self.__relations[index]:  # Checking if the node has a left child
            self.__ComputeNodeLevel(self.__relations[index]['leftChild'])
        if 'rightChild' in self.__relations[index]:  # Checking if the node has a right child
            self.__ComputeNodeLevel(self.__relations[index]['rightChild'])

    # ------------- PROPERTIES -----------------
    @property
    def numberOfNodes(self):
        """
        Retrieve the total number of nodes in the ball tree

        :return: The number of nodes in the ball tree
        """
        return self.__numNodes

    @property
    def ballTreeLeaves(self):
        """
        Retrieving the indexes of the nodes which are leaves
        :return: A list of indexes for all the nodes which are leaves
        """
        return nonzero(self.__ballTreeNodes['is_leaf'] == 1)[0]

    @property
    def maxLevel(self):
        """
        Retrieve the maximum level of the tree

        :return: maximum level of the tree

        :rtype: int
        """
        return self.__levels.max()

    # @property
    # def X(self):
    #     return self.ToNumpy()[:, 0]
    #
    # @property
    # def Y(self):
    #     return self.ToNumpy()[:, 1]
    #
    # @property
    # def Z(self):
    #     return self.ToNumpy()[:, 2]

    @property
    def Size(self):
        return self.ToNumpy().shape[0]

    # ------------ GENERAL FUNCTIONS------------------
    def getNodeRadius(self, index):
        """
        Retrieve the radius of a node given by its index

        :param index: The index of the node whose radius is requested

        :type index: int

        :return: The radius of the node

        :rtype: float
        """
        return self.__ballTreeNodes['radius'][index]

    def getPointsOfNode(self, index):
        """
        Retrieve the indexes of the points in a given node

        :param index: The index of the node whose points are required

        :type index: int

        :return: list of indexes of the points in the node

        :rtype: list
        """

        return self.__ballTreePointIndexes[list(range(self.__ballTreeNodes[index]['idx_start'],
                                                      self.__ballTreeNodes[index]['idx_end']))]

    def getSmallestNodesOfSize(self, radius, startingNode='root'):
        """
        Get a list of the smallest nodes whose radii are larger than a given radius

        :param radius: The minimal required size of the nodes
        :param startingNode: Starting node for the search of the smallest node. Can be 'root' (top-down) or 'leaves' (bottom-up). Default: 'root'

        :type radius: float
        :type startingNode: str

        :return: list of the smallest nodes indices (ints)

        :rtype: list (int), None
        """
        if startingNode == 'root':
            return self.__getFirstNodeOfSize(0, radius=radius, startingNode='root')
        elif startingNode == 'leaves':
            leavesIndexes = self.ballTreeLeaves
            return unique(list(map(partial(self.__getFirstNodeOfSize, radius=radius), leavesIndexes)))
        else:
            return None

    def getNodeLevel(self, index):
        """
        Retrieve the level of a node defined by its index

        :param index: The index of the node whose level is required

        :type index: int

        :return: The level of the node

        :rtype: int
        """
        return self.__levels[index]

    def query(self, pnts, k, return_distnaces=False):
        """
        Query the ball tree for the k nearest neighbors of a given set of points

        :param pnts: The query points
        :param k: The number of neighbors to find for the point
        :param return_distnaces: flag to return computed distances

        :type pnts: np.array nx3
        :type k: int

        :return: The indexes for the neighbors of the points

        :rtype: list of np.array

        .. note::
            Return the query points themselves as the first index of each list

        """
        distances, indexes = self.data.query(pnts, k=k)
        if return_distnaces:
            return indexes, distances
        else:
            return indexes

    def queryRadius(self, pnts, radius):
        """
        Query the ball tree to find the neighbors of a given set of point inside a given radius

        :param pnts: The query points
        :param radius: The query radius

        :type pnts: np.array nx3
        :type radius: float

        :return: The indexes for the neighbors of the points

        :rtype: list of np.array

        .. note::
            Return the query points themselves as the first index of each list

        """
        if isinstance(pnts, list):
            pnts = array(pnts)

        if pnts.ndim == 1:
            indexes = self.data.query_radius(pnts.reshape((1, -1)), radius)

            if indexes.dtype == object:
                indexes = indexes[0]

        else:
            indexes = self.data.query_radius(pnts, radius)

        return indexes

    def getLeftChildOfNode(self, index):
        """
        Retrieve the index of the left child node of a given node

        :param index: The index of the node whose left child is required

        :type index: int

        :return: The index of the left child node or None, if the node does not have a left child

        :rtype: int, None

        """
        if 'leftChild' in self.__relations[index]:
            return self.__relations[index]['leftChild']
        else:
            return None

    def getRightChildOfNode(self, index):
        """
        Retrieve the index of the right child node of a given node

        :param index: The index of the node whose right child is required

        :type index: int

        :return: The index of the right child node or None, if the node does not have a right child

        :rtype: int, None
        """
        if 'rightChild' in self.__relations[index]:
            return self.__relations[index]['rightChild']
        else:
            return None

    def getParentOfNode(self, index):
        """
        Retrieve the index of the parent node of a given node

        :param index: The index of the node whose parent is required

        :type index: int

        :return: The index of the parent node or None, if the node does not have a parent (node is the root)

        :rtype: int, None
        """
        if 'parent' in self.__relations[index]:
            return self.__relations[index]['parent']
        else:
            return None

    def getSiblingOfNode(self, index):
        """
        Retrieve the index of the sibling node of a given node

        :param index: The index of the node whose sibling is required

        :type index: int

        :return: The index of the sibling node or None, if the node does not have a sibling

        :rtype: int, None
        """
        if 'sibling' in self.__relations[index]:
            return self.__relations[index]['sibling']
        else:
            return None

    def ToNumpy(self):
        """
        Points as numpy

        """
        return np.asarray(self.data.get_arrays()[0])

    def GetPoint(self, index):
        return self.ToNumpy()[index, :]


import torch
import torch.nn as nn
class T(nn.Module):
    def __init__(self):
        super().__init__()
        self.alpha = nn.Linear(2, 2)
        self.alpha = nn.Linear(2, 2)
    def forward(self, x):
        return self.l(self.weight)

a = torch.ones(2, 2)
model = T()

optm = torch.optim.SGD(model.parameters(), 1e-3)
label = torch.tensor([1,0])
ct=torch.nn.CrossEntropyLoss()

result = model(a)
loss=ct(result[0], label)
opt.zero_grad()
loss.backward()


import ray
import ray.rllib.agents.ppo as ppo
import json, os, shutil, sys
import gym
import pprint
import time
import shelve
from tensorflow import keras
from ray import tune
import csv

#@ray.remote(num_cpus=0)
def full_train(checkpoint_root, agent, n_iter, save_file, n_ini = 0, header = True, restore = False, restore_dir = None):
    s = "{:3d} reward {:6.2f}/{:6.2f}/{:6.2f} len {:6.2f} learn_time_ms {:6.2f} total_train_time_s {:6.2f} saved {}"
    if(restore):
        if restore_dir == None:
            print("Error: you must specify a restore path")
            return
        agent.restore(restore_dir)
    #else:
        #shutil.rmtree(checkpoint_root, ignore_errors=True, onerror=None)
    results = []
    episode_data = []
    episode_json = []

    total_learn_time = 0
    for n in range(n_iter):
        t0 = time.time()
        result = agent.train()
        t1 = time.time()-t0
        results.append(result)
        episode = {'n': n_ini + n + 1,
                   'episode_reward_min': result['episode_reward_min'],
                   'episode_reward_mean': result['episode_reward_mean'],
                   'episode_reward_max': result['episode_reward_max'],
                   'episode_len_mean': result['episode_len_mean'],
                   'learn_time_ms': result['timers']['learn_time_ms'],
                   'total_train_time_s': t1
                   }
        episode_data.append(episode)
        episode_json.append(json.dumps(episode))
        file_name = agent.save(checkpoint_root)
        print(s.format(
        n_ini + n + 1,
        result["episode_reward_min"],
        result["episode_reward_mean"],
        result["episode_reward_max"],
        result["episode_len_mean"],
        result["timers"]["learn_time_ms"],
        t1,
        file_name
       ))
        total_learn_time+= result["timers"]["learn_time_ms"]

    print("Total learn time: " + str(total_learn_time))
    print("Average learn time per iteration: " + str(total_learn_time/n_iter))

    with open(save_file + '.json', mode='a') as outfile:
        json.dump(episode_json, outfile)

    with open(save_file + '.csv', mode='a') as csv_file:
        fieldnames = ['n', 'episode_reward_min', 'episode_reward_mean', 'episode_reward_max', 'episode_len_mean', 'learn_time_ms','total_train_time_s']
        writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
        if header:
            writer.writeheader()
        for row in episode_data:
            writer.writerow(row)

    return results


"""This module contains classes for the representation of linear queries.

Linear queries should subclass AbstractLinearQueries. Use this module with
the following design principles:

1) Subclasses of AbstractLinearQuery should be simple. The only functionality
    they should provide is a more efficient version of some base class functions
2) Classes should not be instantiated directly. Instead, the QueryFactory should
    provide functions for instantiating the classes. Any complicated construction
    code should be moved from the class constructors and into a QueryFactory function

"""

import functools
from abc import ABCMeta, abstractmethod
import numpy as np
import scipy.sparse as ss

class AbstractLinearQuery(metaclass=ABCMeta):
    """ This class describes the api for queries

    There are two fields:
        self.name: the name of the query. Do not use
            directly. Call getName()
        self.matrix_rep: either none or a cached
           copy of the matrix representation. Do not
           use directly. Call matrixRep()
    """
    def __init__(self, name):
        self.matrix_rep = None
        self.name = name

    def getName(self):
        """ Returns the name of the query. """
        return self.name

    def answer(self, data):
        """ Returns the query answer over data

        Inputs:
            data: a multidimensional numpy array
        Output:
            a vector (not multi-d array) of answers
        Note: the default implementation might not be efficient
        """
        mydata = data.reshape(data.size)
        return self.matrixRep() * mydata

    @abstractmethod
    def kronFactors(self):
        """ Returns a list of matrices whose kron product is the matrix representation """
        pass

    def matrixRep(self):
        """ returns a cached version of the matrix representation if available """
        if self.matrix_rep is None:
            self.matrix_rep = self._matrixRep()
        return self.matrix_rep

    def _matrixRep(self):
        """ Should compute and return matrix representation of the query is csr format

        Note: when the data is flattened as a vector x, this function should return a
             matrix Q such that Qx is the answer to the query
        """
        rep = functools.reduce(lambda x, y: ss.kron(x, y, format="csr"), self.kronFactors())
        # Note: ss.kron differs from np.kron because in the case of kron of 1d vectors, ss.kron
        # returns a 1xc matrix  but np.kron returns a 1d array
        return rep

    def sensitivity(self):
        """ returns the sensitivity of this query set in the UNBOUNDED version of DP

        The sensitivity is the maximum l1 norm of the columns in the matrix representation.
        It can be efficiently computed as the product of the sensitivities of the kron factors.
        Override this  method for query classes where this can be computed faster.
        """
        sen = 1.0
        for mat in self.kronFactors():
            #verify that the kron matrices are either matrices or arrays
            assert len(mat.shape) in [2, 1]
            if len(mat.shape) == 2:
                minisen = np.abs(mat).sum(axis=0).max()
            else:
                minisen = np.abs(mat).max()
            sen = sen * minisen
        return sen

    def isIntegerQuery(self):
        """ Returns true if this is a counting query, e.g., coefficients are integers """
        result = True
        for mat in self.kronFactors():
            if np.abs(mat - np.round(mat)).sum() != 0:
                result = False
        return result

    def domainSize(self):
        """ returns the expected size (number of cells) in the data histogram.

        Note: This should equal the number of columns in the matrix representation
        The default implementation is slow. override this function
        """
        dims = [x.shape[1] if len(x.shape) == 2 else x.shape[0] for x in self.kronFactors()]
        result = np.prod(dims)
        return result

    def numAnswers(self):
        """ returns the number of cells to expect  in the answer

        Note: this should equal the number of rows in the matrix representation
        The default implementation is slow. Override this function
        """
        result = np.prod([x.shape[0] if len(x.shape) == 2 else 1 for x in self.kronFactors()])
        return result

class SparseKronQuery(AbstractLinearQuery):
    """ This class represents queries as a Kron product of sparse matrices """

    def __init__(self, matrices, name=""):
        """ Constructor for SparseKronQuery

        Input:
            matrices: a python list of sparse matrices (preferably in CSR format)
               The query is interpreted as the kron product of the matrices in this list
            name: an optional name for the query
        """
        super().__init__(name)
        self.matrices = matrices
        self.num_columns = np.prod(
            [x.shape[1] if len(x.shape) == 2 else x.shape[0] for x in matrices]
        )
        self.num_rows = np.prod([x.shape[0] if len(x.shape) == 2 else 1 for x in matrices])

    def kronFactors(self):
        return self.matrices

    def domainSize(self):
        return self.num_columns

    def numAnswers(self):
        return self.num_rows

class SumoverQuery(AbstractLinearQuery):
    """ This class provides a more efficient way of answering subset-marginal queries """

    def __init__(self, array_dims, subset=(), add_over_margins=(), name=""):
        """
            This initializes the necessary matrices/arrays.

            Inputs:
                array_dims: the natural dimensions of the data as a multidimensional histogram
                subset: a tuple of lists or iterators (e.g., range() objects)  that should match
                    the number of array dimensions that represent what subset of each dimension
                    we should use to construct the queries e.g ( [0] , range(0,2,1), [1,52,77],
                    range(0,2,1), range(0,63,1), range(0,52,1)).
                add_over_margins: the list of dimensions we will be summing over. None or empty
                    list or empty tuple imply no summation
        """
        super().__init__(name)
        self.array_dims = tuple(array_dims)
        if subset in (None, (), [], False):
            self.subset = np.ix_(*(range(self.array_dims[x]) for x in range(len(self.array_dims))))
            self.subset_input = tuple(
                range(self.array_dims[x]) for x in range(len(self.array_dims))
            )
        else:
            self.subset = np.ix_(*tuple(subset))
            self.subset_input = tuple(subset)
        if add_over_margins in ([], None):
            self.add_over_margins = ()
        else:
            self.add_over_margins = tuple(add_over_margins)
        self.num_columns = np.prod(self.array_dims)
        self.num_rows = np.prod(
            [len(x) for (i, x) in enumerate(self.subset_input) if i not in self.add_over_margins]
        )

    def domainSize(self):
        return self.num_columns

    def numAnswers(self):
        return self.num_rows

    def kronFactors(self):
        """
            This computes the Kronecker representation of the query.
        """
        matrices = [None] * len(self.array_dims)
        for i in range(len(self.array_dims)):
            if i in self.add_over_margins:
                x = np.zeros(self.array_dims[i], dtype=bool)
                x[self.subset_input[i]] = True
            else:
                full = ss.identity(self.array_dims[i], dtype=bool, format="csr")
                x = full[self.subset_input[i], :]
            matrices[i] = x
        return matrices

    def answer(self, data):
        dsize = self.domainSize()
        assert data.size == dsize, "Data does not match except cell count of {}".format(dsize)
        return data[self.subset].sum(axis=self.add_over_margins, keepdims=False).flatten()

class SumOverGroupedQuery(AbstractLinearQuery):
    """ This class provides a more efficient way of answering grouped/collapsed-marginal queries """

    def __init__(self, array_dims, groupings=None, add_over_margins=(), name=""):
        """
            This initializes the necessary matrices/arrays.

            Inputs:
                array_dims: the natural dimensions of the data as a multidimensional histogram

                groupings: this replaces the functionality of subsetting and additionally allows
                            to collapse levels of a dimension into one or more groupings.
                            The argument "groupings" is a dictionary in which the keys are the
                            dimensions (or axes) over which levels should be grouped and
                            the values are each a list containing 1 or more possible groupings
                            which themselves are represented as a list.  For example:

                            groupings = {
                            1: [[1],],
                            3: [range(0, 6), range(6, 21), range(21, 41),
                                range(41, 56), range(56, 62), range(62,63)]
                            }

                            Assume array_dims in this case is (8,2,2,63). This groupings argument
                            would take dimension/axis 1 and form a grouping with single level (1),
                            which is equivalent to subseting this dimension. In the dimension/axis
                            3 it will create 6 groupings that collapse the 63 levels into the
                            corresponding 6 groups by the range arguments listed.

                add_over_margins: the list of dimensions we will be summing over. None or empty
                    list or empty tuple imply no summation
        """
        super().__init__(name)
        self.array_dims = tuple(array_dims)
        self.groupings = groupings if isinstance(groupings, dict) else {}
        self.collapse_axes = list(self.groupings.keys())
        if add_over_margins in ([], None):
            self.add_over_margins = ()
        else:
            self.add_over_margins = tuple(add_over_margins)
        self.num_columns = np.prod(self.array_dims)
        nun_rows_temp = []
        for i in range(len(self.array_dims)):
            if i in self.add_over_margins:
                x = 1
            elif i in self.collapse_axes:
                x = len(self.groupings[i])
            else:
                x = self.array_dims[i]
            nun_rows_temp.append(x)
        self.num_rows = np.prod(nun_rows_temp)

    def domainSize(self):
        return self.num_columns

    def numAnswers(self):
        return self.num_rows

    def kronFactors(self):
        """
            This computes the Kronecker representation of the query.
        """
        matrices = [None] * len(self.array_dims)
        for i in range(len(self.array_dims)):
            if i in self.add_over_margins:
                x = np.ones(self.array_dims[i], dtype=bool)
            elif i in self.collapse_axes:
                n_groups = len(self.groupings[i])
                x = np.zeros((n_groups, self.array_dims[i]), dtype=bool)
                for j in range(n_groups):
                    subset = self.groupings[i][j]
                    x[j, subset] = True
            else:
                x = ss.identity(self.array_dims[i], dtype=bool, format="csr")
            matrices[i] = x
        return matrices

    def collapseLevels(self, data):
        """
        This function is used to iteratively collapse a single axis at a time
        in order to compute the answer to a query

        inputs:
                data: a numpy multi-array
        outputs:
                a numpy multi-array
        """
        #if there is no collapse_axes, just return the array
        result = None
        if self.collapse_axes == []:
            result = data
        else:
            x = data
            #iteratively call the collapse function for each grouping
            for i in self.collapse_axes:
                x = self.collapse(x, i, self.groupings[i])
            result = x
        return result

    @staticmethod
    def collapse(array, axis=None, groups=None):
        """
        This function collapses (adds over) groups of levels in a
        particular dimension of a multi-array

        Inputs:
            array: a numpy multiarray
            axis: the dimension/axis to be grouped (int)
            groups: a list of lists pertaining to the levles to be grouped together
        Output:
            a numpy multiarray
        """
        result = None
        if axis in (None, []) or groups in (None, []):
            assert False, "axis {} {}".format(axis, groups)
            result = array
        else:
            array_dims = array.shape
            n_groups = len(groups)
            #what are all the levels for the particular dimension
            subset = [range(x) for x in array_dims]
            #take a subset for each grouped
            #and append them to a list
            mylist = []
            for i in range(n_groups):
                subset[axis] = groups[i]
                mylist.append(array[np.ix_(*tuple(subset))].sum(axis=axis, keepdims=False))
            #finally stack the sub-arrays
            out = np.stack(mylist, axis=axis)
            result = out
        return result

    def answer(self, data):
        dsize = self.domainSize()
        assert data.size == dsize, "Data does not match except cell count of {}".format(dsize)
        return self.collapseLevels(data).sum(axis=self.add_over_margins, keepdims=False).flatten()

class StackedQuery(AbstractLinearQuery):
    """ This class stacks queries together """

    def __init__(self, queries, domain_subset=None, name=""):
        """ Constructs a stacked query

        Inputs:
            queries: a python list of queries with the same domain size
            domain_subset: a list of indices within the range of domain size
               or None if we want to keep the original domain
            name: an optional name for the query

        Note: this creates a stacked version of the queries over the specified
            Suppose we are stacking two queries with matrix representations A
            and B with dimensions nxd and mxd respectively. Then the new query
            has an (n+m)xd  matrix representation where the first n rows come
            from A then the next m come from B. If domain_subset is specified,
            it reduces the number of columns. For example if domain_subset=[1,3]
            then the matrix representation becomes (n+m)x2 and the top nx2 part of
            the matrix consists of A[:, [1,3]] (i.e. columns 1 and 3) and the bottom
            part consists of B[:, [1,3]]
        """
        super().__init__(name)
        if domain_subset is None:
            self.matrix_rep = ss.vstack([q.matrixRep() for q in queries], format="csr")
        else:
            self.matrix_rep = ss.vstack(
                [x.matrixRep()[:, domain_subset] for x in queries],
                format="csr")

    def kronFactors(self):
        return [self.matrix_rep]

class QueryFactory:
    """Class for instantiaing queries.

    Subclasses of AbstractLinearQuery should be constructed only by functions in this class.
    The job of the QueryFactory is to decide which class to use to represent a desired query

    """

    @staticmethod
    def makeKronQuery(kron_factors, name=""):
        """ Create a kron query """
        query = SparseKronQuery(kron_factors, name)
        return query

    @staticmethod
    def makeTabularQuery(array_dims, subset=(), add_over_margins=(), name=""):
        """ Creates a linear marginal query """
        query = SumoverQuery(array_dims, subset, add_over_margins, name)
        return query

    @staticmethod
    def makeTabularGroupQuery(array_dims, groupings=None, add_over_margins=(), name=""):
        """ Creates a linear query """
        myarray_dims = tuple(array_dims)
        for x in myarray_dims:
            assert isinstance(x, int), "array_dims {} must be ints".format(myarray_dims)
        if add_over_margins in ([], None):
            myadd_over_margins = ()
        else:
            for x in add_over_margins:
                #check that x is int and in range
                assert x in range(len(array_dims)), (
                    "add_over_margins {} must be take values "
                    " in {}").format(add_over_margins, range(len(array_dims)))
            #check that we don't get any duplicate dims
            assert len(add_over_margins) == len(set(add_over_margins)), (
                "add_over_margins {} has duplicate dims").format(add_over_margins)
            #passed checks, set myadd_over_margins
            myadd_over_margins = tuple(add_over_margins)
        if groupings in (None, (), [], False, {}):
            query = SumOverGroupedQuery(array_dims=myarray_dims,
                                        add_over_margins=myadd_over_margins, name=name)
        else:
            assert isinstance(groupings, dict), "groupings must be a dictionary"
            keys = list(groupings.keys())
            for x in keys:
                assert isinstance(x, int), "groupings keys must be integers"
            #check that the intersection is empty
            assert not set(keys).intersection(set(myadd_over_margins)), (
                "add_over_margins {} and groupings {} overlap").format(myadd_over_margins, keys)
            # if so set groupings
            mygroupings = groupings
            query = SumOverGroupedQuery(array_dims=myarray_dims, groupings=mygroupings,
                                        add_over_margins=myadd_over_margins, name=name)
        return query


import requests
from bs4 import BeautifulSoup
import time
import json

class YunSpider:
    """
    网易云音乐热歌榜
    """
    def __init__(self):
        self.base_url = 'https://music.163.com/discover/toplist?id=19723756'
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36',
            'Referer': 'https://music.163.com/',
            'Host': 'music.163.com',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
            'Upgrade-Insecure-Requests': '1',
        }
        self.temp = []

    def send_request(self):
        response = requests.get(self.base_url, headers=self.headers, timeout=60)
        data = response.text
        print(data)
        return data

    def save_file(self, data):
        with open('yun.json', 'w', encoding='utf-8') as f:
            json.dump(data, f, sort_keys=False, indent=4, separators=(',', ': '), ensure_ascii=False)
        print('==============+保存成功+=================')

    def parse_html(self, html):
        soup = BeautifulSoup(html)
        res_json_list = soup.find('textarea', id='song-list-pre-data').get_text()
        res_json_list = json.loads(res_json_list)
        res_dict = {}
        for res_json in res_json_list:

            res_dict['music_detail'] = 'https://music.163.com/weapi/v1/resource/comments/{}?csrf_token='.format(res_json.get('commentThreadId'))
            print('music_detail', res_json.get('commentThreadId'))

            res_dict['music_name'] = res_json.get('name')
            print('歌名:', res_json.get('name'))

            res_dict['name'] = res_json.get('artists')[0].get('name')
            print('歌手:', res_json.get('artists')[0].get('name'))

            t1 = time.localtime(res_json.get('publishTime') / 1000)
            t2 = time.strftime("%Y-%m-%d %H:%M:%S", t1)
            res_dict['created_time'] = t2
            print('歌曲发行时间:', t2)
            t3 = res_json.get('duration') / 1000
            min = int(t3 / 60)
            sec = str(int(t3 % 60))
            if len(sec) < 2:
                sec = '0' + str(sec)
            res_dict['time'] = str(min)+':'+sec
            print('歌曲时长:{}:{}'.format(min, sec))
            print('=============================================\n')
            self.temp.append(res_dict)
            res_dict = {}

    def run(self):
        html = self.send_request()
        self.parse_html(html)
        self.save_file(self.temp)

if __name__ == '__main__':
    YunSpider().run()


from collections import deque

def bfs():
    queue = deque()
    queue.append([home[0], home[1]])

    while queue:
        x, y = queue.popleft()

        if abs(x - destination[0]) + abs(y - destination[1]) <= 1000:
            print("happy")
            return
        for i in range(n):
            if not visited[i]:
                nx, ny = case[i]
                if abs(x - nx) + abs(y - ny) <= 1000:
                    queue.append([nx, ny])
                    visited[i] = 1
    print("sad")
    return

t = int(input())

for i in range(t):
    n = int(input())
    home = [int(x) for x in input().split()]

    case = []
    for i in range(n):
        x, y = map(int, input().split())
        case.append([x,y])

    destination = [int(x) for x in input().split()]

    visited = [0 for i in range(n+1)]
    bfs()


from sys import stdout as out

import logging

class Logger(logging.Logger):
    """Logging handler"""
    def __init__(self, levl=logging.INFO, name='root',
                 **kwargs):
        super(Logger, self).__init__(name, **kwargs)
        self.setLevel(levl)
        if len(self.handlers) < 1:
            ch = logging.StreamHandler(out)
            ch.setLevel(levl)
            formatter = logging.Formatter('\r%(levelname)s '
                                          '- %(message)s')
            ch.setFormatter(formatter)
            self.addHandler(ch)
        self.last_wr = ''
        self.is_prog = False

    def progress(self, name, i, i_max, levl=logging.INFO):
        if self.level > levl:
            return
        if self.last_wr != name:
            if self.is_prog:
                out.write('\n')
            self.is_prog = True
            out.write('{} - {} - '.format(logging.getLevelName(levl), name))
            out.write(' '*7)
            self.last_wr = name
        out.write('\b'*7 + '{:7.2%}'.format(i/i_max))
        if i == i_max-1:
            out.write('\r{} - {} - Done   '
                      ''.format(logging.getLevelName(levl), name))
            out.write('\n')
            self.is_prog = False
            self.last_wr = ''
        out.flush()

    def set_mode(self, levl=logging.INFO):
        self.debug('Set mode: {}'.format(logging.getLevelName(levl)))
        self.setLevel(levl)
        for ch in self.handlers:
            ch.setLevel(levl)

    def debug(self, msg, **kwargs):
        if self.level > 10:
            return
        if self.is_prog:
            out.write('\n')
        self.is_prog = False
        self.last_wr = ''
        super(Logger, self).debug(msg, **kwargs)

    def info(self, msg, **kwargs):
        if self.level > 20:
            return
        if self.is_prog:
            out.write('\n')
        self.is_prog = False
        self.last_wr = ''
        super(Logger, self).info(msg, **kwargs)

    def warning(self, msg, **kwargs):
        if self.level > 30:
            return
        if self.is_prog:
            out.write('\n')
        self.is_prog = False
        self.last_wr = ''
        super(Logger, self).warning(msg, **kwargs)

    def error(self, msg, **kwargs):
        if self.level > 40:
            return
        if self.is_prog:
            out.write('\n')
        self.is_prog = False
        self.last_wr = ''
        super(Logger, self).error(msg, **kwargs)

    def critical(self, msg, **kwargs):
        if self.level > 50:
            return
        if self.is_prog:
            out.write('\n')
        self.is_prog = False
        self.last_wr = ''
        super(Logger, self).exception(msg, **kwargs)

if __name__ == '__main__':
    log = Logger(levl=logging.DEBUG)

    i_max = 1000000

    for i in range(i_max):
        log.progress('Counter', i, i_max)


import requests    # by Kirill Kasparov, 2023
from bs4 import BeautifulSoup
import pandas as pd
import time

# программа берет список ИНН из файла и проверяет наличие конкурсов на сайте zakupki.gov.

start = time.time()    # для таймера выполнения

head = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)'
       ' Chrome/86.0.4240.185 YaBrowser/20.11.2.78 Yowser/2.5 Safari/537.36', 'accept': '*/*'}

inn_list_df = pd.read_csv('inn_list.csv', sep=';', encoding='windows-1251', dtype='unicode', nrows=1000)
inn_list = list(inn_list_df['ИНН'])

total_results_df = []
last_purchase = []
count = 0

for inn in inn_list:
    url = 'https://zakupki.gov.ru/epz/order/extendedsearch/results.html?searchString=' + str(inn) + '&morphology=on&search-filter=%D0%94%D0%B0%D1%82%D0%B5+%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%89%D0%B5%D0%BD%D0%B8%D1%8F&pageNumber=1&sortDirection=false&recordsPerPage=_10&showLotsInfoHidden=false&sortBy=UPDATE_DATE&fz44=on&fz223=on&af=on&ca=on&pc=on&pa=on&currencyIdGeneral=-1'
    r = requests.get(url, headers=head)
    if r.status_code == 200:
        soup = BeautifulSoup(r.content, 'html.parser')
        total_results = soup.findAll('div', class_='search-results__total')
        for elem in total_results:
            total_results_df.append(elem.text.strip())
        data_value = soup.findAll('div', class_="data-block__value")
        if len(data_value) > 1:
            last_purchase.append(data_value[0].text.strip())
        else:
            last_purchase.append('нет')
    count += 1
    if count % 50 == 0:
        end = time.time()
        while True:  # проверка, если файл открыт
            try:
                inn_list_df.to_csv('inn_list_export.csv', sep=';', encoding='windows-1251', index=False, header=True,
                                   mode='a')
                print('Загружено строк:', count, "|  Время выполнения:", end-start, '|  Данные добавлены в файл inn_list_export.csv')
                break
            except IOError:  # PermissionError
                input('Необходимо закрыть файл inn_list.csv перед сохранением данных')

inn_list_df['Всего записей на zakupki.gov'] = total_results_df
inn_list_df['Последняя закупка'] = last_purchase

while True:  # проверка, если файл открыт
    try:
        inn_list_df.to_csv('inn_list_export.csv', sep=';', encoding='windows-1251', index=False, header=True)
        end = time.time()
        print('Загружено строк:', count, "|  Время выполнения:", end-start, '|  Итоговые данные сохранены в файл inn_list_export.csv')
        break
    except IOError:    # PermissionError
        input('Необходимо закрыть файл inn_list.csv перед сохранением данных')


# Tutor: Tran Tien Duc
# Gmail: trantienduc@gmail.com
# Created by Cao Le Cong Minh
# Gmail: caolecongminh1997@gmail.com
# Github: https://github.com/Minh-CaoLeCong

# USAGE
# python power.py --input imagePath --gamma floatValue
# example:  python power.py --input E:\\CVS\\Project\\Digital_Image_Processing\\python\\image\\power.tif --gamma 0.3
#           python power.py --input E:/CVS/Project/Digital_Image_Processing/python/image/power.tif --gamma 0.3

# import the necessary packages
import argparse
import cv2
import numpy as np
import ntpath
import time
import math

def power(imageInput, gamma):
    """
    NOTE: denote the values of pixels, before and after processing, by r and s, respectively
	'c' and 'gamma' is a positive constant.
	we can see:
		if 'gamma' < 1, make the image brighter
		if 'gamma' > 1, make the image darker

		if r = 0,		then s = 0
	and	if r = L - 1,	then s = L - 1
	so the form of Power-law transformations: s = c * pow(r, gamma)
	we can compute: c = (L - 1) / pow(L - 1, gamma) or c = pow(L - 1, 1 - gamma)
    """
    # the number of possible intensity levels in the image (256 for an 8-bit image)
    L = 256

    if (imageInput.shape[-1] == 3): # '-1' retrieves last item that is number of channels image, or could use '-2'
        imageInput = cv2.cvtColor(imageInput, cv2.COLOR_BGR2GRAY) #Convert RGB image to Gray image

    imageOutput = np.zeros((imageInput.shape[0], imageInput.shape[1]), np.uint8)

    M = imageInput.shape[0] # height of image
    N = imageInput.shape[1] # width of image

    c = math.pow(L - 1, 1 - gamma)

    # throughout each pixel of image
    for x in range(0, M):
        for y in range(0, N):
            # denote the values of pixels, before and after processing, by r and s, respectively
            r = imageInput[x, y]
            if (r==0):
                r = 1
            # power-law transformation function:
            s = c * math.pow(r, gamma)
            imageOutput[x, y] = int(s)

    return imageOutput

# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--input", required=True,\
    help="input image path to processing")
ap.add_argument("-g", "--gamma", required=True,\
    help="gamma constant")
args = vars(ap.parse_args())

# read original image from input image path
inputImagePath = args["input"]
imageFileName = ntpath.basename(inputImagePath)
imageOriginal = cv2.imread(inputImagePath)

# display original image
cv2.imshow('original', imageOriginal)

# convert RGB to grayscale
imageGrayscale = cv2.cvtColor(imageOriginal, cv2.COLOR_BGR2GRAY)

# display grayscale image
cv2.imshow('grayscale', imageGrayscale)

# power-law processing
gamma = float(args["gamma"])
startTime = time.time()
imagePower = power(imageGrayscale, gamma)
print("[INFOR]: Time execution: {}".format(time.time() - startTime))

# display power processing image
cv2.imshow('power', imagePower)

print("[INFOR]: Press 's' key to save result and quit")
print("[INFOR]: Press 'q' key to quit and NOT save")
key = cv2.waitKey(0) & 0xFF
if key == ord("s"):
    resultPath = "./output/" + "power" + imageFileName
    cv2.imwrite(resultPath, imagePower)


import csv
from datetime import datetime

#CSV source
user_logs_csv = 'data/raw/user_logs.csv'

# for transfering the type ID to text
log_action_type = ['LOGIN', 'LOGOFF', 'ACCESSCALENDAR', 'ACCESSGOALS', 'ACCESSADDACTIVITYPAGE', 'ADDEDACTIVITY', 'ACCESSGALLERY', 'ACCESSADDPICTUREPAGE',
    'VIEWACTIVITY', 'DELETEACTIVITY', 'DELETEPICTUREFROMACTIVITY', 'UNLINKPICTUREFROMACTIVITY', 'UPDATEACTIVITY',
    'DELETEPICTUREFROMGALLERY', 'SELECTPICTUREFROMGALLRERYPAGE', 'ACCESSADDPICTUREDIRECTLYPAGE', 'ADDEDPICTUREDIRECTLY',
    'LINKPICTURETOACTIVITY', 'UPDATECALENDARDOWN', 'UPDATECALENDARUP', 'UPDATECALENDARDIRECTLY', 'ACCESSSELECTMEASUREMENTPAGE',
    'ACCESSADDGLUCOSEPAGE', 'ADDEDGLUCOSE', 'VIEWMEASUREMENT', 'ADDEDPICTURE', 'REMOVEDMEASUREMENT', 'UPDATEGLUCOSE', 'UPDATEINSULIN',
    'UPDATEDGLUCOSE', 'UPDATEDINSULINE', 'UPDATEDCARBOHYDRATE', 'UPDATECARBOHYDRATE', 'ACCESSADDCARBOHYDRATEPAGE', 'ADDEDINSULIN',
    'ADDEDCARBOHYDRATE', 'UPLOADEDPICTURE', 'ACCESSGOALADDDAILYPAGE', 'ADDEDGOALDAILY', 'ACCESSGOALADDTOTALPAGE', 'ADDEDGOALTOTAL',
    'DELETEGOAL', 'ACCESSUPDATEACTIVITYPAGE', 'ACCESSADDACTIVITYTYPEPAGE', 'ACCESSADDINSULINPAGE', 'ACCESSUPDATEGLUCOSEPAGE',
    'ACCESSUPDATEINSULINPAGE', 'ADDEDACTIVITYTYPE', 'DELETEACTIVITYTYPE', 'DELETEGLUCOSE', 'DELETEINSULIN', 'ADDEDWITHGLUCONLINE',
    'TOGETHERORSELF', 'TOGETHER']

with open(user_logs_csv, 'rb') as csvFile:
    reader = csv.DictReader(csvFile)
    raw_user_logs = list(reader)

def isOnDelList(name):
    delList = ['mike.ligthart', 'hunter', 'elvira', 'viewer']
    return name in delList

def changeNameForNumber(name):
    numberForName = ['benja', 'sinne', 'daan', 'tom', 'rick', 'martijn', 'hunter', 'ilse', 'casper', 'safiye', 'yasmin', 'koen', 'maas', 'janwillem']
    return 1 + numberForName.index(name)

user_logs = []

for raw_user_log in raw_user_logs:
    if isOnDelList(raw_user_log['USER_USER_NAME']) == False:
        user_log = {}
        user_log['participant'] = changeNameForNumber(raw_user_log['USER_USER_NAME'])
        user_log['timestamp'] = datetime.strptime(raw_user_log['TIMESTAMP'].split('.')[0], '%Y-%m-%d %H:%M:%S')
        user_log['behavior'] = log_action_type[int(raw_user_log['TYPE'])]
        user_logs.append(user_log)

with open('data/cleaned/user_logs.csv', 'wb') as outputFile:
    writer = csv.DictWriter(outputFile, user_logs[0].keys())
    writer.writeheader()
    writer.writerows(user_logs)


import angr

from ...storage.file import Flags
from .fstat import fstat

class stat(fstat):
    def run(self, p_addr, stat_buf):
        # open tempory fd
        strlen = angr.SIM_PROCEDURES["libc"]["strlen"]
        p_strlen = self.inline_call(strlen, p_addr)
        p_expr = self.state.memory.load(p_addr, p_strlen.max_null_index, endness="Iend_BE")
        file_path = self.state.solver.eval(p_expr, cast_to=bytes)
        fd = self.state.posix.open(file_path, Flags.O_RDONLY)

        # Use fstat to get the result and everything
        result = super().run(fd, stat_buf)

        # close tempory fd
        self.state.posix.close(fd)

        return result


'''
Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the
non-zero elements.

Example:

Input: [0,1,0,3,12]
Output: [1,3,12,0,0]
'''
from typing import List

class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        for num in nums:
            if num == 0:
                nums.remove(0)
                nums.insert(len(nums),0)

        return nums

    def moveZeroes1(self, nums: List[int]) -> None:
        c = 0

        for i in range(len(nums)):
            print (f"outside if :{nums[i]}")
            if nums[i]:
                print(f"inside if :{nums[i]}")

                nums[c] = nums[i]
                c += 1

        while c < len(nums):
            nums[c] = 0
            c += 1
        return nums

num = [0, 1, 0, 3, 12]

s = Solution()
print(s.moveZeroes(num))
num = [0, 1, 0, 0, 1, 2, 3, 12]

print(s.moveZeroes1(num))


from matplotlib import pyplot as plt
from matplotlib import dates as mplt_dates
from datetime import datetime, timedelta
import pandas as pd

# style
plt.style.use('seaborn')
dates = [
    datetime(2020, 8, 8),
    datetime(2020, 8, 9),
    datetime(2019, 8, 10),
    datetime(2020, 8, 11),
    datetime(2020, 8, 12),
    datetime(2020, 5, 22)]
y = [0, 1, 2, 3, 4, 5]
plt.plot_date(dates, y, linestyle='solid')
date_formater = mplt_dates.DateFormatter('%b,%d,%Y')
plt.gca().xaxis.set_major_formatter(date_formater)
plt.gcf().autofmt_xdate()
# show plot
plt.tight_layout()
plt.savefig('./plots/timeplot.png')
plt.show()


import boto3
import json
import string
import random

def lambda_handler(event, context):
    body = json.loads(event['body'])
    recipename = body.get('recipename')
    recipe = body.get('recipe')
    restaurantName = body.get('restaurantName')
    ingredients = body.get('ingredients')
    recipeid = body.get('recipeid')
    dynamodb = boto3.resource('dynamodb')
    table = dynamodb.Table('Recipe')
    print(body)

    #Author(s) name: Boto3 Docs
    #Date: 28 November 2022
    #Title of program/source code: 1.26.22 Documentations
    #Code version: v1
    #Type: Code
    #Web address: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#DynamoDB.Table.put_item

    table.put_item(
		Item = {
			'recipeid': recipeid,
			'restaurantName': restaurantName,
			'title': recipename,
			'recipe': recipe,
			'ingredients': ingredients
		}
	)

    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }


import abc
import typing

from bytecodemanipulation.assembler.AbstractBase import AbstractSourceExpression
from bytecodemanipulation.assembler.AbstractBase import IAssemblyStructureVisitable
from bytecodemanipulation.assembler.AbstractBase import IIdentifierAccessor
from bytecodemanipulation.assembler.AbstractBase import ParsingScope
from bytecodemanipulation.assembler.AbstractBase import StaticIdentifier
from bytecodemanipulation.assembler.Lexer import SpecialToken
from bytecodemanipulation.assembler.Parser import Parser
from bytecodemanipulation.assembler.syntax_errors import PropagatingCompilerException
from bytecodemanipulation.assembler.util.parser import AbstractExpression
from bytecodemanipulation.data.shared.expressions.CompoundExpression import (
    CompoundExpression,
)
from bytecodemanipulation.data.shared.instructions.AbstractInstruction import (
    AbstractAssemblyInstruction,
)

class AbstractIFAssembly(AbstractAssemblyInstruction, abc.ABC):
    # IF <expression> ['\'' <label name> '\''] '{' <body> '}'
    NAME = "IF"

    @classmethod
    def consume(cls, parser: "Parser", scope: ParsingScope) -> "AbstractIFAssembly":
        source = parser.try_consume_access_to_value(allow_primitives=True, scope=scope)

        if source is None:
            raise PropagatingCompilerException(
                "expected <expression> after IF"
            ).add_trace_level(scope.get_trace_info().with_token(parser[0]))

        if parser.try_consume(SpecialToken("'")):
            label_name = parser.parse_jump_target(scope)

            if not parser.try_consume(SpecialToken("'")):
                raise PropagatingCompilerException(
                    "expected ' after label name declaration"
                ).add_trace_level(scope.get_trace_info().with_token(parser[0]))

        else:
            label_name = None

        body = parser.parse_body(scope=scope)

        return cls(
            source,
            body,
            label_name,
        )

    def __init__(
        self,
        source: AbstractSourceExpression,
        body: CompoundExpression,
        label_name: typing.List[IIdentifierAccessor] | str = None,
    ):
        self.source = source
        self.body = body
        self.label_name = (
            (
                [StaticIdentifier(e) for e in label_name.split(":")]
                if isinstance(label_name, str)
                else label_name
            )
            if label_name is not None
            else None
        )

    def copy(self):
        return type(self)(self.source.copy(), self.body.copy(), self.label_name.copy())

    def __eq__(self, other):
        return (
            type(self) == type(other)
            and self.source == other.source
            and self.body == other.body
            and self.label_name == other.label_name
        )

    def __repr__(self):
        c = '"'
        return f"IF({self.source}{'' if self.label_name is None else f', label={c}' + ':'.join(map(repr, self.label_name)) + c}) -> {{{self.body}}}"

    def visit_parts(
        self,
        visitor: typing.Callable[
            [IAssemblyStructureVisitable, tuple, typing.List[AbstractExpression]],
            typing.Any,
        ],
        parents: list,
    ):
        return visitor(
            self,
            (
                self.source.visit_parts(visitor, parents + [self]),
                self.body.visit_parts(visitor, parents + [self]),
            ),
            parents,
        )

    def visit_assembly_instructions(
        self, visitor: typing.Callable[[IAssemblyStructureVisitable, tuple], typing.Any]
    ):
        return visitor(self, (self.body.visit_assembly_instructions(visitor),))

    def get_labels(self, scope: ParsingScope) -> typing.Set[str]:
        label_name = (
            ":".join(e(scope) for e in self.label_name)
            if self.label_name is not None
            else None
        )

        return (
            set()
            if self.label_name is None
            else {label_name, f"{label_name}:END", f"{label_name}:HEAD"}
        ) | self.body.get_labels(scope)