import sys
sys.setrecursionlimit(500*500)

from math import gcd
from functools import reduce
# product('ABCD', repeat=2) => AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD
from itertools import product
# permutations('ABCD', 2) => AB AC AD BA BC BD CA CB CD DA DB DC
from itertools import permutations
# combinations('ABCD', 2) => AB AC AD BC BD CD
from itertools import combinations
from itertools import accumulate # 累積和作るやつ
from collections import deque
from collections import defaultdict
from heapq import heappop, heappush
from bisect import bisect_left
# 0埋めされた二進数表現
f'{9:05b}'

alpha2num = lambda c: ord(c) - ord('a')
num2alpha = lambda c: chr(c+97)
popcnt = lambda x: bin(x).count("1")

dh = [-1, 0, 1, 0]
dw = [0, -1, 0, 1]
dh8 = [-1, -1, -1,  0,  0,  1,  1,  1]
dw8 = [-1,  0,  1, -1,  1, -1,  0,  1]

def resolve():
  from collections import deque
  mod = 10**9+7
  N = int(input())

  # EDGES[n]: 頂点 n に繋がっている頂点
  EDGES = [[] for _ in range(N)]
  for _ in range(N-1):
    x, y = [int(x)-1 for x in input().split(" ")]
    EDGES[x].append(y)
    EDGES[y].append(x)

  # checked[n]: 頂点 n が既にチェックされているかどうか
  checked = [False]*N
  checked[0] = True

  # parents[n]: 頂点 n の親。根の親は -1 になる。
  parents = [-1]*N

  # dp[n][c] := 頂点 n が c 色のケースのパターン数
  dp = [[1, 1] for _ in range(N)]

  # DFS をやっていく。
  # 帰り道で子の状態から白、黒のそれぞれのパターン数を計算する。
  que = deque([~0, 0])
  while que:
    current = que.pop()
    if current < 0:
      current = ~current
      for n in EDGES[current]:
        # 子だけを見るので、親ノードだった場合はスキップする。
        if n == parents[current]: continue
        dp[current][0] *= sum(dp[n])
        dp[current][1] *= dp[n][0]

        if dp[current][0] >= mod: dp[current][0]%=mod
        if dp[current][1] >= mod: dp[current][1]%=mod
      continue
    for n in EDGES[current]:
      if checked[n]: continue
      checked[n] = True
      parents[n] = current
      que.append(~n)
      que.append(n)

  print(sum(dp[0])%mod)

resolve()

def resolve():
  mod = 10**9+7
  N = int(input())
  A = [[int(x) for x in input().split(" ")] for _ in range(N)]
  # MATCHES[i]: i 番目の男性と相性の良い女性の index
  MATCHES = [[j for j in range(N) if A[i][j] == 1] for i in range(N)]

  #
  que = deque()


# !/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2020/9/23 下午7:18
# @Author  : Zheng Xingtao
# @File    : spider_30_taohua.py

import asyncio
import os
from pprint import pprint
import urllib.request
import aiohttp
from lxml import etree

loop = asyncio.get_event_loop()

base_url = "http://taohuazu9.com/"
start_url = "http://taohuazu9.com/forum.php?gid=190"
save_path = "/home/zheng/Videos/"

async def get_category():
    """获取分类信息"""
    async with aiohttp.ClientSession() as session:
        while True:
            try:
                async with session.get(start_url) as response:
                    html = await response.text()
                    x_html = etree.HTML(html)

                    category_href_list = x_html.xpath("//div[@id='category_190']//tr/td[2]/h2/a/@href")
                    category_title_list = x_html.xpath("//div[@id='category_190']//tr/td[2]/h2/a/text()")
                    for category_href, category_title in zip(category_href_list, category_title_list):
                        category_task = {
                            'category_title': category_title,
                            'category_href': base_url + category_href,
                        }
                        loop.create_task(parse_detail(session, category_task))
            except Exception as e:
                print(e)
            await asyncio.sleep(5)

async def parse_detail(session, task):
    """获取帖子的详细信息"""
    try:
        async with session.get(task["category_href"]) as response:
            html = await response.text()
            x_html = etree.HTML(html)

            detail_href_list = x_html.xpath("//ul[@id='waterfall']/li//h3/a/@href")
            detail_title_list = x_html.xpath("//ul[@id='waterfall']/li//h3/a/text()")
            image_href = x_html.xpath("""//ul[@id='waterfall']/li/div/a[@onclick="atarget(this)"]/img/@src""")[0]
            for detail_href, detail_title in zip(detail_href_list, detail_title_list):
                detail_task = {
                    'category_title': task["category_title"],
                    'category_href': task["category_href"],
                    'detail_title': detail_title.replace(" ", "").replace("/", "-"),
                    'detail_href': base_url + detail_href,
                    'image_href': image_href,
                }
                # pprint(detail_task)
            loop.create_task(get_torrent_page(session, detail_task))
    except Exception as e:
        print(e)
    await asyncio.sleep(5)

async def get_torrent_page(session, detail_task):
    """获取torrent下载页面"""
    try:
        async with session.get(detail_task["detail_href"]) as response:
            html = await response.text()
            x_html = etree.HTML(html)
            torrent_href = x_html.xpath("""//span[@onmouseover="showMenu({'ctrlid':this.id,'pos':'12'})"]/a/@href""")[0]
            torrent_name = x_html.xpath("""//span[@onmouseover="showMenu({'ctrlid':this.id,'pos':'12'})"]/a/text()""")[
                0]
            torrent_task = {
                "category_title": detail_task["category_title"],
                "category_href": detail_task["category_href"],
                "detail_title": detail_task["detail_title"],
                "detail_href": detail_task["detail_href"],
                "image_href": detail_task["image_href"],
                "torrent_href": base_url + torrent_href,
                "torrent_name": torrent_name,
            }
            # pprint(torrent_task)
            # print(randam, torrent_task)
            loop.create_task(get_torrent(session, torrent_task))
    except Exception as e:
        print(e)
    await asyncio.sleep(5)

async def get_torrent(session, torrent_task):
    """获取torrent下载链接"""
    try:
        async with session.get(torrent_task["torrent_href"]) as response:
            html = await response.text()
            x_html = etree.HTML(html)
            torrent_href = x_html.xpath("""//a[@onclick="hideWindow('imc_attachad')"]/@href""")[0]
            file_task = {
                "category_title": torrent_task["category_title"],
                "category_href": torrent_task["category_href"],
                "detail_title": torrent_task["detail_title"],
                "detail_href": torrent_task["detail_href"],
                "torrent_href": torrent_task["torrent_href"],
                "torrent_name": torrent_task["torrent_name"],
                "image_href": torrent_task["image_href"],
                "file_url": torrent_href
            }
            # pprint(file_task)
            loop.create_task(save_torrent(session, file_task))
    except Exception as e:
        print(e)
    await asyncio.sleep(5)

async def save_torrent(session, file_task):
    try:
        image_name = file_task["detail_title"] + ".jpg"
        torrent_name = file_task["torrent_name"]

        file_save_path = save_path + file_task["category_title"] + "/" + file_task["detail_title"] + "/"
        if not os.path.exists(file_save_path):
            os.makedirs(file_save_path)

        # 使用urllib.request
        urllib.request.urlretrieve(file_task["image_href"], file_save_path + image_name)
        urllib.request.urlretrieve(file_task["file_url"], file_save_path + torrent_name)

        # async with session.get(file_task["file_url"]) as torrent:
        #     pprint(file_task)
        #     with open(file_save_path + torrent_name, "w") as code:
        #         code.write(torrent.content)

        # a bytes-like object is required, not 'StreamReader'
        # async with session.get(file_task["image_href"]) as image:
        #     with open(file_save_path + image_name, "wb") as code:
        #         code.write(image.content.encode())

        print(os.getpid(), "{} 保存完成！".format(file_task["category_title"] + "--" + file_task["detail_title"]))
    except Exception as e:
        print(e)
    await asyncio.sleep(5)

# python 3.7
# asyncio.run(get_category())

# python 3.5
asyncio.get_event_loop().run_until_complete(get_category())


#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Developed by Shangchen Zhou <shangchenzhou@gmail.com>

import os
import sys
import torch
import torch.nn as nn
import torch.nn.init as init
import random
import numpy as np
from datetime import datetime as dt
from config import cfg
import torch.nn.functional as F

import cv2

def mkdir(path):
    if not os.path.isdir(path):
        mkdir(os.path.split(path)[0])
    else:
        return
    os.mkdir(path)

def var_or_cuda(x):
    if torch.cuda.is_available():
        x = x.cuda(non_blocking=True)
    return x

def initialize_weights(net_l, scale=1):
    if not isinstance(net_l, list):
        net_l = [net_l]
    for net in net_l:
        for n, m in net.named_modules():
            if isinstance(m, nn.Conv2d) and not '_mean' in n:
                init.kaiming_normal_(m.weight, a=0, mode='fan_in')
                m.weight.data *= scale  # for residual block
                if m.bias is not None:
                    m.bias.data.zero_()
            elif isinstance(m, nn.Linear):
                init.kaiming_normal_(m.weight, a=0, mode='fan_in')
                m.weight.data *= scale
                if m.bias is not None:
                    m.bias.data.zero_()
            elif isinstance(m, nn.BatchNorm2d):
                init.constant_(m.weight, 1)
                init.constant_(m.bias.data, 0.0)

def set_random_seed(seed, deterministic=False):
    """Set random seed just for debug.
    Args:
        seed (int): Seed to be used.
        deterministic (bool): Whether to set the deterministic option for
            CUDNN backend, i.e., set `torch.backends.cudnn.deterministic`
            to True and `torch.backends.cudnn.benchmark` to False.
            Default: False.
    """
    random.seed(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)
    torch.cuda.manual_seed_all(seed)
    if deterministic:
        torch.backends.cudnn.deterministic = True
        torch.backends.cudnn.benchmark = False

def save_checkpoint(file_path, file_name, epoch_idx, net, solver, best_PSNR, best_epoch):
    if not os.path.exists(file_path):
        mkdir(file_path)
    file_path = os.path.join(file_path, file_name)
    print('[INFO] %s Saving checkpoint to %s ...' % (dt.now(), file_path))
    checkpoint = {
        'epoch_idx': epoch_idx,
        'best_PSNR': best_PSNR,
        'best_epoch': best_epoch,
        'net_state_dict': net.state_dict(),
        'solver_state_dict': solver.state_dict()
    }
    torch.save(checkpoint, file_path)

def count_parameters(model):
    return sum(p.numel() for p in model.parameters())

def get_weight_parameters(model):
    return [param for name, param in model.named_parameters() if ('weight' in name)]

def get_bias_parameters(model):
    return [param for name, param in model.named_parameters() if ('bias' in name)]

class AverageMeter(object):
    """Computes and stores the average and current value"""
    def __init__(self):
        self.reset()

    def reset(self):
        self.val = 0
        self.avg = 0
        self.sum = 0
        self.count = 0

    def update(self, val, n=1):
        self.val = val
        self.sum += val * n
        self.count += n
        self.avg = self.sum / self.count

    def __repr__(self):
        return '{:.5f} ({:.5f})'.format(self.val, self.avg)

##################################
# Image convert functions
##################################
def crop_like(input, target):
    if input.size()[2:] == target.size()[2:]:
        return input
    else:
        return input[:, :, :target.size(2), :target.size(3)].contiguous()

def crop_border(img_list, crop_border):
    """Crop borders of images
    Args:
        img_list (list [Numpy]): HWC
        crop_border (int): crop border for each end of height and weight
    Returns:
        (list [Numpy]): cropped image (list)
    """
    if crop_border == 0: return img_list

    if isinstance(img_list, list):
        return [v[crop_border:-crop_border, crop_border:-crop_border] for v in img_list]
    else:
        return v[crop_border:-crop_border, crop_border:-crop_border]

def tensor2img(tensor, out_type=np.uint8, min_max=(0, 255)):
    '''
    Converts a torch Tensor into an image Numpy array
    Input: 4D(B,(3/1),H,W), 3D(C,H,W), or 2D(H,W), any range, RGB channel order
    Output: 3D(H,W,C) or 2D(H,W), [0,255], np.uint8 (default)
    '''
    assert tensor.dim() == 3

    tensor = tensor.squeeze().float().cpu().clamp_(*min_max)  # clamp
    img_np = tensor.numpy()
    img_np = np.transpose(img_np, (1, 2, 0))[:,:,[2,1,0]]  # HWC, to BGR for cv2 imwrite

    if out_type == np.uint8:
        img_np = img_np.round()
        # Important. Unlike matlab, numpy.unit8() WILL NOT round by default.
    return img_np.astype(out_type)

