from datetime import timedelta
from typing import List, Tuple
import pygame
from pygame.draw import rect
from pygame.locals import *
import random
from .pygamextras import *
from .items import Items
from .bg_ui_elements import Badges

class YAwareGroup(pygame.sprite.Group):
    def by_y(self, spr):
        return spr.pos.y

    def draw(self, surface):
        sprites = self.sprites()
        surface_blit = surface.blit
        for spr in sorted(sprites, key=self.by_y):
            self.spritedict[spr] = surface_blit(spr.image, spr.rect)
        self.lostsprites = []
        print(self.by_y)

class Actor(pygame.sprite.Sprite):
    def __init__(self, image, pos=(200,200), surface=screen):
        super().__init__()
        self.colors = TextColors()
        self.image = image
        self.pos = pygame.Vector2(pos)
        # self.rect = self.image.get_rect(center=self.pos)
        self.rect = Rect(pos[0], pos[1], 32, 64)  # self.image.get_rect()
        self.W, self.H = W, H
        # self.image = pygame.image.load(asset('assets/img', 'player-anim.png'))
        self.movex = pos[0]
        self.movey = pos[1]

        self.current_sprite = 1  # constante de velocidad = 1000
        self.aleatorio = random.randrange(500, 999)

        self.sprites = []
        self.character = character_selected()

        if self.character in ('green', 'verde'):
            # Personaje Verde
            self.sprites.append(self.image.subsurface(0, 0, 32, 64))    # Stay_R0
            self.sprites.append(self.image.subsurface(32, 0, 32, 64))   # Stay_R1
            self.sprites.append(self.image.subsurface(64, 0, 32, 64))   # Walk_R0
            self.sprites.append(self.image.subsurface(96, 0, 32, 64))   # Walk_R1
            self.sprites.append(self.image.subsurface(256, 0, 32, 64))  # Stay_down0   <----
            self.sprites.append(self.image.subsurface(288, 0, 32, 64))  # Stay_down1
            self.sprites.append(self.image.subsurface(320, 0, 32, 64))  # Walk_down0
            self.sprites.append(self.image.subsurface(352, 0, 32, 64))  # Walk_down1
            self.sprites.append(self.image.subsurface(128, 0, 32, 64))  # Stay_up0
            self.sprites.append(self.image.subsurface(160, 0, 32, 64))  # Stay_up1
            self.sprites.append(self.image.subsurface(192, 0, 32, 64))  # Walk_up0
            self.sprites.append(self.image.subsurface(224, 0, 32, 64))  # Walk_up1
            self.sprites.append(pygame.transform.flip(self.sprites[0], True, False))  # Stay_L0
            self.sprites.append(pygame.transform.flip(self.sprites[1], True, False))  # Stay_L1
            self.sprites.append(pygame.transform.flip(self.sprites[2], True, False))  # Walk_L0
            self.sprites.append(pygame.transform.flip(self.sprites[3], True, False))  # Walk_L1
        elif self.character in ('blue', 'azul'):
            # Personaje azul
            self.sprites.append(self.image.subsurface(0, 64, 32, 64))
            self.sprites.append(self.image.subsurface(32, 64, 32, 64))
            self.sprites.append(self.image.subsurface(64, 64, 32, 64))
            self.sprites.append(self.image.subsurface(96, 64, 32, 64))
            self.sprites.append(self.image.subsurface(256, 64, 32, 64))
            self.sprites.append(self.image.subsurface(288, 64, 32, 64))
            self.sprites.append(self.image.subsurface(320, 64, 32, 64))
            self.sprites.append(self.image.subsurface(352, 64, 32, 64))
            self.sprites.append(self.image.subsurface(128, 64, 32, 64))
            self.sprites.append(self.image.subsurface(160, 64, 32, 64))
            self.sprites.append(self.image.subsurface(192, 64, 32, 64))
            self.sprites.append(self.image.subsurface(224, 64, 32, 64))
            self.sprites.append(pygame.transform.flip(self.sprites[0], True, False))
            self.sprites.append(pygame.transform.flip(self.sprites[1], True, False))
            self.sprites.append(pygame.transform.flip(self.sprites[2], True, False))
            self.sprites.append(pygame.transform.flip(self.sprites[3], True, False))
        elif self.character in ('red', 'rojo'):
            # Personaje rojo
            self.sprites.append(self.image.subsurface(0, 128, 32, 64))
            self.sprites.append(self.image.subsurface(32, 128, 32, 64))
            self.sprites.append(self.image.subsurface(64, 128, 32, 64))
            self.sprites.append(self.image.subsurface(96, 128, 32, 64))
            self.sprites.append(self.image.subsurface(256, 128, 32, 64))
            self.sprites.append(self.image.subsurface(288, 128, 32, 64))
            self.sprites.append(self.image.subsurface(320, 128, 32, 64))
            self.sprites.append(self.image.subsurface(352, 128, 32, 64))
            self.sprites.append(self.image.subsurface(128, 128, 32, 64))
            self.sprites.append(self.image.subsurface(160, 128, 32, 64))
            self.sprites.append(self.image.subsurface(192, 128, 32, 64))
            self.sprites.append(self.image.subsurface(224, 128, 32, 64))
            self.sprites.append(pygame.transform.flip(self.sprites[0], True, False))
            self.sprites.append(pygame.transform.flip(self.sprites[1], True, False))
            self.sprites.append(pygame.transform.flip(self.sprites[2], True, False))
            self.sprites.append(pygame.transform.flip(self.sprites[3], True, False))
        elif self.character in ('orange', 'nanaranjas'):
            # Personaje naranja
            self.sprites.append(self.image.subsurface(0, 192, 32, 64))
            self.sprites.append(self.image.subsurface(32, 192, 32, 64))
            self.sprites.append(self.image.subsurface(64, 192, 32, 64))
            self.sprites.append(self.image.subsurface(96, 192, 32, 64))
            self.sprites.append(self.image.subsurface(256, 192, 32, 64))
            self.sprites.append(self.image.subsurface(288, 192, 32, 64))
            self.sprites.append(self.image.subsurface(320, 192, 32, 64))
            self.sprites.append(self.image.subsurface(352, 192, 32, 64))
            self.sprites.append(self.image.subsurface(128, 192, 32, 64))
            self.sprites.append(self.image.subsurface(160, 192, 32, 64))
            self.sprites.append(self.image.subsurface(192, 192, 32, 64))
            self.sprites.append(self.image.subsurface(224, 192, 32, 64))
            self.sprites.append(pygame.transform.flip(self.sprites[0], True, False))
            self.sprites.append(pygame.transform.flip(self.sprites[1], True, False))
            self.sprites.append(pygame.transform.flip(self.sprites[2], True, False))
            self.sprites.append(pygame.transform.flip(self.sprites[3], True, False))

        self.surface = surface

        self.collide_rect = Rect(self.rect.midleft[0],self.rect.midleft[1], 32, 32)

        # Cargando el sprite.
        self.spritesheet = self.sprites

    def update(self):

        self.rect.x = self.movex
        self.rect.y = self.movey
        self.vars['location'][0] = self.rect.x
        self.vars['location'][1] = self.rect.y

        # Constante de velocidad...
        # aumente # de frames entre cada FPS
        self.current_sprite += self.aleatorio/10000

        if self.current_sprite > len(self.sprites):
            self.current_sprite = 0

        # si es entero cambiar frame
        self.image = self.sprites[int(self.current_sprite)-1]