def img2tensor(img, min_max=(0, 255)):
    '''
    Converts a numpy.ndarray (H x W x C) to a torch.FloatTensor of shape (C x H x W).
    '''
    img = img.astype('float32')
    img = np.transpose(img, (2, 0, 1))
    img = np.ascontiguousarray(img)
    img = torch.from_numpy(img)
    return img.clamp(*min_max)

def rgb2ycbcr(img, only_y=True):
    '''same as matlab rgb2ycbcr
    only_y: only return Y channel
    Input:
        uint8, [0, 255]
        float, [0, 1]
    For matplotlib.image
    '''
    in_img_type = img.dtype
    img.astype(np.float32)
    if in_img_type != np.uint8:
        img *= 255.
    # convert
    if only_y:
        rlt = np.dot(img, [65.481, 128.553, 24.966]) / 255.0 + 16.0
    else:
        rlt = np.matmul(img, [[65.481, -37.797, 112.0], [128.553, -74.203, -93.786],
                              [24.966, 112.0, -18.214]]) / 255.0 + [16, 128, 128]
    if in_img_type == np.uint8:
        rlt = rlt.round()
    else:
        rlt /= 255.
    return rlt.astype(in_img_type)

def bgr2ycbcr(img, only_y=True):
    '''same as matlab rgb2ycbcr
    only_y: only return Y channel
    Input:
        uint8, [0, 255]
        float, [0, 1]
    For opencv
    '''
    in_img_type = img.dtype
    img.astype(np.float32)
    if in_img_type != np.uint8:
        img *= 255.
    # convert
    if only_y:
        rlt = np.dot(img, [24.966, 128.553, 65.481]) / 255.0 + 16.0
    else:
        rlt = np.matmul(img, [[24.966, 112.0, -18.214], [128.553, -74.203, -93.786],
                              [65.481, -37.797, 112.0]]) / 255.0 + [16, 128, 128]
    if in_img_type == np.uint8:
        rlt = rlt.round()
    else:
        rlt /= 255.
    return rlt.astype(in_img_type)

##################################
# adaptive_instance_normalization
##################################

def adaptive_instance_normalization(center_feat, knn_feat, eps=1e-5):
    # center_feat = center_feat.contiguous()
    # knn_feat = knn_feat.contiguous()
    b,m,c,p = center_feat.size()
    _,_,_,sp,k = knn_feat.size()

    center_var = center_feat.var(dim=3) + eps
    center_std = center_var.sqrt().view(b, m, c, 1, 1)
    center_mean = center_feat.mean(dim=3).view(b, m, c, 1, 1)

    knn_var = knn_feat.var(dim=3) + eps
    knn_std = knn_var.sqrt().view(b, m, c, 1, k)
    knn_mean = knn_feat.mean(dim=3).view(b, m, c, 1, k)

    size = knn_feat.size()
    normalized_feat = (knn_feat - knn_mean.expand(size)) / knn_std.expand(size)

    return normalized_feat * center_std.expand(size) + center_mean.expand(size)

##################################
# Efficient and effective test
##################################
class Chop(nn.Module):
    def __init__(self, model):
        super(Chop, self).__init__()
        self.model = model
        self.scale = cfg.CONST.SCALE
        if cfg.CONST.SCALE == 4:
            self.scale_s = 2
        else:
            self.scale_s = cfg.CONST.SCALE

    def forward(self, x_son, x, shave=12, min_size=40000):
        n_GPUs = min(cfg.CONST.NUM_GPU, 4)
        b, c, h_s, w_s = x_son.size()
        _, _, h, w = x.size()
        h_0, w_0 = h%self.scale_s, w%self.scale_s

        h_half_s, w_half_s = h_s//2, w_s//2
        h_half, w_half = h_half_s*self.scale_s, w_half_s*self.scale_s

        shave_s = shave//self.scale_s

        h_size_s, w_size_s = h_half_s + shave_s, w_half_s + shave_s
        h_size, w_size = h_size_s*self.scale_s, w_size_s*self.scale_s

        lr_list_s = [
            x_son[:, :, 0:h_size_s, 0:w_size_s],
            x_son[:, :, 0:h_size_s, (w_s - w_size_s):w_s],
            x_son[:, :, (h_s - h_size_s):h_s, 0:w_size_s],
            x_son[:, :, (h_s - h_size_s):h_s, (w_s - w_size_s):w_s]]

        lr_list = [
            x[:, :, 0:h_size+h_0, 0:w_size+w_0],
            x[:, :, 0:h_size+h_0, (w - w_size-w_0):w],
            x[:, :, (h - h_size-h_0):h, 0:w_size+w_0],
            x[:, :, (h - h_size-h_0):h, (w - w_size-w_0):w]]

        if w_size * h_size < min_size:
            sr_list = []
            for i in range(0, 4, n_GPUs):
                lr_s_batch = torch.cat(lr_list_s[i:(i + n_GPUs)], dim=0)
                lr_batch = torch.cat(lr_list[i:(i + n_GPUs)], dim=0)
                sr_batch = self.model(lr_s_batch, lr_batch)
                sr_list.extend(sr_batch.chunk(n_GPUs, dim=0))
        else:
            sr_list = [
                self.forward(patch_s, patch, shave=shave, min_size=min_size) \
                for (patch_s, patch) in zip(lr_list_s, lr_list)
            ]

        h, w = self.scale * h, self.scale * w

        h_half, w_half = self.scale * h_half, self.scale * w_half
        h_size, w_size = self.scale * h_size, self.scale * w_size
        shave *= self.scale
        h_0, w_0 = h_0*self.scale, w_0*self.scale
        output = x.new(b, c, h, w)
        output[:, :, 0:h_half, 0:w_half] \
            = sr_list[0][:, :, 0:h_half, 0:w_half]
        output[:, :, 0:h_half, w_half:w] \
            = sr_list[1][:, :, 0:h_half, (w_size - w + w_half+w_0):w_size+w_0]
        output[:, :, h_half:h, 0:w_half] \
            = sr_list[2][:, :, (h_size - h + h_half+h_0):h_size+h_0, 0:w_half]
        output[:, :, h_half:h, w_half:w] \
            = sr_list[3][:, :, (h_size - h + h_half+h_0):h_size+h_0, (w_size - w + w_half+w_0):w_size+w_0]

        return output

def forward_x8(x_son, x, forward_function):
    def _transform(v, op):

        v2np = v.data.cpu().numpy()
        if op == 'v':
            tfnp = v2np[:, :, :, ::-1].copy()
        elif op == 'h':
            tfnp = v2np[:, :, ::-1, :].copy()
        elif op == 't':
            tfnp = v2np.transpose((0, 1, 3, 2)).copy()

        ret = torch.Tensor(tfnp).cuda()

        return ret

    lr_son_list = [x_son]
    lr_list = [x]
    for tf in 'v', 'h', 't':
        lr_son_list.extend([_transform(t, tf) for t in lr_son_list])
        lr_list.extend([_transform(t, tf) for t in lr_list])

    sr_list = [forward_function(lr_son, lr) for (lr_son, lr) in zip(lr_son_list, lr_list)]
    for i in range(len(sr_list)):
        if i > 3:
            sr_list[i] = _transform(sr_list[i], 't')
        if i % 4 > 1:
            sr_list[i] = _transform(sr_list[i], 'h')
        if (i % 4) % 2 == 1:
            sr_list[i] = _transform(sr_list[i], 'v')

    output_cat = torch.cat(sr_list, dim=0)
    output = output_cat.mean(dim=0, keepdim=True)

    return output


from django.db import models

class Team(models.Model):
    name = models.CharField(max_length=100,primary_key=True)
    coach = models.CharField(max_length=150,null=True,blank=True)

    class Meta:
      ordering = ["name"]
      verbose_name = "Time"
      verbose_name_plural = "Times"

    def __str__(self):
      return f'Time:{self.name.upper()}'

class Color(models.Model):
    teams      = models.ManyToManyField(Team)
    definition = models.CharField(max_length=40,unique=True)

    class Meta:
        ordering = ["definition"]
        verbose_name_plural = "Colors"

    def __str__(self):
        return self.definition.lower()

class SoccerPlayer(models.Model):
    team     = models.ForeignKey(Team,on_delete=models.SET_NULL,null=True)
    name     = models.CharField(max_length=150)
    number   = models.IntegerField()

    class Meta:
        ordering = ["number","-team"]
        verbose_name_plural = "SoccerPlayers"
        constraints = [
            models.UniqueConstraint(
                fields=('team', 'name','number'), name='unique_team_name_number'
            )
        ]

    def __str__(self):
        return self.name.upper()

class Match(models.Model):
    team_home      = models.ForeignKey(Team,on_delete=models.CASCADE,related_name='related_home_team')
    team_visiting  = models.ForeignKey(Team,on_delete=models.CASCADE,related_name='related_visiting_team')
    tournament     = models.CharField(max_length=100)
    goal_home      = models.IntegerField(default=0)
    goal_visiting  = models.IntegerField(default=0)
    date           = models.DateTimeField()

    class Meta:
        ordering = ["-date"]
        verbose_name_plural = "Matchs"
        constraints = [
            models.UniqueConstraint(
                fields=('tournament', 'team_home','team_visiting'), name='unique_tournament_team_home_visiting'
            )
        ]

    def __str__(self):
        return f'{self.tournament.upper()}: {self.team_home.name.upper()} x {self.team_visiting.name.upper()}'

class PlayGame(models.Model):
    GOL = 'GL'
    LAT_DIR = 'LD'
    LAT_ESQ = 'LE'
    ZAG = 'ZA'
    VOL = 'VL'
    MEIA = 'ME'
    ATAC = 'TK'
    POSITIONS = (
        (GOL,'Goleiro'),
        (LAT_DIR,'Lateral Direita'),
        (LAT_ESQ,'Lateral Esquerda'),
        (ZAG,'Zagueiro'),
        (VOL,'Volante'),
        (MEIA,'Meia'),
        (ATAC,'Atacante'),
    )

    soccerplayer = models.ForeignKey(SoccerPlayer,on_delete=models.CASCADE)
    match        = models.ForeignKey(Match,on_delete=models.CASCADE)
    position     = models.CharField(max_length=2,choices=POSITIONS)

    class Meta:
        verbose_name_plural = "Play Games"
        constraints = [
            models.UniqueConstraint(
                fields=('soccerplayer', 'match','position'), name='unique_soccerplayer_match_position'
            )
        ]

    def __str__(self):
        return f'{self.soccerplayer.name.upper()} - {self.get_position_display().upper()}'


import numpy as np
import scipy.io
from nn import *
import matplotlib.pyplot as plt
import pickle
import string
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import ImageGrid

train_data = scipy.io.loadmat('../data/nist36_train.mat')
valid_data = scipy.io.loadmat('../data/nist36_valid.mat')

train_x, train_y = train_data['train_data'], train_data['train_labels']
valid_x, valid_y = valid_data['valid_data'], valid_data['valid_labels']

max_iters = 150
# pick a batch size, learning rate
batch_size = 64
learning_rate = 0.001#Also trained with 0.01, 0.001 and 0.0001
hidden_size = 64

batches = get_random_batches(train_x, train_y, batch_size)
batch_num = len(batches)

params = {}

# initialize layers here
initialize_weights(train_x.shape[1], hidden_size, params, 'layer1')
initialize_weights(hidden_size, train_y.shape[1], params, 'output')

# with default settings, you should get loss < 150 and accuracy > 80%
train_loss, train_accuracy = [], []
valid_loss, valid_accuracy = [], []
for itr in range(max_iters):
    total_loss = 0
    total_acc = 0
    for xb, yb in batches:
        # training loop can be exactly the same as q2!

        # plt.figure()
        # plt.imshow(np.reshape(xb,(64,32,32))[0,:,:])
        # plt.colorbar()
        # plt.show()

        yb = yb.astype(int)
        # forward
        h1 = forward(xb, params, 'layer1')
        probs = forward(h1, params, 'output', softmax)

        # loss
        # be sure to add loss and accuracy to epoch totals
        loss, acc = compute_loss_and_acc(yb, probs)
        total_loss += loss
        total_acc += acc

        # backward
        delta2 = backwards(probs - yb, params, 'output', linear_deriv)
        backwards(delta2, params, 'layer1', sigmoid_deriv)

        # apply gradient
        params['Wlayer1'] -= learning_rate * params['grad_Wlayer1']
        params['blayer1'] -= learning_rate * params['grad_blayer1']
        params['Woutput'] -= learning_rate * params['grad_Woutput']
        params['boutput'] -= learning_rate * params['grad_boutput']

    total_acc /= batch_num

    train_loss.append(total_loss)
    train_accuracy.append(total_acc)

    if itr % 2 == 0:
        print("itr: {:02d} \t loss: {:.2f} \t acc : {:.2f}".format(itr, total_loss, total_acc))

    # run on validation set per iteration
    valid_y = valid_y.astype(int)
    probs = forward(forward(valid_x, params, 'layer1'), params, 'output', softmax)
    loss, acc = compute_loss_and_acc(valid_y, probs)
    valid_loss.append(loss)
    valid_accuracy.append(acc)

plt.figure('accuracy')
plt.plot(range(max_iters), train_accuracy, color='r')
plt.plot(range(max_iters), valid_accuracy, color='g')
plt.legend(['train', 'validation'])
plt.show()

plt.figure('loss')
plt.plot(range(max_iters), train_loss, color='r')
plt.plot(range(max_iters), valid_loss, color='g')
plt.legend(['train', 'validation'])
plt.show()

# run on validation set and report accuracy! should be above 75%
h1 = forward(valid_x, params, 'layer1')
probs = forward(h1, params, 'output', softmax)
valid_loss, valid_acc = compute_loss_and_acc(valid_y, probs)

print('Validation accuracy: ', valid_acc)

test_data = scipy.io.loadmat('../data/nist36_test.mat')
test_x, test_y = test_data['test_data'], test_data['test_labels']
# run on test set
h1 = forward(test_x, params, 'layer1')
probs = forward(h1, params, 'output', softmax)
test_loss, test_acc = compute_loss_and_acc(test_y, probs)
print('Test accuracy: ', test_acc)

saved_params = {k:v for k,v in params.items() if '_' not in k}
with open('q3_weights.pickle', 'wb') as handle:
    pickle.dump(saved_params, handle, protocol=pickle.HIGHEST_PROTOCOL)

with open('q3_weights.pickle', 'rb') as handle:
    data = pickle.load(handle)
    params['Wlayer1'] = data['Wlayer1']
    params['blayer1'] = data['blayer1']
    params['Woutput'] = data['Woutput']
    params['boutput'] = data['boutput']

# Q3.1.3

empty_params = {}
initialize_weights(train_x.shape[1], hidden_size, empty_params, 'layer1')
initialize_weights(hidden_size, train_y.shape[1], empty_params, 'output')

fig = plt.figure()
grid = ImageGrid(fig, 111, nrows_ncols=(8, 8))
for i in range(hidden_size):
    grid[i].imshow(np.reshape(empty_params['Wlayer1'][:, i], (32, 32)))  # The AxesGrid object work as a list of axes.
    plt.axis('off')
plt.show()

fig = plt.figure()
grid = ImageGrid(fig, 111, nrows_ncols=(8, 8))
for i in range(hidden_size):
    grid[i].imshow(np.reshape(params['Wlayer1'][:, i], (32, 32)))  # The AxesGrid object work as a list of axes.
    plt.axis('off')
plt.show()

# Q3.1.4

def get_confusion_matrix(probs, y):
    confusion_matrix = np.zeros((y.shape[1], y.shape[1]))

    y = y.astype(int)
    pred_y = (probs == np.expand_dims(np.max(probs, axis=1), axis=1))
    with_same_prob = np.where(np.sum(pred_y, axis=1) > 1)[0]
    for i in range(with_same_prob.shape[0]):
        pred_y[i, np.where(pred_y[i, :] == np.max(pred_y[i, :]))[0][0] + 1:] = False

    yl = [np.where(y[i, :] == 1)[0][0] for i in range(y.shape[0])]
    pred_yl = [np.where(pred_y[i, :] == 1)[0][0] for i in range(pred_y.shape[0])]

    for a, p in zip(yl, pred_yl):
        confusion_matrix[a][p] += 1

    return confusion_matrix

# confusion matrix for training data
train_data = scipy.io.loadmat('../data/nist36_train.mat')
train_x, train_y = train_data['train_data'], train_data['train_labels']
train_probs = forward(forward(train_x, params, 'layer1'), params, 'output', softmax)

confusion_matrix = get_confusion_matrix(train_probs, train_y)

plt.imshow(confusion_matrix, interpolation='nearest')
plt.grid(True)
plt.xticks(np.arange(36), string.ascii_uppercase[:26] + ''.join([str(_) for _ in range(10)]))
plt.yticks(np.arange(36), string.ascii_uppercase[:26] + ''.join([str(_) for _ in range(10)]))
plt.show()

# confusion matrix for validation data
valid_data = scipy.io.loadmat('../data/nist36_valid.mat')
valid_x, valid_y = valid_data['valid_data'], valid_data['valid_labels']
valid_probs = forward(forward(valid_x, params, 'layer1'), params, 'output', softmax)

confusion_matrix = get_confusion_matrix(valid_probs, valid_y)

plt.imshow(confusion_matrix, interpolation='nearest')
plt.grid(True)
plt.xticks(np.arange(36), string.ascii_uppercase[:26] + ''.join([str(_) for _ in range(10)]))
plt.yticks(np.arange(36), string.ascii_uppercase[:26] + ''.join([str(_) for _ in range(10)]))
plt.show()

# confusion matrix for test data
test_data = scipy.io.loadmat('../data/nist36_test.mat')
test_x, test_y = test_data['test_data'], test_data['test_labels']
test_probs = forward(forward(test_x, params, 'layer1'), params, 'output', softmax)

confusion_matrix = get_confusion_matrix(test_probs, test_y)

plt.imshow(confusion_matrix, interpolation='nearest')
plt.grid(True)
plt.xticks(np.arange(36), string.ascii_uppercase[:26] + ''.join([str(_) for _ in range(10)]))
plt.yticks(np.arange(36), string.ascii_uppercase[:26] + ''.join([str(_) for _ in range(10)]))
plt.show()


from brownie import StrategySwapper, AddressProvider  # type: ignore
from support.mainnet_contracts import TokenAddresses, VendorAddresses
from support.utils import scale

from support.utils import (
    get_deployer,
    make_tx_params,
    with_deployed,
    with_gas_usage,
)

@with_gas_usage
@with_deployed(AddressProvider)
def deploy_strategy_swapper(address_provider):
    tx_params = make_tx_params()
    deployer = get_deployer()

    ## Deploying strategy swapper
    strategy_swapper = deployer.deploy(
        StrategySwapper,
        address_provider,
        scale("0.97"),
        **tx_params,
    )

    ## Setting curve pools
    strategy_swapper.setCurvePool(TokenAddresses.CRV, VendorAddresses.CURVE_CRV_ETH_POOL, {"from": deployer, **tx_params})
    strategy_swapper.setCurvePool(TokenAddresses.CVX, VendorAddresses.CURVE_CVX_ETH_POOL, {"from": deployer, **tx_params})

    return strategy_swapper

def main():
    deploy_strategy_swapper()


import PySimpleGUI as sg
from tkinter import *
from tkinter import simpledialog
from tkinter import messagebox
from PIL import ImageTk, Image,ImageFilter
import os
import math
import cv2
from os import listdir
from os.path import isfile, join
import numpy as np
from itertools import cycle
import json

def writeToJSONFile(path, fileName, data):
    filePathNameWExt =  path + '/' + fileName + '.json'
    with open(filePathNameWExt, 'w') as fp:
        json.dump(data, fp)

class GUI:
    def move(self,event):
        if event.char == "a":
            self.canvas.move(self.img_id, -10, 0)
        elif event.char == "d":
            self.canvas.move(self.img_id, 10, 0)
        elif event.char == "w":
            self.canvas.move(self.img_id, 0, -10)
        elif event.char == "s":
            self.canvas.move(self.img_id, 0, 10)

    def resetZoom(self):
        self.canvas_image = ImageTk.PhotoImage(self.curIt)
        self.moveIM = self.canvas.create_image(self.w/2, self.h/2-100, image=self.canvas_image, anchor="center")
        self.zoomed = False
        self.scale = 1
    def zoomOut(self):
        self.scale *= float(2)/3
        self.redraw(self.x, self.y)
    def zoomIn(self):
        self.scale *= 1.5
        self.redraw(self.x, self.y)

    def redraw(self, x=0, y=0):
        if self.img_id:
            self.canvas.delete(self.img_id)
        self.zX = x
        self.zY = y
        print(self.curIt.size)
        self.iw, self.ih = self.curIt.size
        size = int(self.iw * self.scale), int(self.ih * self.scale)
        self.initial_im = self.canvas_image
        self.canvas_image = ImageTk.PhotoImage(self.curIt.resize(size),Image.ANTIALIAS)
        print(size)
        self.canvas.delete(ALL)
        self.img_id = self.canvas.create_image(self.w/2, self.h/2-100, image=self.canvas_image, anchor = "center")
        self.zoomed = True
        self.canvas.old_coords = None

    def leftClick(self,event):
        self.x,self.y = event.x, event.y
        if self.canvas.old_coords:

            self.x1, self.y1 = self.canvas.old_coords
            self.canvas.create_line(self.x, self.y, self.x1, self.y1, width = 2)
            self.canvas.old_coords = None
            if self.x == self.x1:
                if self.y1 < self.y:
                    degree = 90
                else:
                    degree = 270
            elif self.y == self.y1:
                if self.x1 < self.x:
                    degree = 0
                else:
                    degree = 0
            else:
                slope = -(self.y1-self.y)/(self.x1-self.x)
                degree = math.degrees(math.atan(slope))
                degree = round(degree)
                if self.y < self.y1:
                    if degree < 0:
                        degree = 180 + degree
                else:
                    if degree < 0:
                        degree = 360 + degree
                    else:
                        degree = 180 + degree
            if degree == 360:
                degree = 0

            self.angle = str(degree)
            self.label.config(text=self.angle)
            print(degree)

        else:
            self.canvas.old_coords = self.x, self.y
            #self.button2Click()

    def buttonClick(self):

        if (self.angle == None):
            answer  = messagebox.askyesnocancel("Skip the Image","Any angle has not chosen yet, do you want to skip the image?")
            if answer == True:
                self.curName=next(self.iteratorName)
                if self.data[self.curName] == False:
                    self.canvas.delete(ALL)
                    self.curIt = next(self.iterator)
                    self.canvas_image = ImageTk.PhotoImage(self.curIt)
                    self.moveIM = self.canvas.create_image(self.w/2, self.h/2-100, image=self.canvas_image, anchor="center")
                    self.zoomed = False
                    self.scale = 1
                    self.angle = None
                else:
                    messagebox.showinfo("Quit","No Image Left")
                    self.window.destroy()
        else:
            self.f.write(self.curName +","+ self.angle + "\n")
            self.angle = None
            self.label.config(text=self.angle)
            self.data[self.curName] = True
            writeToJSONFile(self.direc,'file-name',self.data)
            self.curName=next(self.iteratorName)

            if self.data[self.curName] == False:
                self.canvas.delete(ALL)
                self.curIt = next(self.iterator)
                self.canvas_image = ImageTk.PhotoImage(self.curIt)
                self.moveIM = self.canvas.create_image(self.w/2, self.h/2-100, image=self.canvas_image, anchor="center")
                self.zoomed = False
                self.scale = 1

            else:
                 messagebox.showinfo("Quit","No Image Left")
                 self.window.destroy()

    def __init__(self):

        self.window = Tk()
        self.window.withdraw()
        self.direc = simpledialog.askstring("Directory","Please enter the directory",initialvalue="C:/Users/cagri/OneDrive/Desktop/Yedek/py/all/set")

        self.window.title("Angle Calculator")
        self.w, self.h = self.window.winfo_screenwidth(), self.window.winfo_screenheight()
        self.window.geometry("%dx%d+0+0" % (self.w, self.h-70))

        self.window.configure(background='grey')
        self.initial_im = None
        self.zX = None
        self.zY = None
        self.zoomed = False
        self.iw = None
        self.ih = None
        self.scale = 1
        self.img_id = None
        self.img = None
        self.x = None
        self.y = None
        self.x1 = None
        self.y1 = None
        self.images = []
        self._drag_data1 = {"x": 0, "y": 0, "item1": None}
        try:
            r = open(self.direc + "/" + 'Name-Angle.txt',mode='r')
            alltxt = r.read()
            r.close()
        except:
            alltxt = ""
        self.f = open(self.direc + "/" +'Name-Angle.txt', 'w')
        self.f.write(alltxt)
        dirs = os.listdir( self.direc )

        try:
            filePathNameWExt =  self.direc + '/' + 'file-name' + '.json'
            with open(filePathNameWExt, "r") as read_file:
                self.data = json.load(read_file)
        except:
            print("Not Found")
            self.data = {}

        print(self.data)
        # resize image
        names = []
        for file in dirs:
            #st = file.find(".jpg" ) is not -1) or (file.find(".JPG" ) is not -1) or (file.find(".bmp" ) is not -1) or (file.find(".BMP" ) is not -1)
            #st = (file.find(".bmp" ) is not -1) or (file.find(".BMP" ) is not -1)# or (file.find(".j" ) is not -1) or (file.find(".BMP" ) is not -1)
            if (file.find(".bmp" ) is not -1) or (file.find(".BMP" ) is not -1):
                file = file.replace(".bmp","")
                file = file.replace(".BMP","")

                if (file in self.data):
                    if (self.data[file] == False):
                        im = cv2.cvtColor(cv2.imread(self.direc+"/"+file+".bmp"), cv2.COLOR_BGR2RGB)
                        im = Image.fromarray(im)
                        names.append(file)
                        self.images.append(im)
                else:
                    im = cv2.imread(self.direc+"/"+file+".bmp")
                    im = Image.fromarray(im)
                    names.append(file)
                    self.images.append(im)
                    self.data[file] = False
            elif (file.find(".jpg" ) is not -1) or (file.find(".JPG" ) is not -1):
                file = file.replace(".jpg","")
                file = file.replace(".JPG","")
                print(self.direc+"/"+file+".jpg")
                if (file in self.data):
                    if (self.data[file] == False):
                        im = cv2.cvtColor(cv2.imread(self.direc+"/"+file+".jpg"), cv2.COLOR_BGR2RGB)
                        im = Image.fromarray(im)
                        names.append(file)
                        self.images.append(im)
                else:
                    #im = cv2.imread("1.jpg")
                    im = cv2.imread(self.direc+"/"+file+".jpg")
                    print(type(im))
                    im = Image.fromarray(im)
                    names.append(file)
                    self.images.append(im)
                    self.data[file] = False
        self.iterator = cycle(self.images)
        self.iteratorName = cycle(names)

        try:
            self.curName = next(self.iteratorName)
        except:
            messagebox.showinfo("Quit","No JPG Image Found")
            self.window.quit()
        self.curIt = next(self.iterator)
        self.img = ImageTk.PhotoImage(self.curIt)
        self.canvas_image = self.img
        writeToJSONFile(self.direc,'file-name',self.data)
        Button(text="Next Image",command=self.buttonClick).pack(side = "bottom", fill = "both", expand = "no")
        Button(text="Zoom In",command=self.zoomIn).pack(side = "bottom", fill = "both", expand = "no")
        Button(text="Zoom Out",command=self.zoomOut).pack(side = "bottom", fill = "both", expand = "no")
        Button(text="Reset Zoom",command=self.resetZoom).pack(side = "bottom", fill = "both", expand = "no")
        self.angle = None
        self.label = Label(text = self.angle)
        self.label.pack(side = "bottom", fill = "both", expand = "no")

        self.canvas = Canvas(width=self.w, height=self.h)
        self.canvas.pack(expand=YES, fill=BOTH)
        self.canvas.old_coords = None
        self.canvas_image = self.img
        self.moveIM = self.canvas.create_image(self.w/2, self.h/2-100, image=self.img, anchor="center")
        self.canvas.bind("<Button-1>",self.leftClick)
        self.window.bind("<Key>", self.move)
        self.move_flag = False
        self.mouse_xpos = self.w/2
        self.mouse_ypos = self.h/2-100
        self.window.deiconify()
        self.window.mainloop()