class Player(Actor, Masking):
    def __init__(self, image, pos=[W//2, H//2], speed=3, surface=screen, W=W, H=H):
        # self.items = Items()

        super().__init__(image, pos, surface)
        Masking.__init__(self, [0,0])

        self.items = Items()

        # Creando la interfas del personaje
        self.badge = Badges()
        self.badge_rect = self.badge.rect
        self.badge_rect = self.rect.bottomleft

        self.speed = speed

        self.frame = 0
        self.bg = [0, 0]

        # pos-rect_list_dialogues
        self.prld = 0
        self.prld_x = 0
        self.prld_y = 0
        self.rect_btn_plus = [0,0]
        self.rect_btn_minu = [0,0]
        self.txt_rect = Rect(0,0,0,0)
        # self.newpos = []
        # self.colors= TextColors()
        self.rectn = self.rect
        self.slide_y = 10
        total = 0
        items = 0

        self.vars = {'left': False, 'right': False, 'up': False, 'down': False, 'last_dir': 'down', 'debug': False, 'location': [self.rect.x, self.rect.y]}

        self.vars['total_store'] = total
        self.vars['total_items'] = items

    def control(self, x, y):
        """
        control player movement
        """
        self.movex += x
        self.movey += y

    def badge_draw(self, badge):
        '''Creando el "grupo de sprites" dentro del Player sprite

        badge : nombre del badge desde ActionBadges
        '''
        badge_group = pygame.sprite.Group(self.badge)
        badge_group.update(badge, self.rect.midtop[0]+8, self.rect.midtop[1]-16)
            # badge, self.rect.midtop[0]+8, self.rect.midtop[1]-16)
        badge_group.draw(self.surface)

    def interaction(self):

        if key_press['F4_key']:
            #Rect global
            pygame.draw.rect(self.surface, 'red', (self.rect.x, self.rect.y, 32, 64), 1)
            # colider
            pygame.draw.rect(screen, self.colors.colorize(), self.collide_rect, 1)

            # Cargando el sprite desde ActionBadges
            posplayer = TExtra(f'pos: {self.rect.x}, {self.rect.y}', [self.rect.x, self.rect.y-20], 'deepskyblue')

        # Badges loader

        # self.dialogue_box()

    def dialogue_box(self, size=[250,100]):
        # Render mask ##########################
        badge = ActionBadges()
        self.badge_draw(badge.drawbadge())

        mask = Masking(size)

        newline_space = 15
        items_number = len(self.items.list)
        self.items_height = (newline_space*items_number)-newline_space*2

        # self.cube.rotate('gold', [50,50, 100,100], mask.mask_surf)
        mask.mask_surf.set_alpha(230)
        pygame.draw.rect(mask.mask_surf, 'gray65', (0,0,250, 100), 0)

        total = 0
        items = 0
        # Renderizado desde Items
        for item in self.items.list:
            # colorized1 = self.colors.colorize(50, 255)
            # colorized2 = self.colors.colorize(0, 200)

            pygame.draw.rect(mask.mask_surf, 'green', (self.prld_x-39, self.prld_y, 12,12), 0, 3)
            pygame.draw.rect(mask.mask_surf, 'chocolate1', (self.prld_x-24, self.prld_y, 12,12), 0, 3)
            pygame.draw.rect(mask.mask_surf, 'green4', (self.prld_x-39, self.prld_y, 12,12), 2, 3)
            pygame.draw.rect(mask.mask_surf, 'chocolate3', (self.prld_x-24, self.prld_y, 12,12), 2, 3)
            # print(self.rect_btn_plus)
            item['name'] = item['name'].replace("_", " ")

            mont = item['cost'] * item['quantity']

            # pos-rect_list_dialogues
            self.prld_x = mask.mask_rect.x + 45
            self.prld_y = mask.mask_rect.y + (item["id"] * newline_space + self.slide_y)
            self.prld = (self.prld_x, self.prld_y)

            itemx = TExtra(
                f'{item["quantity"]}, {item["name"]} ${mont}', self.prld, 'gray1', surface=mask.mask_surf)

            self.txt_rect = itemx.texto_rect
            self.rect_btn_plus = (self.prld_x+self.rect.x-289, self.prld_y+self.rect.y-100)
            self.rect_btn_minu = (self.prld_x+self.rect.x-272, self.prld_y+self.rect.y-100)

            # print(txt_rect)
            boton_mas = DialogueButtons(mask.mask_surf, self.rect_btn_plus)
            if pygame.Rect.collidepoint(boton_mas.rect, mouse.get_pos()):
                item['quantity'] += 1
                # print(f'{item["name"]} (+)')

            boton_menos = DialogueButtons(mask.mask_surf, self.rect_btn_minu)
            if pygame.Rect.collidepoint(boton_menos.rect, mouse.get_pos()):
                if item['quantity'] > 0:
                    item['quantity'] -= 1
                # print(f'{item["name"]} (-)')

            mont = item['cost'] * item['quantity']
            total += mont
            items += item['quantity']

            # print(mont)

        self.vars['total_store'] = total
        self.vars['total_items'] = items

        tit_dialog = TExtra(f'Tienda X - Items ({self.vars["total_items"]}) Tot:${self.vars["total_store"]}', [5,0], 'gray1', bgcolor='gray50', surface=mask.mask_surf)
        #texto de ejemplo para poner texto
        # textra('Hola!!!', [mask.mask_rect.x+5, mask.mask_rect.y+15+self.slide_y], surface=mask.mask_surf)

        mask.draw(screen, (0,0), (self.rect.topright), (-size[0]-32, -size[1]))
        # mask.draw(screen, (0,0), (self.rect.right, self.rect.top-50))

        # Se debe establecer la posicion de mask_rect en el contexto/ambito
        self.mask_rect.x = self.rect[0]-250
        self.mask_rect.y = self.rect[1]-100
        self.mask_rect.w = 250
        self.mask_rect.h = 100
        # self.mask_rect = self.rect
        pygame.draw.rect(screen, 'black', (self.mask_rect), 1)
        # print(self.rect, self.mask_rect)

        # Render mask ##########################

        # self.cube.rotate('blueviolet', [100,100,200,200], screen)

    def get_event(self, event):
        # Es mas recomendable utilizar
        # pygame.event.pump()
        # print(self.mask_rect)

        ''' Mecanismo de movimiento con el scroll/rueda del raton
        '''
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 4 and self.mask_rect.collidepoint(event.pos):
                if self.slide_y > -self.items.items_height:
                    self.slide_y -= 10
                # print('arriba')
            elif event.button == 5 and self.mask_rect.collidepoint(event.pos):
                if self.slide_y < 10:
                    self.slide_y += 10
                # print('abajo')

    # implementar este metodo para reducir codigo en update
    def select_sub_sprite(self, val_a, val_b):
        self.sprites = self.spritesheet
        self.sprites = self.sprites[val_a:val_b]
        return self.sprites

    def update(self):
        '''Actualiza el sprite con las mecanicas genrrales del player
        '''

        # Mecanica de colision con las tiendas
        # if self.rect.colliderect():
            # print('Colisione')

        display_percent = 3

        if self.vars['down']:
            if not self.rect.y + self.rect.height > self.H-(self.H//display_percent):
                self.player_down()
                self.control(y=self.speed, x=0)
                self.select_sub_sprite(6, 8)
            else:
                self.select_sub_sprite(6, 8)
                self.player_down()
                # Movement background trought player
                self.bg[1] -= self.speed

        elif self.vars['last_dir'] == 'down':
            self.select_sub_sprite(4, 6)

        if self.vars['right']:
            if not self.rect.x + self.rect.width > self.W-(self.W//display_percent):
                self.vars['last_dir'] = 'right'
                self.control(y=0, x=self.speed)
                self.select_sub_sprite(2, 4)
            else:
                self.select_sub_sprite(2, 4)
                self.vars['last_dir'] = 'right'
                # Movement background trought player
                self.bg[0] -= self.speed
        elif self.vars['last_dir'] == 'right':
            self.select_sub_sprite(0, 2)

        if self.vars['up']:
            if not self.rect.y < 0+(self.H//display_percent):
                self.vars['last_dir'] = 'up'
                self.control(y=-self.speed, x=0)
                self.select_sub_sprite(10, 12)
            else:
                self.select_sub_sprite(10, 12)
                self.vars['last_dir'] = 'up'
                # Moviendo el fondo
                self.bg[1] += self.speed
        elif self.vars['last_dir'] == 'up':
            self.select_sub_sprite(8, 10)

        if self.vars['left']:
            if not self.rect.x < 0+(self.W//display_percent):
                self.vars['last_dir'] = 'left'
                self.control(y=0, x=-self.speed)
                self.select_sub_sprite(14, 16)
            else:
                self.select_sub_sprite(14, 16)
                self.vars['last_dir'] = 'left'
                # Movement background trought player
                self.bg[0] += self.speed
        elif self.vars['last_dir'] == 'left':
            self.select_sub_sprite(12, 14)

        self.vars['location'][0] = self.rect.x = self.movex
        self.vars['location'][1] = self.rect.y = self.movey

        self.collide_rect[0] = self.movex
        self.collide_rect[1] = self.movey + 48
        self.collide_rect[3] = 16
        ## Borra
        # self.vars['location'][0] = self.rect.x
        #  = self.rect.y

        # Constante de velocidad...
        # aumente # de frames entre cada FPS
        self.current_sprite += self.aleatorio/10000

        if self.current_sprite > len(self.sprites):
            self.current_sprite = 0

        # si es entero cambiar frame
        self.image = self.sprites[int(self.current_sprite)-1]

    def player_up(self):
        self.vars['last_dir'] = 'up'

    def player_down(self):
        self.vars['last_dir'] = 'down'

    def player_left(self):
        self.vars['last_dir'] = 'left'

    def player_right(self):
        self.vars['last_dir'] = 'right'


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os
import sys
import tarfile

from six.moves import urllib
import tensorflow as tf

LABELS_FILENAME = 'labels.txt'

def int64_feature(values):
  """Returns a TF-Feature of int64s.

  Args:
    values: A scalar or list of values.

  Returns:
    A TF-Feature.
  """
  if not isinstance(values, (tuple, list)):
    values = [values]  #将传入数据轩为 元组或列表
  return tf.train.Feature(int64_list=tf.train.Int64List(value=values))

def bytes_feature(values):
  """Returns a TF-Feature of bytes.  string -> byte

  Args:
    values: A string.

  Returns:
    A TF-Feature.
  """
  return tf.train.Feature(bytes_list=tf.train.BytesList(value=[values]))

def float_feature(values):
  """Returns a TF-Feature of floats.

  Args:
    values: A scalar of list of values.

  Returns:
    A TF-Feature.
  """
  if not isinstance(values, (tuple, list)):
    values = [values]  #将传入数据轩为 元组或列表
  return tf.train.Feature(float_list=tf.train.FloatList(value=values))

def image_to_tfexample(image_data, image_format, height, width, class_id):
  return tf.train.Example(features=tf.train.Features(feature={
      'image/encoded': bytes_feature(image_data),
      'image/format': bytes_feature(image_format),
      'image/class/label': int64_feature(class_id),
      'image/height': int64_feature(height),
      'image/width': int64_feature(width),
  }))

def download_and_uncompress_tarball(tarball_url, dataset_dir):
  """Downloads the `tarball_url` and uncompresses it locally.

  Args:
    tarball_url: The URL of a tarball file.
    dataset_dir: The directory where the temporary files are stored.
  """
  filename = tarball_url.split('/')[-1]  #filename
  filepath = os.path.join(dataset_dir, filename)  #locally filename

  def _progress(count, block_size, total_size):
    # progress(n.  进步, 前进, 发展)
    sys.stdout.write('\r>> Downloading %s %.1f%%' % (
        filename, float(count * block_size) / float(total_size) * 100.0))
    sys.stdout.flush()
  filepath, _ = urllib.request.urlretrieve(tarball_url, filepath, _progress)
  # retrieve(v.  重新得到, 收回; 检索, 撷取; 衔回; 使恢复; 找回猎物)
  print()
  statinfo = os.stat(filepath)
  print('Successfully downloaded', filename, statinfo.st_size, 'bytes.')
  # 解压文件
  tarfile.open(filepath, 'r:gz').extractall(dataset_dir)

def write_label_file(labels_to_class_names, dataset_dir,
                     filename=LABELS_FILENAME):
  """Writes a file with the list of class names.

  Args:
    labels_to_class_names: A map of (integer) labels to class names.
    dataset_dir: The directory in which the labels file should be written.
    filename: The filename where the class names are written.
  """
  labels_filename = os.path.join(dataset_dir, filename)
  with tf.gfile.Open(labels_filename, 'w') as f:
    for label in labels_to_class_names:
      class_name = labels_to_class_names[label]
      f.write('%d:%s\n' % (label, class_name))

def has_labels(dataset_dir, filename=LABELS_FILENAME):
  """Specifies whether or not the dataset directory contains a label map file.
     specify(v.  具体指定; 明确说明; 详细指明; 把...列入说明书)

  Args:
    dataset_dir: The directory in which the labels file is found.
    filename: The filename where the class names are written.

  Returns:
    `True` if the labels file exists and `False` otherwise.
  """
  return tf.gfile.Exists(os.path.join(dataset_dir, filename))

def read_label_file(dataset_dir, filename=LABELS_FILENAME):
  """Reads the labels file and returns a mapping from ID to class name.

  Args:
    dataset_dir: The directory in which the labels file is found.
    filename: The filename where the class names are written.

  Returns:
    A map from a label (integer) to class name.
  """
  labels_filename = os.path.join(dataset_dir, filename)
  # 读入二进制文件 并解码成str
  with tf.gfile.Open(labels_filename, 'rb') as f:
    lines = f.read().decode()
  # 以 \n 分隔, 并去掉 None
  lines = lines.split('\n')
  lines = filter(None, lines)

  labels_to_class_names = {}
  for line in lines:
    index = line.index(':')
    # 往字典里添加 label (integer) : class name
    labels_to_class_names[int(line[:index])] = line[index+1:]
  return labels_to_class_names


"""
Compare the different iterative solvers on one LASSO problem.

- Use example/comparison_oracle_ista.py to run the benchmark.
  The results are saved in figures/.
"""

import numpy as np
import matplotlib.pyplot as plt

from adopty.ista import ista
from adopty.fista import fista
from adopty.oracle_ista import oracle_ista
from adopty.backtracking_ista import backtracking_ista

############################################
# Configure matplotlib and joblib cache
############################################
from setup import colors, rc
plt.rcParams.update(rc)

###########################################
# Fix random seed for reproducible figures
###########################################
seed = np.random.randint(100000)
seed = 92518
rng = np.random.RandomState(seed)

###########################################
# Parameters of the simulation
###########################################
n_atoms = 50
n_dims = 10
max_iter = 200
D = rng.randn(n_atoms, n_dims)
x = rng.randn(n_dims)
x /= np.max(np.abs(D.dot(x)))
lmbd = 0.5

############################################
# Benchmark computation function
############################################
_, cost_ista, times_ista = ista(D, x[None, :], lmbd, max_iter=max_iter)
_, cost_fista, times_fista = fista(D, x[None, :], lmbd, max_iter=max_iter)
_, cost_oista, times_oista, steps = oracle_ista(D, x, lmbd, max_iter=max_iter)
_, cost_btista, times_btista, steps_bt = backtracking_ista(D, x, lmbd, eta=.95,
                                                           max_iter=max_iter)
cost_ista = np.array(cost_ista)
cost_oista = np.array(cost_oista)
cost_fista = np.array(cost_fista)
cost_btista = np.array(cost_btista)
z_hat, c_star, _ = ista(D, x[None, :], lmbd, max_iter=3000)
c_star = c_star[-1]

############################################
# Plot the results
############################################
f, axes = plt.subplots(2, 1, figsize=(4, 3), sharex=True,
                       gridspec_kw={'height_ratios': [3, 1]})
ax = axes[0]
ax.semilogy(cost_ista - c_star, label=r'ISTA', color=colors['ISTA'],
            linewidth=2)
ax.semilogy(cost_fista - c_star, label=r'FISTA', color=colors['FISTA'],
            linewidth=2)
ax.semilogy(cost_btista - c_star,
            label=r'BTISTA', color=colors['BTISTA'], linewidth=2)
ax.semilogy(cost_oista - c_star,
            label=r'OISTA (proposed)',
            color=colors['OISTA'], linewidth=2)
ax.grid()
ax.set_ylim([1e-15, cost_ista[0] - c_star])
ax.set_yticks([1e-6, 1e-12])
lgd = f.legend(ncol=3, loc='upper center', handletextpad=0.1, handlelength=0.9,
               columnspacing=.7)
ax2 = axes[1]
ax2.plot(steps / steps[0], color=colors['OISTA'], linewidth=2)
# ax2.plot(steps_bt / steps[0], color=colors['BTISTA'], linewidth=2)
textx = len(steps) / 2 - 3
text_width = 10
ax2.hlines(1., 0, textx - 4, color='k', linestyle='--')
ax2.hlines(1., textx + text_width, len(steps), color='k', linestyle='--')
ax2.text(textx, .7, r'$\frac{1}{L}$', fontsize=15)
ax2.set_ylim(0.1, max(steps/steps[0]) + .2)
ax2.set_ylabel(r'Oracle step')
ax2.set_xlim(0, len(steps)-1)
x = ax2.set_xlabel(r'Number of iterations')
y = ax.set_ylabel(r'$F_x - F_x^*$')
ax2.grid()
plt.subplots_adjust(top=0.85)
plt.savefig('figures/comparison_oista_ista.pdf',
            bbox_extra_artists=[lgd, x, y], bbox_inches='tight')

# Separate plot for step sizes in presentations
fig = plt.figure(figsize=(6, 3))
ax3 = fig.subplots()
ax3.plot(steps / steps[0], color=colors['OISTA'], linewidth=2)
textx = len(steps) / 2 - 3
text_width = 10
ax3.hlines(1., 0, textx - 4, color='k', linestyle='--')
ax3.hlines(1., textx + text_width, len(steps), color='k', linestyle='--')
ax3.text(textx, .7, r'$\frac{1}{L}$', fontsize=15)
ax3.set_ylim(0.5, max(steps/steps[0]) + .2)
ax3.set_ylabel(r'Oracle step')
ax3.set_xlim(0, len(steps)-1)
x = ax3.set_xlabel(r'Number of iterations')
y = ax.set_ylabel(r'$F_x - F_x^*$')
ax3.grid()
ax3.set_xticks([0, 50, 100, 150])
plt.savefig('figures/comparison_oista_ista_steps.pdf')

plt.show()


import unittest
from unittest.mock import MagicMock
from priority_classes import Hospital, Patient, RiskLevel

class TestHospital(unittest.TestCase):
    def setUp(self):
        self.hospital = Hospital()

    def test_triage_patient_high_acuity(self):
        patient = Patient(has_high_acuity=True)
        self.hospital.triage_patient(patient)
        self.assertEqual(patient.triaged_risk, RiskLevel.HIGH)
        self.assertTrue(patient.has_been_triaged)
        self.assertEqual(self.hospital.risk_change_count, 1)

    def test_triage_patient_moderate_acuity(self):
        patient = Patient(has_moderate_acuity=True)
        self.hospital.triage_patient(patient)
        self.assertEqual(patient.triaged_risk, RiskLevel.MODERATE)
        self.assertTrue(patient.has_been_triaged)
        self.assertEqual(self.hospital.risk_change_count, 1)

    def test_triage_patient_needs_stabilization(self):
        patient = Patient(needs_stabilization=True, current_clinical_risk="Moderate")
        self.hospital.triage_patient(patient)
        self.assertEqual(patient.triaged_risk, "Moderate")
        self.assertTrue(patient.has_been_triaged)
        self.assertEqual(self.hospital.risk_change_count, 0)

    def test_triage_patient_low_acuity(self):
        patient = Patient(current_clinical_risk="Low")
        self.hospital.triage_patient(patient)
        self.assertIsNone(patient.triaged_risk)
        self.assertFalse(patient.has_been_triaged)
        self.assertEqual(self.hospital.risk_change_count, 0)

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


# Faça um Programa que leia um vetor de 5 números inteiros e mostre-os.
vetor = [0, 1, 2, 3, 4]
print(vetor[:])

# Faça um Programa que leia um vetor de 10 números reais e mostre-os na ordem inversa.
vetor = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(vetor[::-1])

# Faça um Programa que leia 4 notas, mostre as notas e a média na tela.
notas = [9, 3, 6, 8]
print(notas)
# soma = notas[0]+notas[1]+notas[2]+notas[3]
media = (notas[0]+notas[1]+notas[2]+notas[3]) / 4
print(media)

# Faça um Programa que leia um vetor de 10 itens, e diga quantas letras foram lidas. Imprima as letras.
vetor1 = ['a', 'b', 3, 5, 'c', 'd', 3, 'e', 'f', 2]
tipoConsoante = type(vetor1[0])
listaLetras = []

for i in vetor1[0::1]:
    if (str == type(i)):
        if (not i.isnumeric()):
            listaLetras.append(i)

print('essa é a quantidade de letras:', len(listaLetras))
print(listaLetras, '\n')

# Faça um Programa que leia um vetor de 10 caracteres, e diga quantas consoantes foram lidas. Imprima as consoantes.
vetor2 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
listaConsoante = []
'''
vetor2.remove('a')
vetor2.remove('e')
vetor2.remove('i')

print('há esse número de consoantes:',len(vetor2))
print(vetor2)

'''
for i in vetor2[::1]:
  if (i == 'a'):
    vetor2.remove('a')
    #listaConsoante.append(vetor2)
  elif(i == 'e'):
    vetor2.remove('e')
    #listaConsoante.append(vetor2)
  elif(i == 'i'):
    vetor2.remove('i')
    listaConsoante.append(vetor2)

print('O número de consoantes é : ',len(listaConsoante[0][:]),'\n', listaConsoante,'\n')

'''
  elif (i != 'e'):
    listaConsoante.append(i)
  elif (i != 'i'):
    listaConsoante.append(i)
  elif (i != 'o'):
    listaConsoante.append(i)
  elif (i != 'u'):
    listaConsoante.append(i)
'''

#Faça um Programa que leia 20 números inteiros e armazene-os num vetor. Armazene os números pares no vetor PAR e os números IMPARES no vetor impar. Imprima os três vetores.
vetorAdd = []

for i in range(21):
  vetorAdd.append(i)

vetorPar = [vetorAdd[2::2]]
vetorImpar = [vetorAdd[1::2]]

print('impares:',vetorImpar)
print('pares:',vetorPar)
vetorAdd.remove(0)
print('Com todos Inteiros:',vetorAdd,'\n')

#Faça um Programa que peça as quatro notas de 10 alunos, calcule e armazene num vetor a média de cada aluno, imprima o número de alunos com média maior ou igual a 7.0.

i = 1
aluno = []

while (i <= 10):
  print('Aluno', i,'\n')
  nota1 = float(input('Digite sua primeira nota: '))
  nota2 = float(input('Digite sua segunda nota: '))
  nota3 = float(input('Digite sua terceira nota: '))
  nota4 = float(input('Digite sua quarta nota: '))
  print('='*10, '\n')

  media = (nota1 + nota2 + nota3 + nota4) / 4
  if (media > 7.0):
    aluno.append(media)
  i += 1

print('Dos 10 alunos %d passaram!' %(len(aluno)))

#Faça um Programa que leia um vetor de 5 números inteiros, mostre a soma, a multiplicação e os números.

vetor4 = [1, 2, 3, 4, 5]

soma = vetor4[0] + vetor4[1] + vetor4[2] + vetor4[3] + vetor4[4]

multiplica = vetor4[0] * vetor4[1] * vetor4[2] * vetor4[3] * vetor4[4]

print('soma:', soma)
print('multiplicação:', multiplica)


# 以下部分均为可更改部分，但是不要删除必要接口

from answer_task1 import *

class WalkingController():

    @staticmethod
    def build_kargs():
        '''
        用于构建初始化的参数字典,比如你希望传入一个motion
        '''
        kargs = {
            'motion': r'motion_material\walkF.bvh'
        }
        return kargs

    def __init__(self, physics_info, physics_handler, **kargs) -> None:
        self.physics_info = physics_info
        self.physics_handler = physics_handler
        self.simulated_step = 0
        # 注意必须调整joint_name
        self.motion = BVHMotion(kargs['motion'])
        self.motion.adjust_joint_name(physics_info.joint_name)

    def prepare(self):
        '''
        在仿真开始前调用, 可以用于训练或开环优化
        作为实例我们简单地初始化一下姿势
        '''
        translation, orientation = self.motion.batch_forward_kinematics(frame_id_list = [0])
        self.physics_handler.set_pose(translation[0], orientation[0])

        pass

    def apply_torque(self):
        '''
        在仿真每一帧调用, 返回值为每个关节应该施加的力矩
        我们这里用的是静态站立力矩
        '''
        torque = part3_cal_static_standing_torque(self.motion, self.physics_info)
        self.simulated_step += 1
        return torque


#!/usr/bin/env python

import sys
import logging
import argparse
import itertools

def solve(outlets, devices):
    devices = set(devices)
    outlets = [list(o) for o in outlets]
    L = len(outlets[0])

    def check(perm):
        for o in outlets:
            tmp = list(o)
            for i in perm:
                if tmp[i] == '1':
                    tmp[i] = '0'
                else:
                    tmp[i] = '1'
            t = ''.join(tmp)
            if t not in devices:
                return False
        return True

    for num in xrange(L+1):
        for perm in itertools.combinations(range(L), num):
            if check(perm):
                return num
    return "NOT POSSIBLE"

def main(inp, output):
    T = int(next(inp))
    for case in range(1,T+1):
        N, L = [int(x) for x in next(inp).split()]
        outlets = [x for x in next(inp).split()]
        devices = [x for x in next(inp).split()]
        r = solve(outlets, devices)
        s = "Case #%d: %s" % (case, r)
        print(s)
        output.write(s + "\n")
        logging.info(s)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="run code jam problem")
    parser.add_argument("filename", type=str, help="input filename")
    parser.add_argument("-v", "--verbose", action="store_true",
                        help="enable verbose logging")

    args = parser.parse_args()
    if args.verbose:
        level=logging.DEBUG
    else:
        level=logging.INFO
    logging.basicConfig(level=level,
                        filename="logfile.txt",
                        filemode="w")
    outfile = args.filename + ".out"

    with open(args.filename) as inp:
        with open(outfile, "w") as outp:
            main(inp, outp)


#Uses python3

def max_dot_product(a, b):
    a = sorted(a, reverse=True)
    b = sorted(b, reverse=True)
    return sum([x*y for (x,y) in zip(a, b)])

if __name__ == '__main__':
    n = int(input())
    a = [int(ai) for ai in input().split()]
    b = [int(bi) for bi in input().split()]
    assert len(a) == len(b) == n
    print(max_dot_product(a, b))


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Sep 20 14:27:56 2019

@author: wanglab
"""

import tifffile, matplotlib.pyplot as plt, numpy as np, os, sys
import matplotlib.colors
cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", ["white", "Red"])
from skimage import filters
sys.path.append("/jukebox/wang/zahra/python/lightsheet_py3") #if you clone this repo yourself you can then set this path to your copy of the code fyi
from tools.imageprocessing.orientation import fix_orientation
from tools.conv_net.utils.io import read_roi_zip
from tools.registration.transform import transformed_pnts_to_allen_helper_func
from tools.registration.register import count_structure_lister
from tools.utils.io import load_kwargs

brain = "/jukebox/wang/oostland/lightsheet/m26"

brainname = os.path.basename(brain)
roipth = os.path.join(brain, "probe_track_points_coronal.zip")

rois = np.array([[int(yy) for yy in xx[0].replace(".roi", "").split("-")] for xx in
                            read_roi_zip(roipth, include_roi_name=True)])

pnts = np.array([[xx[0]-1, xx[1], xx[2]] for xx in rois]) #correct for fijis 1-based z numbering
pnts_sag = np.array([[xx[2], xx[0], xx[1]] for xx in pnts])

kwargs = load_kwargs(brain)
impth = [vol for vol in kwargs["volumes"] if vol.ch_type == "injch" or vol.ch_type == "cellch"][0].ch_to_reg_to_atlas

im = tifffile.imread(impth)
imcor = fix_orientation(im, ("2", "0", "1")) #points clicked in coronal vol

track = np.zeros_like(imcor)
size = (1,20,1) #size of dilatation in zyx
otsu_factor=1

for pnt in pnts:
    vol = np.copy(imcor[np.max((pnt[0]-size[0],0)):pnt[0]+size[0], np.max((pnt[1]-size[1],0)):pnt[1]+size[1],
                        np.max((pnt[2]-size[2],0)):pnt[2]+size[2]])*1.0
    v=filters.threshold_otsu(vol)/float(otsu_factor)
    vol[vol<v]=0
    vol[vol>=v]=1
    nvol = np.maximum(track[np.max((pnt[0]-size[0],0)):pnt[0]+size[0], np.max((pnt[1]-size[1],0)):pnt[1]+size[1],
                            np.max((pnt[2]-size[2],0)):pnt[2]+size[2]], vol)
    track[np.max((pnt[0]-size[0],0)):pnt[0]+size[0], np.max((pnt[1]-size[1],0)):pnt[1]+size[1],
          np.max((pnt[2]-size[2],0)):pnt[2]+size[2]]=nvol

merged = np.stack([imcor.astype("uint16"), track.astype("uint16"), np.zeros_like(imcor.astype("uint16"))], -1)

tifffile.imsave(os.path.join(brain, "%s_probe_track_overlay.tif" % brainname), merged.astype("uint16"))

#export coordinates
if os.path.exists(os.path.join(brain, "{}_allen_coordinates.txt".format(brainname))): os.remove(os.path.join(brain, "{}_allen_coordinates.txt".format(brainname)))
with open(os.path.join(brain, "{}_allen_coordinates.txt".format(brainname)), "a") as txt:
    txt.write("\nAtlas coordinates (zyx) in the saggital orientation:\n%s\n" % pnts_sag)
    txt.write("\nAtlas coordinates (zyx) in the coronal orientation:\n%s" % pnts)

#convert to structure
annotation_file = kwargs["annotationfile"]
ann = tifffile.imread(annotation_file)
zpnts, ypnts, xpnts = np.nonzero(fix_orientation(track, ("1", "2", "0"))) #make it back to sagittal for mapping
points = transformed_pnts_to_allen_helper_func([(zi,ypnts[i],xpnts[i]) for i, zi in enumerate(zpnts)], ann, order = "ZYX")

#make dataframe
lut_path = "/jukebox/LightSheetTransfer/atlas/ls_id_table_w_voxelcounts.xlsx" #corresponds with the atlas, change if changing atlas
df = count_structure_lister(lut_path, *points)
df.to_excel(os.path.join(brain, "%s_allen_structures.xlsx" % brainname))


from datetime import datetime, timedelta
from django.http import JsonResponse
from django.shortcuts import render

from .forms import ArtikkelForm, TestForm, FeedbackForm
# from .functions import Nedetidskost, WeibullCDF, ProbNede, ProbSurvival
from .models import Artikkel, FastParameter, Feedback

import json

# Create your views here.
def test(request):
    if request.method == 'POST':
        form = TestForm(request.POST)
        if form.is_valid():
            decision = True
            form.save()
            instance = form.save()
            queryset = Artikkel.objects.get(pk = instance.pk)
            context = {'decision': decision, 'form': form, 'queryset': queryset}
        else:
            context = {'form': form}
    else:
        form = TestForm()
        context = {'form': form}

    return render(request, 'index.html', context)

def feed(request):
    if request.method == "POST":
        feedback = FeedbackForm(request.POST)
        if feedback.is_valid():
            success = True
            feedback.save()
            context = {'feedback': feedback, 'success': success}
        else:
            feedback = FeedbackForm()
            context = {'feedback': feedback}
    else:
        feedback = FeedbackForm()
        context = {'feedback': feedback}
    return render(request, 'feedback.html', context)

def main(request):
    if request.method == 'POST': # hva som skal skje når skjemaet sendes
        lagerkost = 0.05
        today = datetime.today().date()

        form = ArtikkelForm(request.POST)

        context = {
        'form': form
        }

        if form.is_valid(): # Hvis det som er lagt inn i skjemaet er gyldige greier
            art_nr = form.cleaned_data['art_nr']
            pris = form.cleaned_data['pris']
            leveringstid = form.cleaned_data['leveringstid']
            sist_byttet = form.cleaned_data['sist_byttet']
            planlagt_byttet = form.cleaned_data['planlagt_byttet']
            hvor_sikkert = form.cleaned_data['skal_byttes']

            context.update({
                'art_nr': art_nr,
                'pris': pris,
                'leveringstid': leveringstid,
                'sist_byttet': sist_byttet,
                'planlagt_byttet': planlagt_byttet,
                'hvor_sikkert': hvor_sikkert
                })

    else:
        form = ArtikkelForm()
        context = {
        'form': form
        }

    return render(request, 'index.html', context)


from library.Window import Window
from library.WindowsGroupLinker import WindowsGroupLinker
from library.RepeatsHandler import RepeatsHandler
from library.MeanStockPriceLineplot import MeanStockPriceLinePlot
from library.StockPriceChart import StockPriceChart
import pandas as pd
import sqlite3
from library.StockPriceDataFrame import StockPriceDataFrame
from library.Plot import Plot
import os
import click

@click.command()
@click.option('--d1')
@click.option('--t1')
@click.option('--t1_time_col')
@click.option('--t1_class_col')
@click.option('--d2')
@click.option('--t2')
@click.option('--t2_time_col', default='Timestamp')
@click.option('--t2_open_col', default='Open')
@click.option('--t2_high_col', default='High')
@click.option('--t2_low_col', default='Low')
@click.option('--t2_close_col', default='Close')
@click.option('--candles', default=20)
@click.option('--timestamp_period', default=30*60)
@click.option('--save')
def run_script(d1, t1, t1_time_col, t1_class_col,
                d2, t2, t2_time_col, t2_open_col,
                t2_high_col, t2_low_col, t2_close_col,
                candles, timestamp_period, save):

    db1_connection = sqlite3.connect(d1)
    groups_info = pd.read_sql_query(f"SELECT * FROM {t1}", db1_connection, parse_dates=True)
    groups_info = groups_info.rename({t1_time_col: 'timestamp', t1_class_col: 'class'}, axis=1)
    index = pd.to_datetime(groups_info.timestamp, unit='s')
    groups_info = groups_info.drop('timestamp', axis=1)
    groups_info.index = index
    db1_connection.close()

    db2_connection = sqlite3.connect(d2)
    price_data = pd.read_sql_query(f'SELECT {t2_time_col}, {t2_open_col}, {t2_high_col}, {t2_low_col}, {t2_close_col} FROM {t2}', db2_connection, parse_dates=True)
    price_data = StockPriceDataFrame(price_data).get_content()
    db2_connection.close()

    repeats_handler = RepeatsHandler(timestamps_period=timestamp_period)
    cleaned_groups_info = repeats_handler.clear_repeats(groups_info)

    windows = [Window(price_data, timestamp, candles_number=candles) for timestamp in cleaned_groups_info.index]
    windows_group_linker = WindowsGroupLinker(cleaned_groups_info, windows)
    linked_windows_groups = windows_group_linker.get_content()

    save_plots(linked_windows_groups, StockPriceChart(), save)

def save_plots(data: dict, plot: Plot, path):

    count = int()
    for pattern_class, windows in data.items():

        folder_name = path + 'charts\\class_' + str(pattern_class)
        if not os.path.exists(folder_name):
            os.makedirs(folder_name)

        for window in windows:

            first_timestamp = str(int(window.index[0].timestamp()))
            file_path = folder_name + '\\chart_' + first_timestamp + '.png'

            window_plot = plot.set_data(window)
            window_plot.save_plot(file_path)

            count += 1
            print_count_info(pattern_class, count, len(windows))

def print_count_info(pattern_class, count, number_windows):
    print(f"class: {pattern_class}\tcount: {count}/{number_windows}")

if __name__ == '__main__':

    run_script()


from bokeh.plotting import figure, output_file, show
from bokeh.models import ColumnDataSource, TapTool, OpenURL
from bokeh.models.tools import HoverTool
from bokeh.tile_providers import get_provider, Vendors
import pandas as pd
import piexif
from pyproj import Transformer

# Own modules:
from scripts.tagging_functions import GeotaggingFunctions, Logging

class PlotImages:

    def __init__(self, settings):
        pd.set_option('display.max_columns', None)  # show all columns for pandas
        self.input_location = settings.input_location
        # Initialize logging
        self.logger = Logging('Plot_Images', 'DEBUG')
        self.gf = GeotaggingFunctions(self.logger)
        # Setup coordinate conversion parameters:
        self.transformer = Transformer.from_crs("EPSG:4326", "EPSG:3857", always_xy=True)

    def apply(self):
        df = self.exif_coordinates_to_dataframe(self.input_location)
        df = self.add_3857_to_df(df)
        self.create_bokeh_plot(df)

    def exif_coordinates_to_dataframe(self, input_location):
        """
        This function takes all the images in the input location and extracts the exif data from them.
        It retrieves the datetime the image was taken and the latitude and longitude where the image were taken.
        It then creates a pandas dataframe with the filename, datetime, latitude, longitude and it returns this
        dataframe.

        :param input_location: the directory containing the images to extract the exif data from.
        :return: a pandas dataframe containing: path, filename, datetime, latitude, longitude
        """
        image_list = self.gf.retrieve_image_filelist(input_location)
        paths, filenames, dates, lats, lons = [], [], [], [], []
        for file in image_list:
            exif_dict = piexif.load(file)
            # Extract the datetime from the exif data, transform byte to string and create a datetime object from it:
            img_datetime = self.gf.string_to_datetime(
                self.gf.decode_byte_object(exif_dict["0th"][piexif.ImageIFD.DateTime]))
            latitude, longitude = self.gf.dms_to_decimal_degrees((exif_dict["GPS"][piexif.GPSIFD.GPSLatitude],
                                                                  exif_dict["GPS"][piexif.GPSIFD.GPSLongitude]))
            dates.append(img_datetime)
            lats.append(latitude)
            lons.append(longitude)
            filenames.append(file.split('/')[-1])
            paths.append(file)
        df = pd.DataFrame()
        df['path'] = paths
        df['filename'] = filenames
        df['datetime'] = dates
        df['latitude'] = lats
        df['longitude'] = lons

        return df

    def add_3857_to_df(self, df):
        """
        This function adds a epsg:3857 column to the dataframe for both the latitude and longitude.

        :param df: pandas dataframe as generated by exif_coordinates_to_dataframe().
        :return: dataframe with epsg:3857 coordinates added.
        """
        lat3857, lon3857 = [], []
        for index, row in df.iterrows():
            lat, lon = self.convert_wgs84_to_3857(row['latitude'], row['longitude'])
            lat3857.append(lat)
            lon3857.append(lon)
        df['latitude3857'] = lat3857
        df['longitude3857'] = lon3857
        return df

    def convert_wgs84_to_3857(self, latitude, longitude):
        """
        This function transforms a epsg:4326 (WGS84) to a epsg:3857 coordinate.
        :param latitude: the latitude in 4326
        :param longitude: the longitude in 4326
        :return: latitude, longitude in 3857
        """
        return self.transformer.transform(longitude, latitude)

    @staticmethod
    def create_bokeh_plot(df):
        """
        This function creates a bokeh plot which shows where images were taken. It adds a link to the image path so that
        if the location is clicked, the image is shown. The generated html bokeh plot is saved in the same directory
        as the images.

        :param df: A pandas dataframe containing the columns:
         path, filename, datetime, latitude, longitude, latitude3857, longitude3857
        """
        # Extract the image directory by selecting the first image in the dataframe and taking the path from that:
        image_path = df['path'].iloc[0]
        output_path = '/'.join(image_path.split('/')[:-1]) + '/output.html'
        output_file(output_path)

        # Create a data source of the type ColumnDataSource:
        source = ColumnDataSource(df)

        # Get map tile provider (in EPSG:3857):
        tile_provider = get_provider(Vendors.CARTODBPOSITRON)

        # range bounds supplied in web mercator coordinates
        p = figure(x_axis_type="mercator", y_axis_type="mercator", plot_width=1200, plot_height=960,
                   tools=['pan', 'tap',
                          'wheel_zoom',
                          'save', 'reset'])
        p.title.text = 'Images taken this time'
        p.xaxis.axis_label = 'Longitude'
        p.yaxis.axis_label = 'Latitude'
        p.add_tile(tile_provider)
        # Add species data (points)
        p.circle(x="latitude3857", y="longitude3857", size=5, fill_color="green", fill_alpha=0.8, source=source)
        # Add a hovertool:
        hover = HoverTool()
        hover.tooltips = [
            ('Filename', '@filename'),
            ('Date and time taken', '@datetime'),
            ('Latitude (WGS84)', '@latitude'),
            ('Longitude (WGS84)', '@longitude')
        ]
        p.add_tools(hover)

        url = "@path"
        taptool = p.select(type=TapTool)
        taptool.callback = OpenURL(url=url)

        show(p)


from sympy import symbols, diff, pprint, factorial, ln, exp, sin, cos, log, sqrt, sympify
import numpy as np
from decimal import Decimal

def secante_method(x0, x1, tol,niter, f, f_string):
    message = ""
    x0 = float(x0)
    x1 = float(x1)
    tol = float(tol)
    niter = int(niter)

    if x0 >= x1:
        message += "--- x0 >= x1 wrong interval"
        data = {}
        return message, data

    if x0 < 0 or x1 < 0 or tol < 0 or niter < 0:
        message += "--- Please check your values, something is wrong"
        data ={}
        return message, data

    #x = symbols('x', real=True)
    x = x0
    y0 = eval(f_string)
    x = x1
    y1 = eval(f_string)
    #y0 = sympify(f).subs(x, x0)
    #y1 = sympify(f).subs(x, x1)
    #y0 = f(x0)
    #y1 = f(x1)
    cont = 0
    err=0
    print("\n-------------------------------------------------------")
    print("iteracion | xcentro | fxcentro |error abs")
    print(cont, "|", x0,"|",y1,"|",err)
    err_round = '%.2E' % Decimal(str(err))
    data = {'iter': [cont], 'xcentro': [round(x0,4)], 'fxcentro': [round(y1,4)], 'err': [err_round]}
    while abs(y1) > tol and cont < niter:
        try:
            denominator = float(y1 - y0)/(x1 - x0)
            x = x1 - float(y1)/denominator
        except ZeroDivisionError:
            message += "Error! - denominator zero for x = %s" % (str(x))
            print ("Error! - denominator zero for x = ", x)
            return message, data

        err = abs(x1-x0)
        x0 = x1
        x1 = x
        y0 = y1
        x = symbols('x', real=True)
        y1 = sympify(f).subs(x, x1)
        #y1 = f(x1)
        cont += 1
        print(cont, "|", x0,"|",y0,"|",err)
        data["iter"].append(cont)
        data["xcentro"].append(round(x0,4))
        data["fxcentro"].append(round(y1,4))
        err_round = '%.2E' % Decimal(str(err))
        data["err"].append(err_round)
    if abs(y1) > tol:
        cont = -1

    return message, data

def f(x):
    return exp(-x+1) - x**2 + 4*x

#x0 = 1
#x1 = 2
#niter=11
#tol=0.0005
#secant(f, x0, x1, tol, niter)


#!/usr/bin/env python
# -*- coding: utf-8 -*-

from escpos.serial import SerialSettings
from escpos.impl.epson import TMT20
from satextrato import ExtratoCFeVenda, ExtratoCFeCancelamento

# Imprime um cupom de venda na impressora não fiscal
def imprimir_cupom_venda():
    # mini-impressora Epson TM-T20 conectada à porta serial COM1
    conn = SerialSettings.as_from('COM1:9600,8,1,N').get_connection()
    impressora = TMT20(conn)
    impressora.init()

    # abre o arquivo do CF-e e emite o extrato
    with open(r'C:\CFe545090.xml', 'r') as fp:
        extrato = ExtratoCFeVenda(fp, impressora)
        extrato.imprimir()

# Imprime um cupom de cancelamento na impressora não fiscal
def imprimir_cupom_cancelamento():
    # mini-impressora Epson TM-T20 conectada à porta serial COM1
    conn = SerialSettings.as_from('COM1:9600,8,1,N').get_connection()
    impressora = TMT20(conn)
    impressora.init()

    with open('CFe_1.xml', 'r') as fvenda, open('CFeCanc_1.xml', 'r') as fcanc:
        extrato = ExtratoCFeCancelamento(fvenda, fcanc, impressora)
        extrato.imprimir()


#Import Django related functions
from django.shortcuts import render, get_object_or_404, redirect
from django.http import HttpResponseRedirect, FileResponse, HttpResponse, Http404
from django.urls import reverse
from django.utils.text import slugify
from django.utils.datastructures import MultiValueDictKeyError
from django.core.files.storage import FileSystemStorage
from django.conf import settings
from django.utils import timezone
from django.db.models import Q
from django.core.exceptions import ValidationError

#Import seperate background_tasks, allows for processing to be done in background
#and not risk a timeout requesting a page while processing.
from background_task import background
from background_task.models import Task
from background_task.models import CompletedTask

#Import my model and forms
from .models import Job_Submission, Example_Data
from .forms import FireFlySettings_Form, SEDform, SEDfileform, Emissionlines_Form, ASCCI_additional_inputs

#Import firefly
from core_firefly import firefly_class
from core_firefly import create_fits_table
from core_firefly.firefly_wrapper import firefly_run
from core_firefly.emission_lines import emissionline_choices

import numpy as np
import random
import time
import os
import warnings
from io import BytesIO
import base64
import matplotlib.pyplot as plt
import matplotlib as mpl
import matplotlib.gridspec as gridspec
from astropy.io import fits
import sys, traceback
import astropy.cosmology as co
from multiprocessing import Process

time_in_database = 60*60
clean_db = True

#Automatically delete job from databse after certain amount of time.
@background(name = 'clean_db', schedule=time_in_database, queue = 'my-queue')
def clean_database(job_id):

	try:
		job_submission = Job_Submission.objects.get(job_id = job_id)
		job_id = job_submission.job_id
		job_submission.delete()
		print("deleted", job_id)
	except:
		print("Failed to delete", job_id)

def home(request):

	#Post method shows submitting form data
	if request.method == 'POST':
		print(request.POST)

		#Get the form submitted and check it's valid for use
		emissionlines_form  = Emissionlines_Form(request.POST)
		settings_form       = FireFlySettings_Form(request.POST)
		sedfile_form        = SEDfileform(request.POST, request.FILES)
		additional_inputs   =  ASCCI_additional_inputs(request.POST)

		#If the forms are valid, process the data
		if settings_form.is_valid() and sedfile_form.is_valid() and additional_inputs.is_valid() and emissionlines_form.is_valid():

			#Get the users input_files
			userfile_list = request.FILES.getlist('input_file')
			file_list     = []

			#check_file_extension test, make sure all files are .fits or its a single .ascii file
			try:
				filetype = create_fits_table.check_file_extensions(userfile_list)
			except Exception as e:
				file_error = str(e)
				return render(request,
							  'firefly/home.html',
							  {'form':settings_form,
							   'SED':sedfile_form,
							   'emissionlines_form' : emissionlines_form,
							   'ascii_additional_inputs': additional_inputs,
							   'file_error': file_error})

			#Use the date and time to make unique job_id via scrambling the digits.
			time_stamp = time.strftime("%Y%m%d%H%M%S")
			job_id = int(''.join(random.sample(time_stamp,len(time_stamp))))

			input_file_path = os.path.join(settings.MEDIA_ROOT, "job_submissions", str(job_id))
			os.mkdir(input_file_path)

			file_error = None

			#What to do with a list of fits files. Further tests to make sure in correct format and then
			#combine them into a single file.
			if filetype == ".fits":

				#Loop through the list of files
				for file in userfile_list:

					#Make sure the files are unique by assigning them a unique number
					temp_fitsname = file.name[0:-5] + ".fits"
					temp_fitspath = os.path.join(settings.MEDIA_ROOT, "job_submissions", str(job_id), temp_fitsname)

					#Save the files to disk as library cannot read .fits files from memory
					with open(temp_fitspath, 'wb+') as file_destination:
						for chunk in file.chunks():
							file_destination.write(chunk)

					file_list.append(temp_fitspath)

				#Create a filename for that contains the combined data of all the files for Firefly
				#input_file = os.path.join(settings.INPUT_FILES, "input_" + str(job_id) + ".fits")

				input_file = os.path.join(input_file_path, "input_" + str(job_id) + ".fits")

				try:
					#Combine the data and write to the input_file
					create_fits_table.create_fitstable(input_files = file_list, output_file= input_file)

				#Catch any exceptions if files aren't comptabile.
				except Exception as e:
					file_error = str(e)
					print(str(e))

				#Remove the temp files as no longer needed as combined the data to one file
				finally:
					for file in file_list:
						os.remove(file)

			#What to do with a single ascii file
			elif filetype == ".ascii":

				#Try to load the data in to test if useable.
				try:
					np.loadtxt(userfile_list[0])

					#Add a unique id to the filename
					sed_file_name = userfile_list[0].name[0:-6] + "_" +str(job_id) + ".ascii"
					input_file = os.path.join(input_file_path, sed_file_name)

					#Save the file to disk
					with open(input_file, 'wb+') as file_destination:
						for chunk in userfile_list[0].chunks():
							file_destination.write(chunk)

					file_list.append(input_file)

				#Catch exceptions of a bad .ascii file
				except Exception as e:

					print(str(e))
					file_error = "'" + userfile_list[0].name + "' file is corrupt."

			#If an error occured, display it back to the user.
			if file_error:

				os.rmdir(input_file_path)

				return render(request,
							  'firefly/home.html',
							  {'form':settings_form,
							   'SED':sedfile_form,
							   'emissionlines_form' : emissionlines_form,
							   'ascii_additional_inputs': additional_inputs,
							   'file_error': file_error})

			#Read the number of spectra to be processed
			try:
				with fits.open(input_file) as hdulist:
					n_spectra = len(hdulist[1].data["spectra"])
			except:
				n_spectra = 1

			#Get the variables from the form.
			"""
			ageMin, ageMax, ZMin, ZMax, flux_units = settings_form.check_values(ageMin     = request.POST['ageMin'],
																				ageMax     = float(request.POST['ageMax']),
																				ZMin       = request.POST['ZMin'],
																				ZMax       = request.POST['ZMax'],
																				flux_units = request.POST['flux_units'])
			"""
			ageMin			 = float(request.POST['ageMin'])
			ageMax           = request.POST['ageMax']
			if ageMax == '':
				ageMax = None
			else:
				ageMax = float(ageMax)

			ZMin             = float(request.POST['ZMin'])
			ZMax             = float(request.POST['ZMax'])
			flux_units       = float(request.POST['flux_units'])
			#error            = float(request.POST['error'])
			models_key       = request.POST['model_key']
			model_libs       = request.POST['model_libs']
			imfs             = request.POST['imfs']
			wave_medium      = request.POST['wave_medium']
			try:
				request.POST['downgrade_models']
				downgrade_models = True
			except MultiValueDictKeyError:
				downgrade_models = False

			emissionlines = []
			emission_lines_str = ""

			#Loop through which emission lines were selected by user
			"""
			for i in range(emissionlines_form.max_emissionlines):
				if request.POST['Emission_line_' + str(i +1)] != '':

					#Make the emission lines also into a string
					emissionlines.append(request.POST['Emission_line_' + str(i +1)])
					if i == 0:
						comma = ''
					else:
						comma = ', '

					emission_lines_str = emission_lines_str + comma + request.POST['Emission_line_' + str(i +1)]
			"""
			for i in range(len(emissionline_choices)):

				if request.POST.get(emissionline_choices[i][0]):

					emissionlines.append(emissionline_choices[i][0])

					if i == 0:
						comma = ''
					else:
						comma = ', '

					emission_lines_str = emission_lines_str + comma + emissionline_choices[i][0]

			N_angstrom_masked = float(request.POST['N_angstrom_masked'])

			#ascii inputs
			try:
				redshift     = float(request.POST['redshift'])
				ra           = float(request.POST['ra'])
				dec          = float(request.POST['dec'])
				vdisp        = float(request.POST['vdisp'])
				r_instrument = float(request.POST['r_instrument'])
			except(ValueError):
				redshift = ra = dec = vdisp = r_instrument = None

			#Model libs as a string for user
			#if model_libs == "MILES":
			temp_model_libs = models_key + " - " + model_libs
			#else:
			#temp_model_libs = model_libs

			if ageMax == None:
				ageMax_storage = "Default"
			else:
				ageMax_storage = str(ageMax)

			#Create Job_Submission instance to save to database
			job_submission = Job_Submission.objects.create(job_id     = job_id,
														   status     = 'queued',
														   input_file = os.path.relpath(input_file, settings.MEDIA_ROOT),
														   n_spectra  = n_spectra,
														   ageMin     = ageMin,
														   ageMax     = ageMax_storage,
														   Zmin       = ZMin,
														   Zmax       = ZMax,
														   flux_units = flux_units,
														   imf        = imfs,
														   model      = temp_model_libs,
														   wave_medium = wave_medium,
														   downgrade_models = downgrade_models,
														   width_masking = N_angstrom_masked,
														   emission_lines = emission_lines_str)
			if imfs == "Kroupa":
				imfs = "kr"
			elif imfs == "Salpeter":
				imfs = "ss"
			elif imfs == "Chabrier":
				imfs = "cha"
			#Check if imf is a float
			elif imfs.replace('.','',1).isdigit():
				imfs = float(imfs)

			if model_libs == "Theoretical":
				model_libs = "Th"
			elif model_libs == "Empirical":
				model_libs = "E"

			output_name = request.POST.get('output_name')
			if request.POST.get('output_name') == '':
				output_name = "output_" + str(job_id) + ".fits"
			else:
				output_name = output_name + ".fits"

			#Run the background task of firefly
			firefly_run(input_file        = input_file,
						output_name       = output_name,
						job_id            = job_id,
						#Model inputs
						ageMin            = ageMin,
						ageMax			  = ageMax,
						ZMin              = ZMin,
						ZMax              = ZMax,
						flux_units        = flux_units,
						error             = 0,
						models_key        = models_key,
						model_libs        = model_libs,
						imfs              = imfs,
						wave_medium       = wave_medium,
						downgrade_models  = downgrade_models,
						emissionline_list = emissionlines,
						N_angstrom_masked = N_angstrom_masked,
						#Additional ascii file inputs
						redshift          = redshift,
						ra                = ra,
						dec               = dec,
						vdisp             = vdisp,
						r_instrument      = r_instrument)

			#Use HttpResponseRedirect when submitting forms to stop resubmitting
			#Display a processing page
			return HttpResponseRedirect(reverse('firefly:processed', args=(job_id,)))

		#Otherwise redirect back to form page with the forms that were used, display errors to user
		else:
			return render(request,
						 'firefly/home.html',
						 {'form':settings_form,
						 'SED':sedfile_form,
						 'emissionlines_form' : emissionlines_form,
						 'ascii_additional_inputs': additional_inputs})

	#Create a new form instance if first time visiting site
	emissionlines_form = Emissionlines_Form()
	settings_form      = FireFlySettings_Form()
	sedfile_form       = SEDfileform()
	additional_inputs  = ASCCI_additional_inputs()

	#Dispaly a new form to user if first time on site.
	return render(request,
				 'firefly/home.html',
				 {'form': settings_form,
				 'SED'  : sedfile_form,
				 'emissionlines_form' : emissionlines_form,
				 'ascii_additional_inputs': additional_inputs})

import math

def processed(request, job_id):

	mpl.use('Agg')

	#Find the the id in databse, if it can't then catch exception and
	#redirect user to page saying the id they want doesn't exist.
	if Job_Submission.objects.filter(job_id = job_id):

		#Checks if output_file exists, if it does display the results
		job_submission = Job_Submission.objects.get(job_id = job_id)

		if job_submission.status == "failed":
			return render(request, 'firefly/error.html', {'job_id': job_id})

		plot_size = (6.5, 5)

		if job_submission.output_file.name and job_submission.status == "complete":

			graphic_array      = []
			metallicity_array  = []
			stellar_mass_array = []
			age_array          = []
			light_array        = []
			converged_array    = []

			with fits.open(job_submission.output_file.path) as hdul:

				n_spectra = len(hdul[1].data['wavelength'])

				#imf_array          = []
				#model_array        = []
				for i in range(n_spectra):

					fig    = plt.figure(figsize = plot_size)
					buffer = BytesIO()

					wavelength  = np.array(hdul[1].data['wavelength'][i])
					flux        = np.array(hdul[1].data['original_data'][i])
					model       = np.array(hdul[1].data['firefly_model'][i])
					spectra     = np.array(hdul[1].data['spectra'][i])
					converged   = str(hdul[1].data['converged'][i])
					#imf         = hdul[1].data['IMF'][i]
					#model_used  = hdul[1].data['Model'][i]

					#imf_array.append(imf)
					#model_array.append(model_used)

					if converged == 'False':
						converged = False
					elif converged == 'True':
						converged = True

					converged_array.append(converged)

					if converged:

						csp_age   = np.ndarray(int(hdul[1].data['ssp_number'][i]))
						csp_Z     = np.ndarray(int(hdul[1].data['ssp_number'][i]))
						csp_light = np.ndarray(int(hdul[1].data['ssp_number'][i]))
						csp_mass  = np.ndarray(int(hdul[1].data['ssp_number'][i]))

						age         = str(np.around(10**hdul[1].data['age_lightW'][i],decimals=2))
						metallicity = str(np.around(hdul[1].data['metallicity_lightW'][i],decimals=2))
						mass        = str(10**hdul[1].data['stellar_mass'][i])
						mass        = '{0:.2e}'.format(float(mass))

						light       = str(np.around(hdul[1].data['EBV'][i],decimals=2))

						for n in range(len(csp_age)):
							csp_age[n]   = float(hdul[1].data['log_age_ssp_' + str(n)][i])
							csp_Z[n]     = float(hdul[1].data['metal_ssp_' + str(n)][i])
							csp_light[n] = float(hdul[1].data['weightLight_ssp_' + str(n)][i])
							csp_mass[n]  = float(hdul[1].data['weightMass_ssp_' + str(n)][i])
					else:
						age         = None
						metallicity = None
						mass        = None
						light       = None

					age_array.append(age)
					metallicity_array.append(metallicity)

					#if mass != None:
					#	stellar_mass_array.append(np.around(10**(float(mass)), decimals = 2))
					#else:
					stellar_mass_array.append(mass)

					light_array.append(light)

					gridspec.GridSpec(2,2)
					gridsize = (2,2)

					#Mainplot
					plt.subplot2grid(gridsize, (0,0), colspan = 2, rowspan = 1)
					plt.xlabel('Wavelength (Å)')
					plt.ylabel('Flux')
					plt.ticklabel_format(style='sci', axis='y', scilimits=(0,0))
					plt.plot(wavelength, flux, label = 'Original data')
					if converged:
						plt.plot(wavelength, model, label = 'Fitted data')
					plt.title(spectra)
					plt.xlim(left = wavelength[0], right = wavelength[-1])
					plt.ylim(bottom = 0)
					plt.legend()
					plt.grid()

					if converged == True:
						#Small subplot 1
						plt.subplot2grid(gridsize, (1,0))
						plt.bar(10**(csp_age),
								csp_light,
								width=0.3,
								align='center',
								alpha=0.5)
						plt.xlabel('Age')
						plt.ylabel('frequency/Gyr')
						#plt.title()

						#Small subplot 2
						plt.subplot2grid(gridsize, (1,1))
						plt.bar(csp_Z,
								csp_light,
								width=0.1,
								align='center',
								alpha=0.5)
						plt.xlabel('Z')
						plt.ylabel('frequency/Gyr')
						#plt.title()

					fig.tight_layout()

					plt.savefig(buffer, format='png')
					buffer.seek(0)
					image_png = buffer.getvalue()
					buffer.close()
					plt.close()

					graphic = base64.b64encode(image_png)
					graphic = graphic.decode('utf-8')

					graphic_array.append(graphic)

			return render(request,
						  'firefly/processed.html',
						 {'job_id':           job_id,
						  'plot':             graphic_array,
						  'converged':        converged_array,
						  'model':            job_submission.model,
						  'imf':              job_submission.imf,
						  'ageMin':           job_submission.ageMin,
						  'ageMax':           job_submission.ageMax,
						  'Zmin'  :           job_submission.Zmin,
						  'Zmax'  :           job_submission.Zmax,
						  'flux_units':       job_submission.flux_units,
						  'wave_medium':      job_submission.wave_medium,
						  'downgrade_models': job_submission.downgrade_models,
						  'width_masking':    job_submission.width_masking,
						  'emission_lines':   job_submission.emission_lines,
						  'age':              age_array,
						  'metallicity':      metallicity_array,
						  'mass':             stellar_mass_array,
						  'light':            light_array})

		#If it doesn't, display a loading page
		else:
			file_extension = os.path.splitext(job_submission.input_file.name)[1]

			if file_extension == ".ascii":
				data = np.loadtxt(job_submission.input_file.path, unpack=True)
				lamb = data[0,:]

				wavelength = data[0,:]
				flux       = data[1,:]
				spectra    = os.path.basename(job_submission.input_file.name)
				n_spectra  = 1
			else:

				#with fits.open(job_submission.input_file.path) as hdul:
				hdul = fits.open(job_submission.input_file.path)

				try:
					n_spectra        = len(hdul[1].data['flux'])
					flux_array       = np.array(hdul[1].data['flux'])
					wavelength_array = np.array(10**hdul[1].data['loglam'])
					spectra_array    = np.array(hdul[1].data['spectra'])
					fits_table       = True

				except:
					n_spectra        = 1
					flux_array       = np.array(hdul[1].data['flux'])
					wavelength_array = np.array(10**hdul[1].data['loglam'])
					spectra_array    = job_submission.input_file.name

					fits_table = False

				finally:
					hdul.close()

				#os.remove(job_submission.input_file.path)
				#job_submission.delete()

			graphic_array = []
			for i in range(n_spectra):

				buffer = BytesIO()

				fig = plt.figure(figsize = plot_size)

				if file_extension == ".fits":

					if fits_table:
						left  = wavelength_array[i][0]
						right = wavelength_array[i][-1]
						wavelength = wavelength_array[i]
						flux = flux_array[i]
						spectra = spectra_array[i]
					else:
						left  = wavelength_array[0]
						right = wavelength_array[-1]
						wavelength = wavelength_array
						flux = flux_array
						spectra = spectra_array
				else:
					left  = wavelength[0]
					right = wavelength[-1]

				gridspec.GridSpec(2,2)
				gridsize = (2,2)

				#Mainplot
				plt.subplot2grid(gridsize, (0,0), colspan = 2, rowspan = 1)
				plt.xlabel('Wavelength (Å)')

				plt.plot(wavelength, flux, label = 'Original data')
				plt.title(spectra)

				plt.xlim(left = left, right = right)
				plt.legend()
				plt.grid()
				plt.xlabel('Wavelength (Å)')
				plt.ylabel('Flux')
				plt.tight_layout()

				plt.savefig(buffer, format='png')
				buffer.seek(0)
				image_png = buffer.getvalue()
				buffer.close()
				plt.close()

				graphic = base64.b64encode(image_png)
				graphic = graphic.decode('utf-8')
				graphic_array.append(graphic)

			#Find where the user is in the queue
			running_tasks_qs = Task.objects.filter(task_name = 'firefly')

			found = False
			queue = 0

			for running_task in running_tasks_qs:

				if running_task.task_params.find(str(job_id)) != -1:
					found = True
					break

				queue = queue + 1

			if queue == 0 and found:
				queue = 'You are next - processing your data!'

			try:
				status = int(job_submission.status)
			except(ValueError):
				status = 0

			return render(request,
						  'firefly/processing.html',
						  {'job_id':          job_id,
						  'plot'   :          graphic_array,
						  'model':            job_submission.model,
						  'imf':              job_submission.imf,
						  'ageMin':           job_submission.ageMin,
						  'ageMax':           job_submission.ageMax,
						  'Zmin'  :           job_submission.Zmin,
						  'Zmax'  :           job_submission.Zmax,
						  'flux_units':       job_submission.flux_units,
						  'wave_medium':      job_submission.wave_medium,
						  'downgrade_models': job_submission.downgrade_models,
						  'width_masking':    job_submission.width_masking,
						  'emission_lines':   job_submission.emission_lines,
						  'queue'  :          queue,
						  'status' :          status})
	else:
		return render(request, 'firefly/not_found.html', {'job_id': job_id})

#Allow user to download file
def download(request, location, job_id):

	if location == 'results':
		data = Job_Submission.objects.get(job_id = job_id)
		file_path = data.output_file.path

	elif location == 'example':
		data = Example_Data.objects.get(example_id = job_id)
		file_path = data.input_file.path

	if os.path.exists(file_path):
		with open(file_path, 'rb') as fh:
			response = HttpResponse(fh.read(), content_type="application/vnd.ms-excel")
			response['Content-Disposition'] = 'inline; filename=' + os.path.basename(file_path)
			return response
	raise Http404

"""
running_tasks_qs = Task.objects.filter()
completed_tasks_qs = CompletedTask.objects.all()

found = False
#Check if task with job_id is running
for running_task in running_tasks_qs:

	if running_task.task_params.find(str(job_id)) != -1:
		found = True
		print("running job_id", job_id)
		break

#If it can't find it, check completed tasks
error = False
if found == False:
	for completed_task in completed_tasks_qs:
		if completed_task.task_params.find(str(job_id)) != -1:
			error = True
			print("found error for job_id", bool(completed_task.last_error))
			break
"""

def fits_format(request):

	examples = Example_Data.objects.all()

	example_list = []

	for i in range(len(examples)):
		example_list.append(examples[i])

	#[Example_Data.objects.all()[0], Example_Data.objects.all()[1], Example_Data.objects.all()[2]]

	return render(request, 'firefly/fits_format.html', {'example_data': example_list})


# -*- coding: utf-8 -*-
"""
Created on Sat Jan 21 19:21:45 2017

@author: Axle
"""

from initialisations import *

def denoise():
    astro = img_as_float(data.astronaut())
    astro = astro[30:180, 150:300]

    noisy = astro + 0.3 * np.random.random(astro.shape)
    noisy = np.clip(noisy, 0, 1)

    denoise = denoise_nl_means(noisy, 7, 9, 0.08)

    fig, ax = plt.subplots(ncols=2, figsize=(8, 4), sharex=True, sharey=True, subplot_kw={'adjustable':'box-forced'})

    ax[0].imshow(noisy)
    ax[0].axis('off')
    ax[0].set_title('noisy')
    ax[1].imshow(denoise)
    ax[1].axis('off')
    ax[1].set_title('non-local means')

    fig.subplots_adjust(wspace=0.02, hspace=0.2,
                        top=0.9, bottom=0.05, left=0, right=1)

    plt.show()


import humanfriendly
import pytest

from cato_server.api.schemas.test_result_schemas import (
    CreateOutputSchema,
    StartTestResultSchema,
)

STRING_WITH_MAX_SIZE = "".join(["x" for x in range(humanfriendly.parse_size("10mb"))])

class TestCreateOutputSchema:
    def test_success(self):
        schema = CreateOutputSchema()

        errors = schema.validate({"testResultId": 1, "text": "This is a long text"})

        assert errors == {}

    def test_success_max_length_string(self):
        schema = CreateOutputSchema()

        errors = schema.validate({"testResultId": 1, "text": STRING_WITH_MAX_SIZE})

        assert errors == {}

    @pytest.mark.parametrize(
        "data,expected_errors",
        [
            (
                {},
                {
                    "testResultId": ["Missing data for required field."],
                    "text": ["Missing data for required field."],
                },
            ),
            (
                {"testResultId": "wurst", "text": "This is a long text"},
                {"testResultId": ["Not a valid integer."]},
            ),
            (
                {"testResultId": 1, "text": ["This is a long text"]},
                {"text": ["Not a valid string."]},
            ),
            (
                {"testResultId": 1, "text": STRING_WITH_MAX_SIZE + "x"},
                {"text": ["Longer than maximum length 10000000."]},
            ),
        ],
    )
    def test_failure(self, data, expected_errors):
        schema = CreateOutputSchema()

        errors = schema.validate(data)

        assert errors == expected_errors

class TestStartTestResultSchema:
    def test_success(self):
        schema = StartTestResultSchema()

        errors = schema.validate(
            {"id": 42, "machineInfo": {"cpuName": "Intel", "cores": 8, "memory": 24}}
        )

        assert errors == {}

    @pytest.mark.parametrize(
        "data,expected_errors",
        [
            (
                {},
                {
                    "id": ["Missing data for required field."],
                    "machineInfo": ["Missing data for required field."],
                },
            ),
            (
                {
                    "id": "w",
                    "machineInfo": {"cpuName": "Intel", "cores": 8, "memory": 24},
                },
                {"id": ["Not a valid integer."]},
            ),
            (
                {
                    "id": 42,
                    "machineInfo": {"cpu_wname": "Intel", "cores": 8, "memory": 24},
                },
                {"machineInfo": {"cpuName": ["Missing data for required field."]}},
            ),
            (
                {
                    "id": 42,
                    "machineInfo": {
                        "cpuName": "Intel",
                        "cores": "eight",
                        "memory": 24,
                    },
                },
                {"machineInfo": {"cores": ["Not a valid integer."]}},
            ),
            (
                {
                    "id": 42,
                    "machineInfo": {"cpuName": "Intel", "cores": -8, "memory": -24},
                },
                {
                    "machineInfo": {
                        "cores": ["Must be greater than or equal to 1."],
                        "memory": ["Must be greater than or equal to 0."],
                    }
                },
            ),
        ],
    )
    def test_failure(self, data, expected_errors):
        schema = StartTestResultSchema()

        errors = schema.validate(data)

        assert errors == expected_errors


import torch
import torch.nn as nn
import torch.nn.functional as F

class GRU_clf(nn.Module):
    def __init__(self, feat_dim, place_holder=None):
        super(GRU_clf, self).__init__()
        self.gru = nn.GRU(feat_dim, feat_dim // 2, batch_first=True, bidirectional=True)
        self.act = nn.LeakyReLU()
        self.clf_s = nn.Linear(feat_dim, 1)
        torch.nn.init.normal_(self.clf_s.weight, std=0.02)
        self.clf_e = nn.Linear(feat_dim, 1)
        torch.nn.init.normal_(self.clf_e.weight, std=0.02)

    def forward(self, feat):
        feat, (_, _) = self.gru(feat)
        feat = self.act(feat)
        # B x seq x feat_dim
        start = self.clf_s(feat)
        end = self.clf_e(feat)
        return torch.cat((start, end), dim = 2)

class LSTM_clf(nn.Module):
    def __init__(self, feat_dim, place_holder=None):
        super(LSTM_clf, self).__init__()
        self.lstm = nn.LSTM(feat_dim, feat_dim // 2, batch_first=True, bidirectional=True)
        self.act = nn.LeakyReLU()
        self.clf_s = nn.Linear(feat_dim, 1)
        torch.nn.init.normal_(self.clf_s.weight, std=0.02)
        self.clf_e = nn.Linear(feat_dim, 1)
        torch.nn.init.normal_(self.clf_e.weight, std=0.02)

    def forward(self, feat):
        feat, (_, _) = self.lstm(feat)
        feat = self.act(feat)
        # B x seq x feat_dim
        start = self.clf_s(feat)
        end = self.clf_e(feat)
        return torch.cat((start, end), dim = 2)

class CNN_clf(nn.Module):
    def __init__(self, feat_dim, place_holder=None):
        '''
        placeholder is not used, is to sync with nn.Linear
        '''
        super(CNN_clf, self).__init__()
        self.start = []
        self.start.append(nn.Conv1d(feat_dim, feat_dim // 2, kernel_size=2))
        self.start.append(nn.LeakyReLU())
        self.start = nn.Sequential(*self.start)
        self.start_clf = nn.Linear(feat_dim // 2, 1)
        torch.nn.init.normal_(self.start_clf.weight, std=0.02)

        self.end = []
        self.end.append(nn.Conv1d(feat_dim, feat_dim // 2, kernel_size=2))
        self.end.append(nn.LeakyReLU())
        self.end = nn.Sequential(*self.end)
        self.end_clf = nn.Linear(feat_dim // 2, 1)
        torch.nn.init.normal_(self.end_clf.weight, std=0.02)

    def forward(self, feat):
        # convert B x Seq x F ==> B x F x Seq
        feat = feat.permute(0, 2, 1)
        feat = F.pad(feat, (0, 1), 'constant', 0)
        start = self.start(feat)
        start = start.permute(0, 2, 1)
        start = self.start_clf(start)
        end = self.end(feat)
        end = end.permute(0, 2, 1)
        end = self.end_clf(end)

        return torch.cat((start, end), dim = 2)

def sentimented_embedding(model,
                          input_ids,
                          token_type_ids=None,
                          attention_mask=None,
                          position_ids=None,
                          head_mask=None):
    '''
    only applicable for QA mode under RoBERTa
    '''
    assert head_mask is None # does not support head mask now
    head_mask = [None] * model.config.num_hidden_layers

    if attention_mask is None:
        attention_mask = torch.ones_like(input_ids)
    if token_type_ids is None:
        token_type_ids = torch.zeros_like(input_ids)

    extended_attention_mask = attention_mask.unsqueeze(1).unsqueeze(2)
    extended_attention_mask = extended_attention_mask.to(dtype=next(model.parameters()).dtype)
    extended_attention_mask = (1.0 - extended_attention_mask) * -10000.0
    '''
    if head_mask is not None:
        if head_mask.dim() == 1:
            head_mask = head_mask.unsqueeze(0).unsqueeze(0).unsqueeze(-1).unsqueeze(-1)
            head_mask = head_mask.expand(self.config.num_hidden_layers, -1, -1, -1, -1)
        elif head_mask.dim() == 2:
            head_mask = head_mask.unsqueeze(1).unsqueeze(-1).unsqueeze(-1)  # We can specify head_mask for each layer
        head_mask = head_mask.to(dtype=next(self.parameters()).dtype) # switch to fload if need + fp16 compatibility
    else:
        head_mask = [None] * self.config.num_hidden_layers
    '''

    embedding_output = model.embeddings(input_ids, position_ids=position_ids, token_type_ids=token_type_ids)

    # add in sentiment, but note that this sentiment is being affected by position id (at least i think)
    for sample_idx in range(embedding_output.size(0)):
        end_pos = input_ids.size(1) - 1
        while end_pos > 0 and input_ids[sample_idx, end_pos].item() != 2: # 2 is the end tag for RoBERTa
            end_pos -= 1

        if end_pos < 5 or input_ids[sample_idx, end_pos-2].item() != 2:
            continue
        else:
            sent_embed = embedding_output[sample_idx, end_pos-1, :]
            embedding_output[sample_idx, :end_pos-3] += sent_embed

    encoder_outputs = model.encoder(embedding_output,
                                   extended_attention_mask,
                                   head_mask=head_mask)
    sequence_output = encoder_outputs[0]
    pooled_output = model.pooler(sequence_output)

    outputs = (sequence_output, pooled_output,) + encoder_outputs[1:]

    return outputs


# coding=utf-8
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Chrome(executable_path=r"C:\Users\10366\chromedriver.exe")
driver.get('https://www.baidu.com')
# 行为链,爬虫一般不用,测试时用的比较多
inputTag = driver.find_element_by_id('kw')
button = driver.find_element_by_id('su')

actions = ActionChains(driver)
actions.move_to_element(inputTag)
actions.send_keys_to_element(inputTag,'python')
actions.move_to_element(button)
actions.click(button)
actions.perform()


arabic_letters = ['أ', 'ة', 'إ', 'ؤ', 'آ', 'ا', 'ب', 'ت', 'ث', 'ج', 'ح', 'خ', 'د', 'ذ', 'ر', 'ز',
                  'س', 'ش', 'ص', 'ض', 'ط', 'ظ', 'ع', 'غ', 'ف', 'ق', 'ك', 'ل', 'م', 'ن', 'ه', 'و', 'ي', 'ئ', 'ئ', 'ء', 'ى']
arabic_diacs = ["َ", "ً", "ِ", "ٍ", "ُ", "ٌ", "ْ", "َّ", "ِّ", "ُّ", "ّ"]

def _filter_funtion(variable):
    return (variable not in arabic_diacs)

def _remove_diac(example, isDataset=True):
    if isDataset:
        example = example['text']

    example_arr = [char for char in example]
    final_arr = filter(_filter_funtion, example_arr)
    final_text = ''.join(final_arr)
    return {'text': final_text, 'diacritized': example}

def _create_mask_arr(sentence):
    masks_arr = []
    s_arr = [char for char in sentence]
    for i in range(1, len(s_arr)):
        if s_arr[i] in arabic_letters:
            masks_arr.append(''.join([*s_arr[0:i], '<mask>', *s_arr[i:]]))
    masks_arr.append(''.join([*s_arr, '<mask>']))
    return masks_arr

def _fill_mask_arr(fill_mask, arr):
    fills = []
    for i in arr:
        if fill_mask(i)[0]['token_str'] == ' ':
            fills.append(fill_mask(i)[1])
        else:
            fills.append(fill_mask(i)[0])
    return fills

def _create_seq_from_fills(fills):
    seq_of_diac = [i['token_str'] for i in fills]
    return seq_of_diac

def _fix_fills(diacritized_sentence, fill_mask):
    output_arr = [char for char in diacritized_sentence]
    o_mask_arr = []
    for i in range(len(output_arr)):
        if diacritized_sentence[i] in arabic_diacs:
            o_mask_arr.append(
                ''.join([*output_arr[0:i], '<mask>', *output_arr[i+1:]]))

    fills = []
    for i in o_mask_arr:
        if fill_mask(i)[0]['token_str'] == ' ':
            fills.append(fill_mask(i)[1])
            # fills.append({'token_str': ''})
        else:
            fills.append(fill_mask(i)[0])

    return fills

def _mix_letters_and_diacs(sentence, seq_of_diac):
    diac_iterator = 0
    output = ""

    for i in range(len(sentence)):
        if sentence[i] in arabic_letters:
            output += sentence[i]
            output += seq_of_diac[diac_iterator]
            diac_iterator += 1
        elif sentence[i] == ' ':
            output += " "

    return output

def diacritize(sentence, fill_mask, passes=1, isDataset=False):

    removed_diac_sentence = _remove_diac(sentence, isDataset)['text']
    mask_array = _create_mask_arr(removed_diac_sentence)
    fills = _fill_mask_arr(fill_mask, mask_array)
    seq_of_diac = _create_seq_from_fills(fills)
    output = _mix_letters_and_diacs(sentence, seq_of_diac)

    if passes > 1:
        for i in range(1, passes):
            fixed_fills = _fix_fills(output, fill_mask)
            seq_of_diac = _create_seq_from_fills(fixed_fills)
            output = _mix_letters_and_diacs(sentence, seq_of_diac)

    return output


"""
stanCode Breakout Project
Adapted from Eric Roberts's Breakout by
Sonja Johnson-Yu, Kylie Jue, Nick Bowman,
and Jerry Liao

YOUR DESCRIPTION HERE
"""
from campy.graphics.gwindow import GWindow
from campy.graphics.gimage import GImage
from campy.graphics.gobjects import GOval, GRect, GLabel
from campy.gui.events.mouse import onmouseclicked, onmousemoved
import random

BRICK_SPACING = 5      # Space between bricks (in pixels). This space is used for horizontal and vertical spacing.
BRICK_WIDTH = 40       # Width of a brick (in pixels).
BRICK_HEIGHT = 15      # Height of a brick (in pixels).
BRICK_ROWS = 10        # Number of rows of bricks.
BRICK_COLS = 10        # Number of columns of bricks.
BRICK_OFFSET = 50      # Vertical offset of the topmost brick from the window top (in pixels).
BALL_RADIUS = 10       # Radius of the ball (in pixels).
PADDLE_WIDTH = 75      # Width of the paddle (in pixels).
PADDLE_HEIGHT = 15     # Height of the paddle (in pixels).
PADDLE_OFFSET = 50     # Vertical offset of the paddle from the window bottom (in pixels).

INITIAL_Y_SPEED = 7.0  # Initial vertical speed for the ball.
MAX_X_SPEED = 5      # Maximum initial horizontal speed for the ball.
NUM_LIVES = 3       # Maximum chances for player to play

class BreakoutGraphics:

    def __init__(self, ball_radius=BALL_RADIUS, paddle_width=PADDLE_WIDTH,
                 paddle_height=PADDLE_HEIGHT, paddle_offset=PADDLE_OFFSET,
                 brick_rows=BRICK_ROWS, brick_cols=BRICK_COLS,
                 brick_width=BRICK_WIDTH, brick_height=BRICK_HEIGHT,
                 brick_offset=BRICK_OFFSET, brick_spacing=BRICK_SPACING,
                 title='Breakout'):
        # only three lives
        self.num_lives = NUM_LIVES
        # win img
        self.img = GImage('WIN!!.png')

        # Create a graphical window, with some extra space.
        window_width = brick_cols * (brick_width + brick_spacing) - brick_spacing
        window_height = brick_offset + 3 * (brick_rows * (brick_height + brick_spacing) - brick_spacing)
        self.window = GWindow(width=window_width, height=window_height, title=title)

        # Start button
        self.button_back = GRect(250, 50)
        self.button_back.filled = True
        self.button_back.fill_color = 'darkgrey'
        self.window.add(self.button_back, x=(self.window.width - self.button_back.width) // 2, y=352.5)

        self.button = GRect(250, 50)
        self.button.filled = True
        self.button.fill_color = 'grey'
        self.window.add(self.button, x=(self.window.width-self.button.width)//2, y=350)

        self.button_word = GLabel('CLICK TO START')
        self.button_word.font = '-30'
        self.window.add(self.button_word, x=(self.window.width-self.button_word.width)//2,
                        y=350+self.button_word.height+10)

        # Create a paddle.
        self.paddle = GRect(paddle_width, paddle_height, x=(window_width-paddle_width)//2, y=window_height-paddle_offset)
        self.paddle.filled = True
        self.window.add(self.paddle)

        # Center a filled ball in the graphical window.
        self.ball = GOval(ball_radius*2, ball_radius*2, x=window_width//2-ball_radius, y=window_height//2-ball_radius)
        self.ball.filled = True
        self.window.add(self.ball)

        # Default initial velocity for the ball.
        self.__dx = self.set_ball_x_velocity()
        self.__dy = INITIAL_Y_SPEED

        # Initialize our mouse listeners.
        onmouseclicked(self.start)
        onmousemoved(self.control_paddle)

        # the switch of the game
        self.start = False

        # Score board.
        self.score = 0
        self.score_label = GLabel('Score: ' + str(self.score))
        self.score_label.font = '-22'
        self.window.add(self.score_label, x=0, y=self.score_label.height+5)

        # how many lives
        self.life1 = GLabel('❤')
        self.life1.font = '-20'
        self.window.add(self.life1, self.window.width-self.life1.width, self.life1.height+7)

        self.life2 = GLabel('❤')
        self.life2.font = '-20'
        self.window.add(self.life2, self.window.width-self.life2.width*2, self.life2.height+7.35)

        self.life3 = GLabel('❤')
        self.life3.font = '-20'
        self.window.add(self.life3, self.window.width-self.life3.width*3, self.life3.height+7.35)

        # Draw bricks.
        x = 0
        # to change row
        space = 0
        self.change = 0
        self.color = 'red'
        # 5 colors
        for i in range(brick_rows//2):
            # each color 2 rows
            for j in range(2):
                # x bricks
                for k in range(brick_cols):
                    self.brick = GRect(brick_width, brick_height, x=0+x, y=brick_offset+space)
                    x += (brick_width+brick_spacing)
                    self.brick.filled = True
                    self.brick.fill_color = self.color
                    self.brick.color = self.color
                    self.window.add(self.brick)
                x = 0
                space += (brick_height + brick_spacing)
            self.change_color()

    def change_color(self):
        """
        a method for making different color of the bricks
        :return: color
        """
        self.change += 1
        if self.change == 1:
            self.color = 'orange'
        elif self.change == 2:
            self.color = 'yellow'
        elif self.change == 3:
            self.color = 'green'
        elif self.change == 4:
            self.color = 'blue'

    def control_paddle(self, m):
        """
        This method controls the paddle by moving your mouse inside the window.
        The midpoint of the paddle follows the mouse
        :param m: mouse event
        """
        if self.paddle.width//2 <= m.x <= self.window.width-self.paddle.width//2:
            self.paddle.x = m.x-self.paddle.width//2

    def start(self, m):
        """
        The switch of this game
        """
        self.window.remove(self.button)
        self.window.remove(self.button_back)
        self.window.remove(self.button_word)
        if self.num_lives > 0:
            self.start = True

    def set_ball_x_velocity(self):
        """
        This method gives random dx for the ball whenever the ball starts moving.
        """
        # ball start w/ different dx speed
        self.__dx = random.randint(1, MAX_X_SPEED)
        # ball start w/ different direction
        if random.random() > 0.5:
            self.__dx = -self.__dx
        return self.__dx

    # getter: ball dx
    def get_ball_x_velocity(self):
        return self.__dx

    # getter: ball dy
    def get_ball_y_velocity(self):
        return self.__dy

    def touch_thing(self):
        """
        This method checks whether the ball has touched something.
        No, keep moving
        Yes, return the thing to next place to check what is the thing
        """
        # object sensor: left up, right up, left down, right down
        obj1 = self.window.get_object_at(self.ball.x, self.ball.y)
        obj2 = self.window.get_object_at(self.ball.x+self.ball.width, self.ball.y)
        obj3 = self.window.get_object_at(self.ball.x, self.ball.y+self.ball.width)
        obj4 = self.window.get_object_at(self.ball.x+self.ball.width, self.ball.y+self.ball.width)

        # check whether ball touch object
        if obj1 is None:
            if obj2 is None:
                if obj3 is None:
                    if obj4 is None:
                        pass
                    else:
                        return obj4
                else:
                    return obj3
            else:
                return obj2
        else:
            return obj1

    def check_hit_wall(self):
        """
        This method checks whether the ball hits the top, left or right wall and changes
        its direction dx = -dx
        """
        if self.ball.x <= 0 or self.ball.x >= self.window.width-self.ball.width:
            self.__dx = -self.__dx
        if self.ball.y <= 0:
            self.__dy = -self.__dy

    def check_what_object(self):
        """
        This method checks what object did the ball hit
        """
        if self.touch_thing() is self.paddle:
            # avoid the situation: when the ball touches the edge of paddle, it will stuck in the paddle, up and down
            if self.__dy > 0:
                self.__dy = -self.__dy
            else:
                pass
        elif self.touch_thing() is self.score_label:
            pass
        elif self.touch_thing() is self.img:
            pass
        elif self.touch_thing() is not None:
            self.window.remove(self.touch_thing())
            self.score += 1
            self.score_label.text = 'Score: ' + str(self.score)
            self.__dy = -self.__dy
        elif self.touch_thing() is self.life1 or self.life2 or self.life3:
            pass

    # def bonus_ball(self):
    #     while self.ball.y < self.window.height//2:
    #         self.ball.fill_color = 'red'

    def win(self):
        """
        This method shows an image and label if the user wins the game by clearing
        all the bricks
        """
        if self.score == 100:
            win = GLabel('WIN!!')
            win.font = 'Times-50'
            self.window.add(win, 50, 235)
            self.window.add(self.img, 10, 25)
            self.window.remove(self.ball)

    def dead(self):
        """
        This method will check whether the ball falls below the window and will show a
        label 'Gameover' when there's no lives left.
        """
        if self.ball.y >= self.window.height:
            self.window.remove(self.ball)
            self.num_lives -= 1
            if self.num_lives > 0:
                self.reset_ball()
                # lives left
                if self.num_lives == 2:
                    self.window.remove(self.life3)
                elif self.num_lives == 1:
                    self.window.remove(self.life2)
            else:
                # last life
                if self.num_lives == 0:
                    self.window.remove(self.life1)
                lose = GLabel('GAMEOVER!!!')
                lose.font = 'Trattatello-60-italic'
                self.window.add(lose, x=(self.window.width-lose.width)//2, y=(self.window.height+lose.height)//2)

    def reset_ball(self):
        """
        This method resets the ball to the middle of the window and assign a new speed
        in order to reset the game.
        """
        self.ball = GOval(self.ball.width, self.ball.width, x=(self.window.width-self.ball.width)//2,
                          y=(self.window.height-self.ball.width)//2)
        self.ball.filled = True
        self.window.add(self.ball)
        self.start = False
        self.set_ball_x_velocity()


# Autohor: Tor K Gjerde - OASIS bachelor thesis -  May 2020.

import math
import matplotlib.pyplot as plt
from matplotlib.pyplot import ion, show

data_raw = open("TEST2_12_MAY.txt", "r")

data = data_raw.read()
data = data.split(',')  # create a list containing all the datapoints
nbr_of_samples = len(data)

# Number of samplepoints
N = nbr_of_samples
print(N)

# Convert string entries in data to float entries.
float_data = [0]*nbr_of_samples
for i in range(0,nbr_of_samples):
	float_data[i] = float(data[i])

sample_nbr = [0]*nbr_of_samples
for i in range(0, nbr_of_samples):
    sample_nbr[i] = i

plt.style.use('seaborn-whitegrid')
plt.plot(sample_nbr, data, color ='red', linewidth=1)
plt.title('Plotting of ADC voltage data')
plt.xlabel('Sample nbr.')
plt.ylabel('voltage difference between inputs')
plt.tight_layout()
plt.show()