def main():
    GUI()
if __name__ == "__main__":
     main()


from os import environ
from os.path import dirname, join
# environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
import tensorflow as tf
from joblib import load
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from deep_translator import GoogleTranslator

NUM_WORDS = 189
MAX_TEXT_LEN = 910
MODEL_PATH = "training_1/model"
model_dir = dirname(MODEL_PATH)

if __name__ == "__main__":
    translator = GoogleTranslator(source="it", target="en")
    model = tf.keras.models.load_model(MODEL_PATH)
    tokenizer_path = join(model_dir, "tokenizer.joblib")
    tokenizer: Tokenizer = load(tokenizer_path)
    while True:
        messages = [input("Message: ")]
        translated_messages = list(map(translator.translate, messages))
        for translated_message in translated_messages:
            print(f"Translated Message: {translated_message}")
        sequences = tokenizer.texts_to_sequences(translated_messages)
        X = pad_sequences(sequences, maxlen=NUM_WORDS)
        print(sequences)
        y = model.predict(X, verbose=0).flatten()
        for prediction in y:
            if y > 0.5:
                print("Not SPAM")
            else:
                print("SPAM")


import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import copy

times = 1
distance = 4.1
neighbors = []

# def neighbor(points):

def move(x, y, t):
    # moving: y = x*2
    resx = x+t
    resy = y + t*2

def show(points):
    global times
    fig = plt.figure(times)
    plt.scatter(points[:, 0], points[:, 1], c='r')
    print(points)
    plt.plot(16,16,'bo')
    plt.plot(0, 0, 'bo')
    plotx = []
    ploty = []
    for index in range(len(points)):
        plotx.append(points[index][0])
        ploty.append(points[index][1])
        plt.annotate(s=index, xy=(points[index][0], points[index][1]), xytext=(-5, 5), textcoords='offset points')

    times = times + 1

def anim(list_points):
    fig = plt.figure()
    ax = plt.axes(xlim=(-2, 30), ylim=(-2, 30))
    length = len(list_points)
    new_points = np.array(list_points[0])
    scat = ax.scatter(new_points[:, 0], new_points[:, 1], c='r')

    def update(frame_number):
        global new_points
        new_points = np.array(list_points[frame_number])
        new_points = new_points[:,0:2]
        print('update ', frame_number, list_points[frame_number])
        scat.set_offsets(new_points)
        return scat,

    animate = animation.FuncAnimation(fig, update, frames=length, interval=200, blit=False)  # interval是每隔70毫秒更新一次，可以查看help
    animate.save('basic_animation.mp4', fps=30, extra_args=['-vcodec', 'libx264'])
    plt.show()

points = np.loadtxt('./node.npy')
points = points[0:11, :]
list_points = []
list_points.append(copy.deepcopy(points))
iterator_time = 30
robot_num = len(points)
time = 1
# show(points)
while iterator_time > 0:
    for index in range(robot_num):
        if index == 0 or index == 1 or index == 10:
            points[index][0] = points[index][0] + (np.random.random()-0.5) + 0.5
            points[index][1] = points[index][1] + (np.random.random() - 0.5) + 0.5
    # print('iteraotr_time is ', iterator_time, points)
    list_points.append(copy.deepcopy(points))
    # show(points)
    for index in range(robot_num):
        if index != 0 and index != 1 and index != 10:
            points[index][0] = points[index][0] + (np.random.random()-0.5) + 0.5
            points[index][1] = points[index][1] + (np.random.random() - 0.5) + 0.5
            rand = np.random.randint(0, 3)
            if rand == 0:
                points[index][0] = points[index][0] + (np.random.random() - 0.5)
                points[index][1] = points[index][1] + (np.random.random() - 0.5) * 3
    # print('iteraotr_time is ', iterator_time, points)
    list_points.append(copy.deepcopy(points))
    # show(points)
    iterator_time = iterator_time - 1

anim(list_points)
# print(list_points)
# plt.show()

#
# import numpy as np
# import matplotlib
# import matplotlib.pyplot as plt
# from matplotlib.animation import FuncAnimation
# # from matplotlib import animation
# # No toolbar
# matplotlib.rcParams['toolbar'] = 'None'
# # New figure with white background
# fig = plt.figure(figsize=(6,6), facecolor='white')
# # New axis over the whole figureand a 1:1 aspect ratio
# # ax = fig.add_axes([0,0,1,1], frameon=False, aspect=1)
# ax = fig.add_axes([0.005,0.005,0.990,0.990], frameon=True, aspect=1)
# # Number of ring
# n = 50
# size_min = 50
# size_max = 50*50
# # Ring position ，圆环位置，范围在[0,1]之间
# P = np.random.uniform(0,1,(n,2))
# # Ring colors环的颜色
# C = np.ones((n,4)) * (0,1,0,1)
# #C = np.ones((n,3)) * (1,0,1)
# # Alpha color channel goes from 0 (transparent) to 1 (opaque)
# # 透明度，数值在[0,1]之间
# C[:,2] = np.linspace(0,1,n)
# # Ring sizes环的大小，范围在[50,2500]
# S = np.linspace(size_min, size_max, n)
# # Scatter plot
# # 散点图绘制
# scat = ax.scatter(P[:,0], P[:,1], s=S, lw = 0.5,
#          edgecolors = C, facecolors='None')
# # Ensure limits are [0,1] and remove ticks
# #保证x,y的范围在[0,1]之间,移除坐标轴标记
# ax.set_xlim(0,1), ax.set_xticks([])
# ax.set_ylim(0,1), ax.set_yticks([])
# def update(frame):
#   global P, C, S
#   # Every ring is made more transparent每个环变得更透明
#   C[:,3] = np.maximum(0, C[:,3] - 1.0/n)
#   # Each ring is made larger每个环都比原来的大
#   S += (size_max - size_min) / n
#   # Reset ring specific ring (relative to frame number)
#   i = frame % 50
#   P[i] = np.random.uniform(0,1,2) # P[i] = P[i,:],同时改变了x,y两个位置的值
#   S[i] = size_min #从最小的形状开始
#   C[i,3] = 1   #设置透明度为1
#   # Update scatter object
#   # 更新scatter绘图对象的属性，例如edgecolors,sizes,offsets等
#   scat.set_edgecolors(C) #设置边缘颜色
#   scat.set_sizes(S)    #设置大小
#   scat.set_offsets(P)   #设置偏置
#   print('update ',frame)
#   return scat,
# animate = FuncAnimation(fig, update, frames = 300,interval=70)#interval是每隔70毫秒更新一次，可以查看help
# # FFwriter = animation.FFMpegWriter(fps=20)  #frame per second帧每秒
# # animate.save('rain.mp4', writer=FFwriter,dpi=360)#设置分辨率
# plt.show()


from datetime import datetime
from unittest import mock
from entities.book import Book
from entities.order import Order
from entities.customer import Customer
from UserInterface import UserInterface
from repositories.book_repository import BookRepository
from repositories.customer_repository import CustomerRepository
from repositories.order_repository import OrderRepository
import unittest

class TestGeral(unittest.TestCase):
    def test_registration(self):
        with mock.patch('builtins.input', side_effect=[2,"asd",2]):
            user = UserInterface(CustomerRepository(), BookRepository(), OrderRepository())
            user_input = user.register_new_customer()
            user_input2 = user.register_new_customer()

            self.assertEquals(user_input, "Client cadastrado com sucesso!")
            self.assertEquals(user_input2, "Cliente já existe")

    def test_validate_sell(self):
        customer_repository = CustomerRepository()
        book_repository = BookRepository()
        order_repository = OrderRepository()
        user_interface = UserInterface(customer_repository, book_repository, order_repository)

        customer1 = Customer(1,'c1')
        customer_repository.list_customers.append(customer1)

        book1 = Book(1, "Livro1", "a", "autor1", "tipo1", 10)
        book2 = Book(2, "Livro2", "b", "autor2","tipo2", 15)
        book3 = Book(3, "Livro3", "c", "autor3", "tipo3", 20)
        book4 = Book(4, "Livro4", "d", "autor4","tipo4", 0)
        book_repository.list_books.append(book4)
        book_repository.list_books.append(book2)
        book_repository.list_books.append(book3)

        book_repository.down_stock(book3.id)

        order1 = Order(1,customer1,datetime.today())
        order_repository.list_orders.append(order1)

        book_not_exist = user_interface.verify_if_sell_is_possible(2,customer1.id,book1)
        book_zeroed = user_interface.verify_if_sell_is_possible(2,customer1.id,book3)
        book_invalid_price = user_interface.verify_if_sell_is_possible(2,customer1.id,book4)
        invalid_order = user_interface.verify_if_sell_is_possible(order1.id,customer1.id,book2)
        invalid_customer = user_interface.verify_if_sell_is_possible(2,2,book1)

        self.assertEqual(book_not_exist, "Livro não cadastrado")
        self.assertEqual(book_zeroed, "Livro esgotado")
        self.assertEqual(book_invalid_price, "Livro com preço invalido")
        self.assertEqual(invalid_order, "Pedido já existe")
        self.assertEqual(invalid_customer, "Cliente não existe")

def test_selling(monkeypatch):
    customer_repository = CustomerRepository()
    book_repository = BookRepository()
    order_repository = OrderRepository()
    user_interface = UserInterface(customer_repository, book_repository, order_repository)

    book1 = Book(1, "livro1", "a", "autor1", "tipo1", 15)
    book_repository.list_books.append(book1)

    customer1 = Customer(1, "c1")
    customer_repository.list_customers.append(customer1)

    inputs = iter([1, customer1.id, book1.id])
    monkeypatch.setattr('builtins.input', lambda _: next(inputs))
    vendido = user_interface.selling_book()

    inputs = iter([2, 2, 2])
    monkeypatch.setattr('builtins.input', lambda _: next(inputs))
    nao_vendido = user_interface.selling_book()

    assert vendido == "Pedido cadastrado com sucesso!"
    assert nao_vendido == "Algo deu errado :/"


# %% operatory bool
a, b = 3, 4
print(a == b)
print(a != b)
print(a < b)
print(a > b)
print(a <= b)
print(a >= b)
print(True and False)
print(True or False)
print(not True)
my_boolean = True
print(my_boolean)
# %% kontrola przepływu
x = 50
if x > 5:
    print('highter')
elif x < 60:
    print('lower 60')
else:
    print('more')
# %%
x = 50
if x == 50:
    print('highter')
    if x < 60:
        print('lower 60')
else:
    print('more')
# %% pętla while
# pętla bez końca trzeba podać warunek by zakończyć
x = 10
while True:
    if x >= 0:
        print(f'liczba {x}')
        x -= 1
    else:
        print('end')
        break
# %%
x = 0
while x < 5:
    print(f"liczba {x}")
    x += 1
# %% while break continue
i = 1
while i <= 5:
    print(f"liczba {i}")
    i += 1
    if i == 3:
        print(f'skip {i}')
        continue
    if i == 5:
        print(f"koniec {i}")
        break

# %%
i = 0
x = 0
while i < 4:
    x += i
    i += 1
    print(i, x)
print(x)
# %% petla for
for x in range(5):
    print(x)

# %% for vs while
"""
Pętla for jest pętlą sończoną, a dla pętli while trzeba podać
Warunek przerwania pętli.
Pętla while może wykonywać to samo co pętla for tylko mniej elegancko.
"""

for i in range(5):
    print(f'pętla for liczba {i}')
    i += 1
i = 0
while i < 5:
    print(f'pętla while liczba {i}')
    i += 1
# %%

def func(x):
    res = 0
    for i in range(x):
        res += i
    return res

print(func(4))  # 0 + 1 + 2 + 3 = 6
# %%


#Greatest common divisor function.

def gcd(a, b):
    if a > b:
        r = a % b
        if r == 0:
            return b
        else:
            return gcd(b, r)
    if a < b:
        r = b % a
        if r == 0:
            return a
        else:
            return gcd(a, r)
    if a == b:
        return a

def R(num):
    """ (int) -> number

    Return the sum of 1/(p*q) for all integer pairs p and q that satisfy

    1. 1 <= p < q <= num
    2. p + q >= M
    3. p and q are coprime.

    >>> R(2)
    0.5
    >>> R(3)
    1
    """

    M = num
    R_sum = 0

    for q in range(1, M + 1):
        for p in range(1, q):
            if p + q >= M and gcd(p, q) == 1:
                R_sum = R_sum + 1/(p*q)

    return R_sum

def S(num):
    """ (int) -> number

    Return the sum of R(i) for 2 <= i <= num.
    >>> S(2)
    0.5
    >>> S(10)
    6.9147
    >>> S(100)
    58.2962
    """

    S_sum = 0

    for i in range(2, num + 1):
        S_sum = S_sum + R(num)

    return S_sum


"""Tencent Vector store index.

An index that that is built with Tencent Vector Database.

"""
import json
from typing import Any, Dict, List, Optional

from llama_index.schema import BaseNode, NodeRelationship, RelatedNodeInfo, TextNode
from llama_index.vector_stores.types import (
    VectorStore,
    VectorStoreQuery,
    VectorStoreQueryResult,
)
from llama_index.vector_stores.utils import DEFAULT_DOC_ID_KEY, DEFAULT_TEXT_KEY

DEFAULT_USERNAME = "root"
DEFAULT_DATABASE_NAME = "llama_default_database"
DEFAULT_COLLECTION_NAME = "llama_default_collection"
DEFAULT_COLLECTION_DESC = "Collection for llama index"
DEFAULT_TIMEOUT: int = 30

DEFAULT_SHARD = 1
DEFAULT_REPLICAS = 2
DEFAULT_INDEX_TYPE = "HNSW"
DEFAULT_METRIC_TYPE = "COSINE"

DEFAULT_HNSW_M = 16
DEFAULT_HNSW_EF = 200
DEFAULT_IVF_NLIST = 128
DEFAULT_IVF_PQ_M = 16

FIELD_ID: str = "id"
FIELD_VECTOR: str = "vector"
FIELD_METADATA: str = "metadata"

READ_CONSISTENCY = "read_consistency"
READ_STRONG_CONSISTENCY = "strongConsistency"
READ_EVENTUAL_CONSISTENCY = "eventualConsistency"
READ_CONSISTENCY_VALUES = "['strongConsistency', 'eventualConsistency']"

VALUE_NONE_ERROR = "Parameter `{}` can not be None."
VALUE_RANGE_ERROR = "The value of parameter `{}` must be within {}."
NOT_SUPPORT_INDEX_TYPE_ERROR = (
    "Unsupported index type: `{}`, supported index types are {}"
)
NOT_SUPPORT_METRIC_TYPE_ERROR = (
    "Unsupported metric type: `{}`, supported metric types are {}"
)

def _try_import() -> None:
    try:
        import tcvectordb  # noqa
    except ImportError:
        raise ImportError(
            "`tcvectordb` package not found, please run `pip install tcvectordb`"
        )

class FilterField:
    name: str
    data_type: str = "string"

    def __init__(self, name: str, data_type: str = "string"):
        self.name = name
        self.data_type = "string" if data_type is None else data_type

    def match_value(self, value: Any) -> bool:
        if self.data_type == "uint64":
            return isinstance(value, int)
        else:
            return isinstance(value, str)

    def to_vdb_filter(self) -> Any:
        from tcvectordb.model.enum import FieldType, IndexType
        from tcvectordb.model.index import FilterIndex

        return FilterIndex(
            name=self.name,
            field_type=FieldType(self.data_type),
            index_type=IndexType.FILTER,
        )

class CollectionParams:
    r"""Tencent vector DB Collection params.
    See the following documentation for details:
    https://cloud.tencent.com/document/product/1709/95826.

    Args:
        dimension int: The dimension of vector.
        shard int: The number of shards in the collection.
        replicas int: The number of replicas in the collection.
        index_type (Optional[str]): HNSW, IVF_FLAT, IVF_PQ, IVF_SQ8... Default value is "HNSW"
        metric_type (Optional[str]): L2, COSINE, IP. Default value is "COSINE"
        drop_exists (Optional[bool]): Delete the existing Collection. Default value is False.
        vector_params (Optional[Dict]):
          if HNSW set parameters: `M` and `efConstruction`, for example `{'M': 16, efConstruction: 200}`
          if IVF_FLAT or IVF_SQ8 set parameter: `nlist`
          if IVF_PQ set parameters: `M` and `nlist`
          default is HNSW
        filter_fields: Optional[List[FilterField]]: Set the fields for filtering
          for example: [FilterField(name='author'), FilterField(name='age', data_type=uint64)]
          This can be used when calling the query method：
             store.add([
                TextNode(..., metadata={'age'=23, 'name'='name1'})
            ])
             ...
             query = VectorStoreQuery(...)
             store.query(query, filter="age > 20 and age < 40 and name in (\"name1\", \"name2\")")
    """

    def __init__(
        self,
        dimension: int,
        collection_name: str = DEFAULT_COLLECTION_NAME,
        collection_description: str = DEFAULT_COLLECTION_DESC,
        shard: int = DEFAULT_SHARD,
        replicas: int = DEFAULT_REPLICAS,
        index_type: str = DEFAULT_INDEX_TYPE,
        metric_type: str = DEFAULT_METRIC_TYPE,
        drop_exists: Optional[bool] = False,
        vector_params: Optional[Dict] = None,
        filter_fields: Optional[List[FilterField]] = [],
    ):
        self.collection_name = collection_name
        self.collection_description = collection_description
        self.dimension = dimension
        self.shard = shard
        self.replicas = replicas
        self.index_type = index_type
        self.metric_type = metric_type
        self.vector_params = vector_params
        self.drop_exists = drop_exists
        self.filter_fields = filter_fields or []

class TencentVectorDB(VectorStore):
    """Tencent Vector Store.

    In this vector store, embeddings and docs are stored within a Collection.
    If the Collection does not exist, it will be automatically created.

    In order to use this you need to have a database instance.
    See the following documentation for details:
    https://cloud.tencent.com/document/product/1709/94951

    Args:
        url (Optional[str]): url of Tencent vector database
        username (Optional[str]): The username for Tencent vector database. Default value is "root"
        key (Optional[str]): The Api-Key for Tencent vector database
        collection_params (Optional[CollectionParams]): The collection parameters for vector database

    """

    stores_text: bool = True
    filter_fields: List[FilterField] = []

    def __init__(
        self,
        url: str,
        key: str,
        username: str = DEFAULT_USERNAME,
        database_name: str = DEFAULT_DATABASE_NAME,
        read_consistency: str = READ_EVENTUAL_CONSISTENCY,
        collection_params: CollectionParams = CollectionParams(dimension=1536),
        batch_size: int = 512,
        **kwargs: Any,
    ):
        """Init params."""
        self._init_client(url, username, key, read_consistency)
        self._create_database_if_not_exists(database_name)
        self._create_collection(database_name, collection_params)
        self._init_filter_fields()
        self.batch_size = batch_size

    def _init_filter_fields(self) -> None:
        fields = vars(self.collection).get("indexes", [])
        for field in fields:
            if field["fieldName"] not in [FIELD_ID, DEFAULT_DOC_ID_KEY, FIELD_VECTOR]:
                self.filter_fields.append(
                    FilterField(name=field["fieldName"], data_type=field["fieldType"])
                )

    @classmethod
    def class_name(cls) -> str:
        return "TencentVectorDB"

    @classmethod
    def from_params(
        cls,
        url: str,
        key: str,
        username: str = DEFAULT_USERNAME,
        database_name: str = DEFAULT_DATABASE_NAME,
        read_consistency: str = READ_EVENTUAL_CONSISTENCY,
        collection_params: CollectionParams = CollectionParams(dimension=1536),
        batch_size: int = 512,
        **kwargs: Any,
    ) -> "TencentVectorDB":
        _try_import()
        return cls(
            url=url,
            username=username,
            key=key,
            database_name=database_name,
            read_consistency=read_consistency,
            collection_params=collection_params,
            batch_size=batch_size,
            **kwargs,
        )

    def _init_client(
        self, url: str, username: str, key: str, read_consistency: str
    ) -> None:
        import tcvectordb
        from tcvectordb.model.enum import ReadConsistency

        if read_consistency is None:
            raise ValueError(VALUE_RANGE_ERROR.format(read_consistency))

        try:
            v_read_consistency = ReadConsistency(read_consistency)
        except ValueError:
            raise ValueError(
                VALUE_RANGE_ERROR.format(READ_CONSISTENCY, READ_CONSISTENCY_VALUES)
            )

        self.tencent_client = tcvectordb.VectorDBClient(
            url=url,
            username=username,
            key=key,
            read_consistency=v_read_consistency,
            timeout=DEFAULT_TIMEOUT,
        )

    def _create_database_if_not_exists(self, database_name: str) -> None:
        db_list = self.tencent_client.list_databases()

        if database_name in [db.database_name for db in db_list]:
            self.database = self.tencent_client.database(database_name)
        else:
            self.database = self.tencent_client.create_database(database_name)

    def _create_collection(
        self, database_name: str, collection_params: CollectionParams
    ) -> None:
        import tcvectordb

        collection_name: str = self._compute_collection_name(
            database_name, collection_params
        )
        collection_description = collection_params.collection_description

        if collection_params is None:
            raise ValueError(VALUE_NONE_ERROR.format("collection_params"))

        try:
            self.collection = self.database.describe_collection(collection_name)
            if collection_params.drop_exists:
                self.database.drop_collection(collection_name)
                self._create_collection_in_db(
                    collection_name, collection_description, collection_params
                )
        except tcvectordb.exceptions.VectorDBException:
            self._create_collection_in_db(
                collection_name, collection_description, collection_params
            )

    @staticmethod
    def _compute_collection_name(
        database_name: str, collection_params: CollectionParams
    ) -> str:
        if database_name == DEFAULT_DATABASE_NAME:
            return collection_params.collection_name
        if collection_params.collection_name != DEFAULT_COLLECTION_NAME:
            return collection_params.collection_name
        else:
            return database_name + "_" + DEFAULT_COLLECTION_NAME

    def _create_collection_in_db(
        self,
        collection_name: str,
        collection_description: str,
        collection_params: CollectionParams,
    ) -> None:
        from tcvectordb.model.enum import FieldType, IndexType
        from tcvectordb.model.index import FilterIndex, Index, VectorIndex

        index_type = self._get_index_type(collection_params.index_type)
        metric_type = self._get_metric_type(collection_params.metric_type)
        index_param = self._get_index_params(index_type, collection_params)
        index = Index(
            FilterIndex(
                name=FIELD_ID,
                field_type=FieldType.String,
                index_type=IndexType.PRIMARY_KEY,
            ),
            FilterIndex(
                name=DEFAULT_DOC_ID_KEY,
                field_type=FieldType.String,
                index_type=IndexType.FILTER,
            ),
            VectorIndex(
                name=FIELD_VECTOR,
                dimension=collection_params.dimension,
                index_type=index_type,
                metric_type=metric_type,
                params=index_param,
            ),
        )
        for field in collection_params.filter_fields:
            index.add(field.to_vdb_filter())

        self.collection = self.database.create_collection(
            name=collection_name,
            shard=collection_params.shard,
            replicas=collection_params.replicas,
            description=collection_description,
            index=index,
        )

    @staticmethod
    def _get_index_params(index_type: Any, collection_params: CollectionParams) -> None:
        from tcvectordb.model.enum import IndexType
        from tcvectordb.model.index import (
            HNSWParams,
            IVFFLATParams,
            IVFPQParams,
            IVFSQ4Params,
            IVFSQ8Params,
            IVFSQ16Params,
        )

        vector_params = (
            {}
            if collection_params.vector_params is None
            else collection_params.vector_params
        )

        if index_type == IndexType.HNSW:
            return HNSWParams(
                m=vector_params.get("M", DEFAULT_HNSW_M),
                efconstruction=vector_params.get("efConstruction", DEFAULT_HNSW_EF),
            )
        elif index_type == IndexType.IVF_FLAT:
            return IVFFLATParams(nlist=vector_params.get("nlist", DEFAULT_IVF_NLIST))
        elif index_type == IndexType.IVF_PQ:
            return IVFPQParams(
                m=vector_params.get("M", DEFAULT_IVF_PQ_M),
                nlist=vector_params.get("nlist", DEFAULT_IVF_NLIST),
            )
        elif index_type == IndexType.IVF_SQ4:
            return IVFSQ4Params(nlist=vector_params.get("nlist", DEFAULT_IVF_NLIST))
        elif index_type == IndexType.IVF_SQ8:
            return IVFSQ8Params(nlist=vector_params.get("nlist", DEFAULT_IVF_NLIST))
        elif index_type == IndexType.IVF_SQ16:
            return IVFSQ16Params(nlist=vector_params.get("nlist", DEFAULT_IVF_NLIST))
        return None

    @staticmethod
    def _get_index_type(index_type_value: str) -> Any:
        from tcvectordb.model.enum import IndexType

        index_type_value = index_type_value or IndexType.HNSW
        try:
            return IndexType(index_type_value)
        except ValueError:
            support_index_types = [d.value for d in IndexType.__members__.values()]
            raise ValueError(
                NOT_SUPPORT_INDEX_TYPE_ERROR.format(
                    index_type_value, support_index_types
                )
            )

    @staticmethod
    def _get_metric_type(metric_type_value: str) -> Any:
        from tcvectordb.model.enum import MetricType

        metric_type_value = metric_type_value or MetricType.COSINE
        try:
            return MetricType(metric_type_value.upper())
        except ValueError:
            support_metric_types = [d.value for d in MetricType.__members__.values()]
            raise ValueError(
                NOT_SUPPORT_METRIC_TYPE_ERROR.format(
                    metric_type_value, support_metric_types
                )
            )

    @property
    def client(self) -> Any:
        """Get client."""
        return self.tencent_client

    def add(
        self,
        nodes: List[BaseNode],
        **add_kwargs: Any,
    ) -> List[str]:
        """Add nodes to index.

        Args:
            nodes: List[BaseNode]: list of nodes with embeddings

        """
        from tcvectordb.model.document import Document

        ids = []
        entries = []
        for node in nodes:
            document = Document(id=node.node_id, vector=node.get_embedding())
            if node.ref_doc_id is not None:
                document.__dict__[DEFAULT_DOC_ID_KEY] = node.ref_doc_id
            if node.metadata is not None:
                document.__dict__[FIELD_METADATA] = json.dumps(node.metadata)
                for field in self.filter_fields:
                    v = node.metadata.get(field.name)
                    if field.match_value(v):
                        document.__dict__[field.name] = v
            if isinstance(node, TextNode) and node.text is not None:
                document.__dict__[DEFAULT_TEXT_KEY] = node.text

            entries.append(document)
            ids.append(node.node_id)

            if len(entries) >= self.batch_size:
                self.collection.upsert(
                    documents=entries, build_index=True, timeout=DEFAULT_TIMEOUT
                )
                entries = []

        if len(entries) > 0:
            self.collection.upsert(
                documents=entries, build_index=True, timeout=DEFAULT_TIMEOUT
            )

        return ids

    def delete(self, ref_doc_id: str, **delete_kwargs: Any) -> None:
        """
        Delete nodes using with ref_doc_id or ids.

        Args:
            ref_doc_id (str): The doc_id of the document to delete.

        """
        if ref_doc_id is None or len(ref_doc_id) == 0:
            return

        from tcvectordb.model.document import Filter

        delete_ids = ref_doc_id if isinstance(ref_doc_id, list) else [ref_doc_id]
        self.collection.delete(filter=Filter(Filter.In(DEFAULT_DOC_ID_KEY, delete_ids)))

    def query_by_ids(self, ids: List[str]) -> List[Dict]:
        return self.collection.query(document_ids=ids, limit=len(ids))

    def truncate(self) -> None:
        self.database.truncate_collection(self.collection.collection_name)

    def describe_collection(self) -> Any:
        return self.database.describe_collection(self.collection.collection_name)

    def query(self, query: VectorStoreQuery, **kwargs: Any) -> VectorStoreQueryResult:
        """Query index for top k most similar nodes.

        Args:
            query (VectorStoreQuery): contains
                query_embedding (List[float]): query embedding
                similarity_top_k (int): top k most similar nodes
                doc_ids (Optional[List[str]]): filter by doc_id
                filters (Optional[MetadataFilters]): filter result
            kwargs.filter (Optional[str|Filter]):

            if `kwargs` in kwargs:
               using filter: `age > 20 and author in (...) and ...`
            elif query.filters:
               using filter: " and ".join([f'{f.key} = "{f.value}"' for f in query.filters.filters])
            elif query.doc_ids:
               using filter: `doc_id in (query.doc_ids)`
        """
        search_filter = self._to_vdb_filter(query, **kwargs)
        results = self.collection.search(
            vectors=[query.query_embedding],
            limit=query.similarity_top_k,
            retrieve_vector=True,
            output_fields=query.output_fields,
            filter=search_filter,
        )
        if len(results) == 0:
            return VectorStoreQueryResult(nodes=[], similarities=[], ids=[])

        nodes = []
        similarities = []
        ids = []
        for doc in results[0]:
            ids.append(doc.get(FIELD_ID))
            similarities.append(doc.get("score"))

            meta_str = doc.get(FIELD_METADATA)
            meta = {} if meta_str is None else json.loads(meta_str)
            doc_id = doc.get(DEFAULT_DOC_ID_KEY)

            node = TextNode(
                id_=doc.get(FIELD_ID),
                text=doc.get(DEFAULT_TEXT_KEY),
                embedding=doc.get(FIELD_VECTOR),
                metadata=meta,
            )
            if doc_id is not None:
                node.relationships = {
                    NodeRelationship.SOURCE: RelatedNodeInfo(node_id=doc_id)
                }

            nodes.append(node)

        return VectorStoreQueryResult(nodes=nodes, similarities=similarities, ids=ids)

    @staticmethod
    def _to_vdb_filter(query: VectorStoreQuery, **kwargs: Any) -> Any:
        from tcvectordb.model.document import Filter

        search_filter = None
        if "filter" in kwargs:
            search_filter = kwargs.pop("filter")
            search_filter = (
                search_filter
                if type(search_filter) is Filter
                else Filter(search_filter)
            )
        elif query.filters is not None and len(query.filters.legacy_filters()) > 0:
            search_filter = " and ".join(
                [f'{f.key} = "{f.value}"' for f in query.filters.legacy_filters()]
            )
            search_filter = Filter(search_filter)
        elif query.doc_ids is not None:
            search_filter = Filter(Filter.In(DEFAULT_DOC_ID_KEY, query.doc_ids))

        return search_filter


import cv2
from matplotlib import pyplot as plt
import numpy as np

img = cv2.imread('flor.jpg')

img_orig = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, otsu_img = cv2.threshold(gray, 127, 255, cv2.THRESH_OTSU)
ret, trunc_img = cv2.threshold(gray, 127, 255, cv2.THRESH_TRUNC)
ret, zero_img = cv2.threshold(gray, 127, 255, cv2.THRESH_TOZERO)

plt.subplot(321),plt.imshow(gray, cmap="gray"),plt.title('Gray')
plt.xticks([]), plt.yticks([])
plt.subplot(322),plt.imshow(otsu_img, cmap="gray"),plt.title('Otsu tresholded')
plt.xticks([]), plt.yticks([])
plt.subplot(323),plt.imshow(trunc_img, cmap="gray"),plt.title('Trunc tresholded')
plt.xticks([]), plt.yticks([])
plt.subplot(324),plt.imshow(zero_img, cmap="gray"),plt.title('To zero tresholded')
plt.xticks([]), plt.yticks([])
plt.subplot(325),plt.imshow(img_orig),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.show()


import streamlit as st

from components.faq import faq

def set_huggingface_api_token(api_key: str):
    st.session_state["HF_API_TOKEN"] = api_key
    st.session_state["api_key_configured"] = True

def sidebar():
    with st.sidebar:
        st.markdown(
            "## How to use\n"
            "1. Enter your [ðŸ¤—HuggingFace API token](https://huggingface.co/settings/tokens) belowðŸ”‘\n"  # noqa: E501
            "2. Ask a question about the podcastsðŸ’¬\n"
        )
        api_key_input = st.text_input(
            "HuggingFace API Token",
            type="password",
            placeholder="Paste your HuggingFace API token here (hf_...)",
            help="You can get your API token from https://huggingface.co/settings/tokens.",  # noqa: E501
            value=st.session_state.get("HF_API_TOKEN", ""),
        )

        if api_key_input:
            set_huggingface_api_token(api_key_input)

        st.markdown("---")
        st.markdown("# About")
        st.markdown(
            ":snake: Explore Talk Python To Me allows you to ask questions about "
            "the wonderful podcasts hosted in [Talk Python To Me](https://talkpython.fm/episodes/all). "
        )
        st.markdown(
            "This tool is a work in progress. "
            "You can contribute to the project on [GitHub](https://github.com/plaguss/talking-python) "  # noqa: E501
            "with your feedback and suggestionsðŸ’¡"
        )
        st.markdown(
            "Made by [Agus](https://github.com/plaguss), thanks to [Michael Kennedy](https://talkpython.fm/)"
        )
        st.markdown("---")

        faq()


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

"""morse.morse: provides entry point main()."""

__version__ = "0.1.0"

import sys
import time
from pysinewave import SineWave

code = {
    "a": ".-",
    "b": "-...",
    "c": "-.-.",
    "d": "-..",
    "e": ".",
    "f": "..-.",
    "g": "--.",
    "h": "....",
    "i": "..",
    "j": ".---",
    "k": "-.-",
    "l": ".-..",
    "m": "--",
    "n": "-.",
    "o": "---",
    "p": ".--.",
    "q": "--.-",
    "r": ".-.",
    "s": "...",
    "t": "-",
    "u": "..-",
    "v": "...-",
    "w": ".--",
    "x": "-..-",
    "y": "-.--",
    "z": "--..",
    "0": "-----",
    "1": ".----",
    "2": "..---",
    "3": "...--",
    "4": "....-",
    "5": ".....",
    "6": "-....",
    "7": "--...",
    "8": "---..",
    "9": "----."
}

def beep(seconds):
    sinewave = SineWave(pitch=9) # 440 Hz / A
    sinewave.play()
    time.sleep(seconds)
    sinewave.stop()

def toMorse(word):
    converted = ""
    for letter in word:
        letter = str.lower(letter)
        if letter in code:
            morseLetter = code[letter]
            converted = converted + morseLetter + " "
            for char in morseLetter:
                print(char, end="", flush=True)
                if(char=="-"):
                    beep(0.5/velocity)
                else:
                    beep(0.25/velocity)
            time.sleep(0.5/velocity)
            print(" ", end="", flush=True)

def main():
    global velocity
    velocity = 1
    words = []

    for param in sys.argv[1:]:
        if(param=="--1x"):
            velocity = 1
        elif(param=="--2x"):
            velocity = 2
        elif(param=="--3x"):
            velocity = 3
        else:
            words.append(param)

    for word in words:
        toMorse(word)
        time.sleep(1/velocity)


import pytest
from assertpy import assert_that

from pcluster.api.models import GetClusterStackEventsResponseContent
from pcluster.cli.entrypoint import run
from pcluster.cli.exceptions import APIOperationException

class TestGetClusterStackEventsCommand:
    def test_helper(self, test_datadir, run_cli, assert_out_err):
        command = ["pcluster", "get-cluster-stack-events", "--help"]
        run_cli(command, expect_failure=False)

        assert_out_err(expected_out=(test_datadir / "pcluster-help.txt").read_text().strip(), expected_err="")

    @pytest.mark.parametrize(
        "args, error_message",
        [
            ([""], "error: the following arguments are required: -n/--cluster-name"),
            (["--cluster-name"], "error: argument -n/--cluster-name: expected one argument"),
            (["--cluster-name", "cluster", "--invalid"], "Invalid arguments ['--invalid']"),
            (
                ["--cluster-name", "cluster", "--region", "eu-west-"],
                "Bad Request: invalid or unsupported region 'eu-west-'",
            ),
        ],
    )
    def test_invalid_args(self, args, error_message, run_cli, capsys):
        command = ["pcluster", "get-cluster-stack-events"] + args
        run_cli(command, expect_failure=True)

        out, err = capsys.readouterr()
        assert_that(out + err).contains(error_message)

    def test_execute(self, mocker):
        response_dict = {
            "nextToken": "99/nexttoken",
            "events": [
                {
                    "eventId": "00000000-aaaa-1111-bbbb-000000000000",
                    "physicalResourceId": "arn:aws:cloudformation:eu-west-1:000000000000:stack/cluster/aa",
                    "resourceStatus": "UPDATE_COMPLETE",
                    "stackId": "arn:aws:cloudformation:eu-west-1:000000000000:stack/cluster/aaa",
                    "stackName": "cluster",
                    "logicalResourceId": "cluster",
                    "resourceType": "AWS::CloudFormation::Stack",
                    "timestamp": "2021-01-01T00:00:00.000Z",
                }
            ],
        }

        response = GetClusterStackEventsResponseContent().from_dict(response_dict)
        get_cluster_stack_events_mock = mocker.patch(
            "pcluster.api.controllers.cluster_logs_controller.get_cluster_stack_events",
            return_value=response,
            autospec=True,
        )

        out = run(["get-cluster-stack-events", "--cluster-name", "cluster"])
        assert_that(out).is_equal_to(response_dict)
        assert_that(get_cluster_stack_events_mock.call_args).is_length(2)  # this is due to the decorator
        expected_args = {"region": None, "cluster_name": "cluster", "next_token": None}
        get_cluster_stack_events_mock.assert_called_with(**expected_args)

    def test_error(self, mocker):
        api_response = {"message": "error"}, 400
        mocker.patch(
            "pcluster.api.controllers.cluster_logs_controller.get_cluster_stack_events",
            return_value=api_response,
            autospec=True,
        )

        with pytest.raises(APIOperationException) as exc_info:
            command = ["get-cluster-stack-events", "--region", "eu-west-1", "--cluster-name", "name"]
            run(command)
        assert_that(exc_info.value.data).is_equal_to(api_response[0])


from fastapi import File, UploadFile, APIRouter, Request, Depends
from fastapi.templating import Jinja2Templates
from fastapi.responses import RedirectResponse
from endpoints.jwt_auth import encode_auth_token, jwt_required_wrap, decode_auth_token
from fastapi_jwt_auth import AuthJWT
import json
import os
import random
from datetime import datetime as dt
router = APIRouter()
templates = Jinja2Templates(directory='templates')
class csv:
    def __init__(self, csv_name, date_uploaded, user_upload_by):
        self.csv_name =csv_name
        self.date_uploaded = date_uploaded
        self.user_upload_by = user_upload_by
@router.post('/upload_csv')
async def create_upload_file(request: Request, file : UploadFile = File(...)):
    file_id = random.randint(111111,999999)
    auth_cookie = request.cookies["access_token_cookie"]
    user = decode_auth_token(auth_cookie)

    if file.filename.endswith('.csv'):
        path = 'upload_files/' + str(file_id) + '.csv'
    else:
        return {"error":"file extension must be .csv"}
    with open(path, 'wb+') as f:
        f.write(file.file.read())
        f.close()

    json_path = 'db/user_uploads.json'

    with open(json_path, 'r') as f:
        current_data = json.loads(f.read())
        f.close()
    print(type(file.filename))
    try:
        users_data = current_data[user]
        current_data[user].append({"file":file.filename,"date":str(dt.utcnow()), "file_id":file_id})
    except Exception as e:
        print(e)
        current_data[user] = []
        current_data[user].append({"file":file.filename, "date":str(dt.utcnow()), "file_id":file_id})

    with open(json_path, 'w') as fp:
        print(type(current_data))
        json.dump(current_data, fp)
    return RedirectResponse('/my_csvs', status_code=303)

@router.get('/upload_csv')
async def get_upload_file(request: Request, Authorise: AuthJWT = Depends()):
    Authorise.jwt_required()
    user = Authorise.get_jwt_subject()
    return templates.TemplateResponse("upload_csv.html", {"request":request, "user":user})


import io

with open('000.jpg','rb') as inf:
    jpgdata = inf.read()

if jpgdata.startswith(b'\xff\xd8'):
    text = u'is JPEG(%d bytes long)\n'
else:
    text = u'is random(%d bytes long)\n'

with io.open('summary.txt','w',encoding='gbk') as  outf:
    outf.write(text %len(jpgdata))


from flask import Flask, make_response, render_template
import io
import csv

app = Flask(__name__)

import grpc
import report_pb2
import report_pb2_grpc
from google.protobuf.json_format import MessageToDict

def obj_to_dict(obj):
    return obj.__dict__

@app.route("/")
def index():
    try:
        data = get_covid_data_by_state()
        return render_template("index.html", data=data)

    except Exception as e:
        return e

@app.route("/download")
def download():

    try:
        data = get_covid_data_by_state()
        csv_data = covid_data_as_csv(data)
        si = io.StringIO()
        csv_writer = csv.writer(si)
        csv_writer.writerows(csv_data)
        output = make_response(si.getvalue())
        output.headers["Content-Disposition"] = "attachment; filename=us_covid_data.csv"
        output.headers["Content-type"] = "text/csv"
        return output

    except Exception as e:
        return e

def get_covid_data_by_state():
    try:
        channel = grpc.insecure_channel('localhost:3000')
        stub = report_pb2_grpc.ReportStub(channel)
        reportRequest = report_pb2.ReportRequest()
        reportResponse = stub.GetCovidDataForAllStates(reportRequest)

        return [MessageToDict(r) for r in reportResponse]

    except Exception as e:
        return e

def covid_data_as_csv(state_data_as_dicts):
    headers = state_data_as_dicts[0].keys()
    data = [s.values() for s in state_data_as_dicts]
    data.insert(0, headers)

    return data

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


from flask_jwt_extended import JWTManager
import redis

jwt = JWTManager()
jwt_redis_blocklist = redis.StrictRedis(
    host="localhost", port=6379, db=0, decode_responses=True
)

@jwt.token_in_blocklist_loader
def check_if_token_is_revoked(jwt_header, jwt_payload):
    jti = jwt_payload["jti"]
    token_in_redis = jwt_redis_blocklist.get(jti)
    return token_in_redis is not None


def solution(numbers):
    answer=''
    arr=[]
    for i in numbers:
        tmp=(str(i)*4)[:4]
        arr.append((i,tmp))
    arr=sorted(arr,key=lambda x:x[1],reverse=True)
    print(arr)
    for i in range(len(arr)):
        if i==0 and arr[i][0]==0:
            return '0'
        else: answer+=str(arr[i][0])
    return answer

print(solution([6,10,2]))
print(solution([3,30,34,5,9]))
print(solution([ 67,676,677]))
print(solution([0,0,0,0,0]))
print(solution([9,997,99,878,87]))
print(solution([1,10,100,1000]))

# 핵심 => numbers에 담긴 숫자를 각각 4번씩 반복한 수를 [:4]로 슬라이싱한다. => 0<=number<=1000이기 때문
# 첫번째 풀이때 numbers에 담긴 숫자를 key로 하고 슬라이싱한 수를 value로 하는 defaultdict(str)를 정렬 했으나 40점에 달했다
# 이유는 겹치는 숫자인 경우 같은 key에 list value로 저장하지 않고 str value로 저장했기 때문에 이전 키에 저장된 값이 삭제되기 때문이라고 생각하여
# 이에 두번째 풀이때는 tuple => (numbers,sliced nubmer) 형식으로 저장후 정렬하니 정답 처리가 되었다.


from __future__ import print_function, division, absolute_import

import sys
import threading
import time

from wukong import metrics
from wukong.compatibility import PY3
from wukong.utils_test import run_for

def test_wall_clock():
    for i in range(3):
        time.sleep(0.01)
        t = time.time()
        samples = [metrics.time() for j in range(50)]
        # Resolution
        deltas = [samples[j + 1] - samples[j] for j in range(len(samples) - 1)]
        assert min(deltas) >= 0.0, deltas
        assert max(deltas) <= 1.0, deltas
        assert any(lambda d: 0.0 < d < 0.0001 for d in deltas), deltas
        # Close to time.time()
        assert t - 0.5 < samples[0] < t + 0.5

def test_process_time():
    start = metrics.process_time()
    run_for(0.05)
    dt = metrics.process_time() - start
    assert 0.03 <= dt <= 0.2

    # All threads counted
    t = threading.Thread(target=run_for, args=(0.1,))
    start = metrics.process_time()
    t.start()
    t.join()
    dt = metrics.process_time() - start
    assert dt >= 0.05

    if PY3:
        # Sleep time not counted
        start = metrics.process_time()
        time.sleep(0.1)
        dt = metrics.process_time() - start
        assert dt <= 0.05

def test_thread_time():
    start = metrics.thread_time()
    run_for(0.05)
    dt = metrics.thread_time() - start
    assert 0.03 <= dt <= 0.2

    if PY3:
        # Sleep time not counted
        start = metrics.thread_time()
        time.sleep(0.1)
        dt = metrics.thread_time() - start
        assert dt <= 0.05

        if sys.platform == "linux":
            # Always per-thread on Linux
            t = threading.Thread(target=run_for, args=(0.1,))
            start = metrics.thread_time()
            t.start()
            t.join()
            dt = metrics.thread_time() - start
            assert dt <= 0.05


#!/usr/bin/env python3
from pathlib import Path

import acts
import acts.examples
from acts.examples.simulation import addParticleGun, addGeant4, EtaConfig
from acts.examples.odd import getOpenDataDetector
from common import getOpenDataDetectorDirectory

u = acts.UnitConstants

def runGeant4(
    detector,
    trackingGeometry,
    field,
    outputDir,
    s: acts.examples.Sequencer = None,
):
    s = s or acts.examples.Sequencer(events=100, numThreads=1)
    s.config.logLevel = acts.logging.INFO
    rnd = acts.examples.RandomNumbers()
    addParticleGun(
        s,
        EtaConfig(-2.0, 2.0),
        rnd=rnd,
    )
    outputDir = Path(outputDir)
    addGeant4(
        s,
        detector,
        trackingGeometry,
        field,
        outputDirCsv=outputDir / "csv",
        outputDirRoot=outputDir,
        rnd=rnd,
    )
    return s

if "__main__" == __name__:
    detector, trackingGeometry, decorators = getOpenDataDetector(
        getOpenDataDetectorDirectory()
    )

    field = acts.ConstantBField(acts.Vector3(0, 0, 2 * u.T))

    runGeant4(detector, trackingGeometry, field, Path.cwd()).run()


import random, time
from tkinter import *

def push(x):
    global turn
    global game
    global game_left
    game[x] = 'x'
    buttons[x].config(text='x', state="disabled")
    game_left.remove(x)
    if x == 4 and turn == 0:
        t = random.choice(game_left)
    elif x != 4 and turn == 0:
        t = 4
    if turn > 0:
        t = 8 - x
        if game[t] != None:
            t = random.choice(game_left)
        if (game[0] == game[2] != None) and (game[1] == None) :
            t = 1
        if (game[2] == game[8] != None) and (game[5] == None) :
            t = 5
        if (game[8] == game[6] != None) and (game[7] == None) :
            t = 7
        if (game[6] == game[0] != None) and (game[3] == None) :
            t = 3
    game[t] = 'o'
    time.sleep(0.3)
    buttons[t].config(text='o', state="disabled")
    game_left.remove(t)
    turn += 1

    if game[0] == game[1] == game[2] != None:
        Label(text=f'Победа {game[0]}', font=('Arial', 14, 'bold')).grid(row=0, column=0, columnspan=3)
    if game[3] == game[4] == game[5] != None:
        Label(text=f'Победа {game[3]}', font=('Arial', 14, 'bold')).grid(row=0, column=0, columnspan=3)
    if game[6] == game[7] == game[8] != None:
        Label(text=f'Победа {game[6]}', font=('Arial', 14, 'bold')).grid(row=0, column=0, columnspan=3)
    if game[0] == game[4] == game[8] != None:
        Label(text=f'Победа {game[0]}', font=('Arial', 14, 'bold')).grid(row=0, column=0, columnspan=3)
    if game[2] == game[4] == game[6] != None:
        Label(text=f'Победа {game[2]}', font=('Arial', 14, 'bold')).grid(row=0, column=0, columnspan=3)
    if game[0] == game[3] == game[6] != None:
        Label(text=f'Победа {game[0]}', font=('Arial', 14, 'bold')).grid(row=0, column=0, columnspan=3)
    if game[1] == game[4] == game[7] != None:
        Label(text=f'Победа {game[1]}', font=('Arial', 14, 'bold')).grid(row=0, column=0, columnspan=3)
    if game[2] == game[5] == game[8] != None:
        Label(text=f'Победа {game[2]}', font=('Arial', 14, 'bold')).grid(row=0, column=0, columnspan=3)

game = [None] * 9
game_left = list(range(9))
turn = 0
win = Tk()
win.title("X with O")
win.geometry("285x293+500+200")
win.resizable(False, False)
win.config(bg="#fff2e6")
label1 = Label(text='', font=('Arial', 14, 'bold')).grid(row=0, column=0, columnspan=3)

buttons = [Button(width=5, height=2, font=('Arial', 20, 'bold'), bg = '#cce0ff', command=lambda x=i: push(x)) for i in range(9)]

r = 1
c=0
for i in range(9):
    buttons[i].grid(row=r, column=c)
    c +=1
    if c == 3:
        r += 1
        c = 0

win.mainloop()


"""
Use the class given to calculate the area based on upon the shape. Start with making an object of Class Area and than Playing with it for different shapes.

Input Format:

shape and l,b or r depending upon the shape

Output Format:

area of the shape

Sample Input 0:

circle
4
Sample Output 0:

50
"""

import math
class Area:
    def rectangle(self,l,b):
        print(l*b)
    def circle(self,r):
        circle_area = math.pi*(r**2)
        circle_area_rounded = round(circle_area)
        print(circle_area_rounded)

shape = input()

if shape == "circle":
    r = int(input())
else:
    l,b = map(int,input().split())
# Write your code here
A = Area()
if shape == "circle":
	A.circle(r)
else:
	A.rectangle(l,b)


# -*- coding: utf-8 -*-
"""
Created on Thu Dec 04 17:16:27 2014

@author: lwasser
"""

#import libraries that Python needs to read shapefiles
import h5py
import numpy as np
import shapefile

#enter the directory that you wish to explore
#fileDirectory = (r'/Volumes/My Passport/D17_Data_2014_Distro/02_SJER/SJER_Spectrometer_Data/2013061320/Reflectance/')
#fileDirectory = (r'X:/All_data_distro/D17/SJER/2013/SJER_Spectrometer_Data/2013061320/Reflectance')
#fileDirectory = (r'F:/D17_Data_2014_Distro/02_SJER/SJER_Spectrometer_Data/2013061320/Reflectance/')
#windows version
fileDirectory = (r'F:/D17_Data_2014_Distro/02_SJER/SJER_Spectrometer_Data/2013061320/Reflectance/')

#get a list of all files in the directory
from os import listdir
from os.path import isfile, join
onlyfiles = [ f for f in listdir(fileDirectory) if isfile(join(fileDirectory,f)) ]

#Generate a list of the names of H5 files in the specified directory
onlyH5files=[]
for f in onlyfiles:
  if f.endswith(".h5"):
    onlyH5files.append(f)

#filePattern=join(fileDirectory, '*.h5')

#a better way to import a list of files
#import glob
#onlyH5files = glob.glob(filePattern)

#should be able to populate this ahead of time with Nan
#oop through all of the files in the directory, extract flightline bounds and resolution
#calculate extent in UTM
finalLookup=[]
#for f in onlyH5files:
    #iterate through all H5 files in the directory
for f in xrange(len(onlyH5files)):
    #open the file name to the directory path so the code knows where to find
    #the hdf5 file to open.
    filePath=join(fileDirectory,onlyH5files[f])
    #open hdf5 file
    file = h5py.File(filePath, 'r')   # 'r' means that hdf5 file is open in read-only mode

    #Select the reflectance dataset within the H5 file and associated needed attributes.
    reflectance=file['/Reflectance']
    CRS=file['/coordinate system string']
    mapInfo=['/map info']

    #Split map info string to extract raster corner location
    mapInfo=str(file['map info'][:]).split(',')
    eastingUL=float(mapInfo[3])
    northingUL=float(mapInfo[4])
    xsize=float(mapInfo[5])
    ysize=float(mapInfo[6])
    zone=int(mapInfo[7])

    #grab the shape of the reflectance matrix (the raster size)
    #Use this to define raster x,y,z extent (matrix dimensions)
    nb,nY,nX=reflectance.shape

    #find the extents of the hdf5 file
    yTop=northingUL
    yBot=northingUL-nY*ysize
    xLeft=eastingUL
    xRight=eastingUL+nX*xsize

    #find file centroid
    yCent=yBot+(nY/2)
    xCent=xLeft+(nX/2)

    #be sure to close the file
    file.close()

    #write out elements into a list
    fileExtents=[onlyH5files[f],yTop,yBot,xLeft,xRight,mapInfo,xCent,yCent]
    finalLookup.append(fileExtents)

#%reset clears all variables
print("All Files Inventoried - finalLookup Table Created!")

###########################################################################
# PART TWO -- Find flightlines for each plot
###########################################################################

#first get the plot coordinate

#plotBoundariesPath=(r'F:\ESA_WorkshopData\WorkingDirectory\Field_SHP_Use\SJERPlotCentroids_Buff_Square.shp')
#for mac
#plotBoundariesPath=(r'/Volumes/My Passport/ESA_WorkshopData/WorkingDirectory/Field_SHP_Use/SJERPlotCentroids_Buff_Square.shp')
plotBoundariesPath=(r'C:/Users/lwasser/Documents/GitHub/adventures-with-python/data/sjerPlots/SJERPlotCentroids_Buff_Square.shp')

sf = shapefile.Reader(plotBoundariesPath)
shapes = sf.shapes()

#read all of the fields in the shapefile
plotMetadata=sf.fields
records = sf.records()
#Create dictionary object that will store final data
#to access attribute data records[0][2:3]
plotIdDict={}

#loop through all plots, determine which fligthlines they fall wtihin the boundary of
#add the flightlines that fall wtihin the boundary of each plot to the dictionary
for j in xrange(len(shapes)):
    #get the coordinates of the plot boundary
    #bbox saves 4 corners as follows [left X, Lower Y, right X, Upper Y ]
    plotVertices=shapes[j].bbox
    #grab plot centroid coords
    plotCentroidX=float(records[j][3])
    plotCentroidY=float(records[j][2])

    #finalLookup order 1:Ytop 2:ybottom 3:xLeft  4:xRIGHT
    #loop through all flightlines - figure out which ones contain the plot boundary
    #if they create the boundary, then store that in the disctionary
    #plotID
    isInTemp=[]
    for i in xrange(len(finalLookup)):
        if ((plotVertices[0] > finalLookup[i][3]) and (plotVertices[2] < finalLookup[i][4])) and ((plotVertices[1] > finalLookup[i][2]) and (plotVertices[3] < finalLookup[i][1])):
            isInTemp.append([i,finalLookup[i][0],finalLookup[i][1],finalLookup[i][2],finalLookup[i][3],finalLookup[i][4]])
        plotIdDict[records[j][0]]=[isInTemp]

########################################################################
#plot things
########################################################################

import matplotlib
import matplotlib.pyplot as plt

onePlot=plotIdDict['SJER1068'][0]

#create the figure
fig = plt.figure()
ax = fig.add_subplot(111)

for i in xrange(len(onePlot)):
    print(i)
    xWidth=(onePlot[i][5]-onePlot[i][4])
    yHeight=(onePlot[i][2]-onePlot[i][3])
    locals()["rect"+str(i)] = matplotlib.patches.Rectangle((onePlot[i][4],onePlot[i][3]), xWidth, yHeight, fill=None, edgecolor='red')
    ax.add_patch(locals()["rect"+str(i)])
    #ax.add_patch(matplotlib.patches.Rectangle((onePlot[i][4],onePlot[i][2]), xWidth, yHeight, edgecolor='violet'))

###################
#dummy test code...
recCen=[[100,400],[140,450],[150,500]]
plotcent=[170,620]
dis=[]
for q in xrange(3):
	dis.append([abs(plotcent[0]-recCen[q][0]),abs(plotcent[1]-recCen[q][1])])

#############################
#use this code to sort out the smallest values...
dis=[[20, 1], [30, 5], [20, 120]]
min(dis, key=lambda item: (item[0], item[1]))

dis.index(min(dis, key=lambda item: (item[0], item[1])))
#############################

#add plot boundary
#bbox saves 4 corners as follows [left X, Lower Y, right X, Upper Y ]
plotVertices=shapes[0].bbox
plotBoundary = matplotlib.patches.Rectangle((plotVertices[0],plotVertices[1]), 40, 40, edgecolor='blue', facecolor='white')
ax.add_patch(plotBoundary)

plt.xlim([250000, 265000])
plt.ylim([4104000, 4115000])
plt.show()

fig = plt.figure()
ax = fig.add_subplot(111)
rect1 = matplotlib.patches.Rectangle((0,0), 200, 800, fill=None, edgecolor='red')
rect2 = matplotlib.patches.Rectangle((100,150), 180, 750, fill=None, edgecolor='green')
rect3 = matplotlib.patches.Rectangle((50,100), 200, 800, fill=None, edgecolor='violet')
plot = matplotlib.patches.Rectangle((150,600), 40, 40, color='blue')

#circle1 = matplotlib.patches.Circle((-200,-250), radius=90, color='#EB70AA')
ax.add_patch(rect1)
ax.add_patch(rect2)
ax.add_patch(rect3)
ax.add_patch(plot)

#ax.add_patch(circle1)
plt.xlim([-100, 1000])
plt.ylim([-100, 1000])
plt.show()


import pickle
import matplotlib.pyplot as plt
from src.image_classification.experiment import configuration, plot_results, get_best_configuration_per_k, plot_time_vs_accuracy

config = configuration()
resdir = f'{config["basepath"]}/results/image-classification/eval/'
savdir = f'{config["basepath"]}/results/image-classification/figs/'
savfig = True
mode = 'efficient'  # best, efficient
threshold = 0.05

fig1, axs1 = plt.subplots(4, 5, figsize=(12, 8))
fig2, axs2 = plt.subplots(4, 3, figsize=(7.2, 8))

for i, dataset in enumerate(config['datasets']):
    with open(f'{resdir}{dataset}.pickle', 'rb') as h:
        results = pickle.load(h)

    for j, k in enumerate(config['K']):
        times, accuracies, configs, duration, accuracy, best = get_best_configuration_per_k(results, k, mode, threshold)
        plot_time_vs_accuracy(
            dataset,
            k,
            times,
            accuracies,
            threshold,
            duration,
            accuracy,
            fig2,
            axs2[i, j],
            i == 0,
            i == len(config['datasets']) - 1,
            j == 0,
            i == 0 and j == 0
        )

    plot_results(dataset, results, 'model', config['models'], fig1, axs1[i, 0], x_bool=i == len(config['datasets']) - 1, y1_bool=True, y2_bool=False)
    plot_results(dataset, results, 'k', config['K'], fig1, axs1[i, 1], x_bool=i == len(config['datasets']) - 1, y1_bool=False, y2_bool=False)
    plot_results(dataset, results, 'iterations', config['iterations'], fig1, axs1[i, 2], x_bool=i == len(config['datasets']) - 1, y1_bool=False, y2_bool=False)
    plot_results(dataset, results, 'learning_rate', config['learning_rates'], fig1, axs1[i, 3], x_bool=i == len(config['datasets']) - 1, y1_bool=False, y2_bool=False)
    plot_results(dataset, results, 'batch_size', config['batch_sizes'], fig1, axs1[i, 4], x_bool=i == len(config['datasets']) - 1, y1_bool=False, y2_bool=True)

if savfig:
    fig1.savefig(f'{savdir}results.jpg')
    if mode == 'efficient':
        fig2.savefig(f'{savdir}time-vs-accuracy.jpg')