def make_half_bytes(byte_vec):
    """Преобразование списка байт в список полубайт LE

    Args:
        byte_vec (bytes): Список байт

    """
    half_bytes_vec = [0] * 16
    for i in range(8):
        half_bytes_vec[2 * i] = (byte_vec[i] & 0xf0) >> 4
        half_bytes_vec[2 * i + 1] = byte_vec[i] & 0xf
    return half_bytes_vec

class Craft:
    """Основной класс, реализующий шифрование сообщения в режиме ECB"""

    def __init__(self, key, tweak, message=bytes(1)):
        """Начальная инициализация векторов

        Args:
            key (list): Ключ шифрования/расшифрования
            tweak (list): tweak для генерации ключей
            message (bytes): Сообщение для шифрования/расшифрования

        """
        self.Q = [0xc, 0xa, 0xf, 0x5, 0xe, 0x8, 0x9, 0x2, 0xb, 0x3, 0x7, 0x4, 0x6, 0x0, 0x1, 0xd]
        self.P = [0xf, 0xc, 0xd, 0xe, 0xa, 0x9, 0x8, 0xb, 0x6, 0x5, 0x4, 0x7, 0x1, 0x2, 0x3, 0x0]
        self.S = [0xc, 0xa, 0xd, 0x3, 0xe, 0xb, 0xf, 0x7, 0x8, 0x9, 0x1, 0x5, 0x0, 0x2, 0x4, 0x6]
        self.RC4 = [0x1, 0x8, 0x4, 0x2, 0x9, 0xc, 0x6, 0xb, 0x5, 0xa, 0xd, 0xe, 0xf, 0x7, 0x3, 0x1, 0x8, 0x4, 0x2, 0x9,
                    0xc, 0x6, 0xb, 0x5, 0xa, 0xd, 0xe, 0xf, 0x7, 0x3, 0x1, 0x8]
        self.RC5 = [0x1, 0x4, 0x2, 0x5, 0x6, 0x7, 0x3, 0x1, 0x4, 0x2, 0x5, 0x6, 0x7, 0x3, 0x1, 0x4, 0x2, 0x5, 0x6, 0x7,
                    0x3, 0x1, 0x4, 0x2, 0x5, 0x6, 0x7, 0x3, 0x1, 0x4, 0x2, 0x5]
        self.blocks = []
        self.result_message = []
        self.message = message
        self.key = key
        self.tweak = tweak
        self.tweakey = [[0] * 16, [0] * 16, [0] * 16, [0] * 16]
        self.make_blocks()

    def __bytes__(self):
        if self.result_message:
            result = []
            for block in self.result_message:
                result.extend(bytes([(block[2 * i] << 4) | block[2 * i + 1] for i in range(len(block) // 2)]))
            return bytes(result)
        else:
            return None

    def __str__(self):
        if self.result_message:
            return str(self.__bytes__())

        else:
            return "Результат пока пустой"

    def check_message_len(self):
        """Проверяет длину сообщения на кратность 8 байтам

        Returns:
            bool: True если длина сообщения не кратна 8, False иначе
        """
        return 0 != len(self.message) % 8

    def add_padding(self):
        """Дополняет сообщение до длины, кратной 8"""
        self.message += b'\x80'
        while len(self.message) % 8 != 0:
            self.message += b'\x00'

    def make_blocks(self):
        """Разбивает сообщение на блоки по 64 бита (массив из 16 полубайт)"""
        if self.check_message_len():
            self.add_padding()

        for i in range(0, len(self.message), 8):
            block = make_half_bytes(self.message[i: i+8])
            self.blocks.append(block)

    def initialize_tweakey(self, decrypt=False):
        """Инициализация tweakey.

        Args:
            decrypt (:(bool, optional): Использовать преобразование для шифрования (False) или для расшифрования (True).
                По умолчанию - False

        """
        for i in range(16):
            self.tweakey[0][i] = self.key[0][i] ^ self.tweak[i]
            self.tweakey[1][i] = self.key[1][i] ^ self.tweak[i]
            self.tweakey[2][i] = self.key[0][i] ^ self.tweak[self.Q[i]]
            self.tweakey[3][i] = self.key[1][i] ^ self.tweak[self.Q[i]]

        if decrypt:
            for i in range(4):
                for j in range(4):
                    self.tweakey[i][j] ^= (self.tweakey[i][j + 8] ^ self.tweakey[i][j + 12])
                    self.tweakey[i][j + 4] ^= self.tweakey[i][j + 12]

    def mix_column(self, block):
        """Выполняет начальную перестановку в столбцах матрицы

        Args:
            block (list): Матрица текущего обрабатываемого блока, представленная в виде вектора

        Returns:
            list: Результат операции в виде вектора

        """
        for i in range(4):
            block[i] ^= (block[i + 8] ^ block[i + 12])
            block[i + 4] ^= block[i + 12]

        return block

    def add_constant(self, block, rnd):
        """Добавление раундовых констант

        Args:
            block (list): Матрица текущего обрабатываемого блока, представленная в виде вектора
            rnd (int): Номер текущего раунда

        Returns:
            list: Результат операции в виде вектора

        """
        block[4] ^= self.RC4[rnd]
        block[5] ^= self.RC5[rnd]
        return block

    def add_tweakey(self, block, rnd):
        """Замешивание ключа

        Args:
            block (list): Матрица текущего обрабатываемого блока, представленная в виде вектора
            rnd (int): Номер текущего раунда

        Returns:
            list: Результат операции в виде вектора

        """
        for i in range(16):
            block[i] ^= self.tweakey[rnd % 4][i]
        return block

    def make_permutation(self, block):
        """Перестановки внутри матрицы

        Args:
            block (list): Матрица текущего обрабатываемого блока, представленная в виде вектора

        Returns:
            list: Результат операции в виде вектора

        """
        permutated = [0] * 16
        for i in range(16):
            permutated[self.P[i]] = block[i]

        return permutated

    def do_s_box(self, block):
        """Осуществляет подстановку с помощью s_box

        Args:
            block (list): Матрица текущего обрабатываемого блока, представленная в виде вектора

        Returns:
            list: Результат операции в виде вектора

        """
        for i in range(16):
            block[i] = self.S[block[i]]
        return block

    def do_round(self, block, rnd, decrypt=False):
        """Выполняет один раунд шифрования/расшифрования

        Args:
            block (list): Матрица текущего обрабатываемого блока, представленная в виде вектора
            rnd (int): Номер текущего раунда
            decrypt(bool): Используется ли раунд для шифрования (False) или для расшифрования (True)

        Returns:
            list: Результат раунда

        """
        if decrypt:
            rnd = 31 - rnd
        block = self.mix_column(block)
        block = self.add_constant(block, rnd)
        block = self.add_tweakey(block, rnd)
        if rnd != 31 and not decrypt or rnd != 0 and decrypt:
            temporary = self.make_permutation(block)
            block = self.do_s_box(temporary)

        return block

    def encrypt(self):
        """Производит шифрование сообщения"""
        self.initialize_tweakey()
        for block in self.blocks:
            for i in range(32):
                block = self.do_round(block, i)
            self.result_message.append(block)

    def decrypt(self):
        """производит расшифрование сообщения"""
        self.initialize_tweakey(decrypt=True)
        for block in self.blocks:
            for i in range(32):
                block = self.do_round(block=block, rnd=i, decrypt=True)
            self.result_message.append(block)

if __name__ == '__main__':
    cypher = Craft(key=[[0x2, 0x7, 0xa, 0x6, 0x7, 0x8, 0x1, 0xa, 0x4, 0x3, 0xf, 0x3, 0x6, 0x4, 0xb, 0xc],
                        [0x9, 0x1, 0x6, 0x7, 0x0, 0x8, 0xd, 0x5, 0xf, 0xb, 0xb, 0x5, 0xa, 0xe, 0xf, 0xe]],
                   tweak=[0x5, 0x4, 0xc, 0xd, 0x9, 0x4, 0xf, 0xf, 0xd, 0x0, 0x6, 0x7, 0x0, 0xa, 0x5, 0x8],
                   message=b'Hello, letshbgvg')
    cypher.encrypt()
    print(cypher)

    decrypted = Craft(key=cypher.key, tweak=cypher.tweak, message=bytes(cypher))
    decrypted.decrypt()
    print(decrypted)


import copy
import os
import random
from collections import namedtuple, deque, Iterable

import numpy as np
import torch
import torch.nn.functional as F
import torch.optim as optim

from src.model import Dueling_DQN

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)

class DQNAgent:
	"""Interacts with and learns from the environment."""

	def __init__(self, args, action_space, bitmap_height, double_dqn=True):
		"""Initialize an Agent object.

		Params
		======
			state_size (int): dimension of each state
			action_space (int): dimension of each action
		"""
		self.args = args
		# self.state_size = state_size # used by the network, not the algorithm
		self.width = args.prediction_depth + 1 # Bitmap width
		self.height = bitmap_height # num altmaps (3) x max num rails
		self.action_space = action_space
		self.double_dqn = double_dqn
		# Q-Network
		self.qnetwork_local = Dueling_DQN(self.width, self.height, action_space).to(device)
		self.qnetwork_target = copy.deepcopy(self.qnetwork_local)

		self.optimizer = optim.Adam(self.qnetwork_local.parameters(), lr=self.args.lr)

		# Replay memory
		self.memory = ReplayBuffer(action_space, self.args.buffer_size, self.args.batch_size, self.width, self.height)
		# Initialize time step (for updating every UPDATE_EVERY steps)
		self.t_step = 0

	def save(self, filename):
		torch.save(self.qnetwork_local.state_dict(), filename + ".local")
		torch.save(self.qnetwork_target.state_dict(), filename + ".target")

	def load(self, filename):
		if os.path.exists(filename + ".local"):
			self.qnetwork_local.load_state_dict(torch.load(filename + ".local"))
		if os.path.exists(filename + ".target"):
			self.qnetwork_target.load_state_dict(torch.load(filename + ".target"))

	def step(self, state, action, reward, next_state, done, train=True):
		# Save experience in replay memory
		self.memory.add(state, action, reward, next_state, done)

		# Learn every UPDATE_EVERY time steps.
		# training is done taking a sample batch from the replay memory
		self.t_step = (self.t_step + 1) % self.args.update_every # TODO Meglio farla ad eps?
		if self.t_step == 0:
			# If enough samples are available in memory, get random subset and learn
			if len(self.memory) > self.args.batch_size:
				experiences = self.memory.sample()
				if train:
					self.learn(experiences, self.args.gamma)

	def act(self, state, eps=0.):
		"""Returns actions for given state as per current policy.

		Params
		======
			state (array_like): current state
			eps (float): epsilon, for epsilon-greedy action selection
		"""
		state = torch.from_numpy(state).float().unsqueeze(0).unsqueeze(0).to(device)
		self.qnetwork_local.eval()
		with torch.no_grad():
			action_values = self.qnetwork_local(state) # Compute Q values
		self.qnetwork_local.train()  # Set PyTorch module in training mode

		return action_values[0]

	def learn(self, experiences, gamma):

		"""Update value parameters using given batch of experience tuples.

		Params
		======
			experiences (Tuple[torch.Tensor]): tuple of (s, a, r, s', done) tuples
			gamma (float): discount factor
		"""
		states, actions, rewards, next_states, dones = experiences		# batch_size experiences

		# Get expected Q values from local model
		Q_expected = self.qnetwork_local(states).gather(1, actions.unsqueeze(-1)).view(self.args.batch_size)

		if self.double_dqn:
			# Double DQN
			q_best_action = self.qnetwork_local(next_states).max(1)[1] # shape (512)
			Q_targets_next = self.qnetwork_target(next_states).gather(1, q_best_action.unsqueeze(-1)).view(self.args.batch_size) # (512, 1)
		else:
			# DQN
			Q_targets_next = self.qnetwork_target(next_states).detach().max(1)[0].unsqueeze(-1)

		# Compute Q targets for current states
		Q_targets = rewards + (gamma * Q_targets_next * (1 - dones))

		# Compute loss
		loss = F.mse_loss(Q_expected, Q_targets)
		# Minimize the loss
		self.optimizer.zero_grad()
		loss.backward()
		self.optimizer.step()

		# ------------------- Update target network ------------------- #
		self.soft_update(self.qnetwork_local, self.qnetwork_target, self.args.tau)

	def soft_update(self, local_model, target_model, tau):
		"""Soft update model parameters.
		θ_target = τ*θ_local + (1 - τ)*θ_target

		Params
		======
			local_model (PyTorch model): weights will be copied from
			target_model (PyTorch model): weights will be copied to
			tau (float): interpolation parameter
		"""
		for target_param, local_param in zip(target_model.parameters(), local_model.parameters()):
			target_param.data.copy_(tau * local_param.data + (1.0 - tau) * target_param.data)

class ReplayBuffer:
	"""Fixed-size buffer to store experience tuples."""

	def __init__(self, action_space, buffer_size, batch_size, width, height):
		"""Initialize a ReplayBuffer object.

		Params
		======
			action_space (int): dimension of each action
			buffer_size (int): maximum size of buffer
			batch_size (int): size of each training batch
		"""
		self.action_space = action_space
		self.memory = deque(maxlen=buffer_size)
		self.batch_size = batch_size
		self.width = width
		self.height = height
		self.experience = namedtuple("Experience", field_names=["state", "action", "reward", "next_state", "done"])

	def add(self, state, action, reward, next_state, done):
		"""Add a new experience to memory."""
		# expand_dims adds one dimension along axis 0 for PyTorch
		e = self.experience(np.expand_dims(state, 0), action, reward, np.expand_dims(next_state, 0), done)
		self.memory.append(e)

	def sample(self):
		"""Randomly sample a batch of experiences from memory."""
		experiences = random.sample(self.memory, k=self.batch_size)

		states = torch.from_numpy(self.__v_stack_impr([e.state for e in experiences if e is not None])) \
			.float().to(device)
		actions = torch.from_numpy(self.__v_stack_impr([e.action for e in experiences if e is not None])) \
			.long().to(device)
		rewards = torch.from_numpy(self.__v_stack_impr([e.reward for e in experiences if e is not None])) \
			.float().to(device)
		next_states = torch.from_numpy(self.__v_stack_impr([e.next_state for e in experiences if e is not None])) \
			.float().to(device)
		dones = torch.from_numpy(self.__v_stack_impr([e.done for e in experiences if e is not None]).astype(np.uint8)) \
			.float().to(device)

		return states, actions, rewards, next_states, dones

	def __len__(self):
		"""Return the current size of internal memory."""
		return len(self.memory)

	# This same function is used for states, actions, rewards etc, so the parameter 'states' doesn't contain states all the time
	# and for this reason has different shapes
	def __v_stack_impr(self, states):
		"""

		:param states: a list of states (or actions/rewards/dones), len = self.batch_size
		:return:
		"""
		if isinstance(states[0], Iterable): # States, next_states
			# Debug shapes
			#for i in range(len(states)):
			#	print(states[i].shape)
			# States and next_states
			np_states = np.array(states) # (512, 1, 400, 101)
			np_states = np.reshape(np_states, (len(states), 1, self.height, self.width))
		else: # Actions, rewards, dones
			np_states = np.reshape(np.array(states), (len(states))) # (512, )

		return np_states


import requests
from bs4 import BeautifulSoup
from time import sleep
from csv import DictWriter
base_url = r'https://movie.douban.com/top250'
records = []
for start in [x*25 for x in range(10)]:
    #Every single page
    url = base_url+f'?start={start}&filter='
    response = requests.get(url).text
    soup = BeautifulSoup(response,'html.parser')
    movies = soup.find(class_='grid_view').find_all('li')
    rank=1+start
    for movie in movies:
        #Every single movie on the page
        movie_link = movie.find(class_='info').find(class_='hd').find('a')['href']
        movie_dict = {'rank':rank, 'link':movie_link}
        records.append(movie_dict)
        rank += 1
#Use the scapped link to further scrape movie details
for record in records:
    rank = record.get('rank')
    print(f'Scarpping rank {rank} of 250')
    link = record.get('link')
    response = requests.get(link).text
    soup = BeautifulSoup(response,'html.parser')
    record['title'] = soup.find('h1').find('span').get_text()
    record['year'] = soup.find('h1').find(class_='year').get_text()[1:5]
    record['director'] = soup.find(id='info').find(class_='attrs').find('a').get_text()
    record['length'] = soup.find(id='info').find(property='v:runtime').get_text()[:-2]

    attrs = soup.find(id='info').find_all(class_='pl')
    for attr in attrs:
        if attr.get_text().startswith('制片国家'):
            record['country_region']=attr.nextSibling.strip()
        elif attr.get_text().startswith('语言'):
            record['language']=attr.nextSibling.strip()

    record['avg_rating'] = soup.find(class_='ll rating_num').get_text()
    record['num_of_ratings'] = soup.find(class_='rating_people').find('span').get_text()
    interests = soup.find(class_='subject-others-interests-ft').find_all('a')
    record['people_watched'] = interests[0].get_text()[:-3]
    record['people_wants_to_watch'] = interests[1].get_text()[:-3]
    record['num_comment'] = soup.find(id='comments-section').find('h2').find('a').get_text().split()[1]
    record['num_reviews'] = soup.find(class_='reviews mod movie-content').find('h2').find('a').get_text().split()[1]
    #Set scrapping interval in case of ip blocking
    sleep(5)
#Write the 250 movies into a csv file
with open('douban_top_250.csv','w', newline='', encoding='utf-8-sig') as file:
    headers = [key for key in records[0].keys()]
    csv_writer = DictWriter(file, fieldnames=headers)
    csv_writer.writeheader()
    for record in records:
        csv_writer.writerow(record)


# preparation:
# 1) please put the source csv file and this python file in the same folder
# 2) please change the source csv file name as source.csv
# 3) please install python 3 in advance
# 4) please install pandas in advance, run the command line: pip3 install pandas
# 5) please install hashlib in advance, run the command line: pip3 install hashlib
# 6) please run the python in the command line: python3 transform_emailsha256_in_csv.py

import pandas as pd
import hashlib

# The csv file need to transform from email to emailsha256
# the csv file must contain at least two columns: customuid and emailsha256
# in the emailsha256 field, the content is the customers' original email addresses
source_file_name = "source.csv"

# result csv file name as
result_file_name = "result.csv"

# emailsha256 converter
def convert_to_emailsha256(email):
    if not email:
        return email
    else:
        return hashlib.sha256(email.strip().lower().encode('utf-8')).hexdigest()

# read csv to convert
df = pd.read_csv(source_file_name, converters={'emailsha256': convert_to_emailsha256})
df.to_csv(result_file_name, index=False)
print("Converted email to emailsha256")


import os
from traemplist.logger import StandardOutputLogger
from traemplist.config import JsonConfig
from traemplist.client import SpotifyClient, SpotifyAccessTokenProvider, AccountCredentialsConfig
from traemplist.generator import TraemplistGenerator
from traemplist.repository import SqLiteTracksRepository
from traemplist.service import TraemplistGeneratorService

this_dir_path = os.path.dirname(os.path.abspath(__file__))
logger = StandardOutputLogger()
config = JsonConfig(f"{this_dir_path}/config.json")

for traemplist_config in config.get_traemplist_configs():
    account_credentials = traemplist_config.account.credentials
    spotify_client = SpotifyClient(
        access_token_provider=SpotifyAccessTokenProvider(
            AccountCredentialsConfig(
                client_id=account_credentials.client_id,
                client_secret=account_credentials.client_secret,
                refresh_token=account_credentials.refresh_token
            )
        )
    )
    TraemplistGeneratorService(
        config=traemplist_config,
        client=spotify_client,
        generator=TraemplistGenerator(
            client=spotify_client,
            history=SqLiteTracksRepository(
                f"{this_dir_path}/storage/{account_credentials.client_id}_tracks.db"
            ),
            logger=logger
        ),
        logger=logger
    ).generate_and_save_traemplist()


N = int(input())
P = list(map(int, input().split()))

ans = [0] * N
s = set()

for i in range(N):
    s.add(P[i])
    if i == 0:
        if P[0] == 0:
            ans[0] = 1
        else:
            ans[0] = 0
        print(ans[0])
    else:
        if P[i] == ans[i - 1]:
            j = 1
            while ans[i - 1] + j in s:
                j += 1
            ans[i] = ans[i - 1] + j
        else:
            ans[i] = ans[i - 1]
        print(ans[i])


import numpy as np
import pandas as pd
data=pd.read_csv('finds.csv')
concepts = np.array(data)[:, 0:-1]
target = np.array(data)[:, -1]

def learn(concepts, target):
    #initialize Specific and General Hypothesis
    specific_h = concepts[0].copy()
    general_h = [["?" for i in range(len(specific_h))]
                 for i in range(len(specific_h))]

    for i, h in enumerate(concepts):
        if target[i] == "Yes":
            for x in range(len(specific_h)):
                if h[x] != specific_h[x]:
                    specific_h[x] = '?'
                    general_h[x][x] = '?'
        if target[i] == "No":
            for x in range(len(specific_h)):
                if h[x] != specific_h[x]:
                    general_h[x][x] = specific_h[x]
                else:
                    general_h[x][x] = '?'

        print("Iteration[" + str(i+1) + "]")
        print("Specific: " + str(specific_h))
        print("General: " + str(general_h) + "\n")

    #Trimming general_h by Removing completely generalized list
    general_h=[general_h[i] for i, h in enumerate(general_h) if h!= ['?' for x in range(len(specific_h))]]
    return specific_h,general_h

specific,general=learn(concepts,target)

print("Final Hypothesis: ")
print("Specific hypothesis: " + str(specific))
print("General hypothesis: " + str(general))


from ply.lex import lex

states = (
    ('slash', 'exclusive'),
    ('paren', 'exclusive'),
)
tokens = (
    'NAME',
    'TIMES',
    'NUMBER'
)

t_NAME = r'[a-zA-Z]'
# t_ignore_COMMENT =r'[/]{1}[*]{1}[a-zA-Z0-9()*/ \n]*[*]{1}[/]{1}|[(]{1}[*]{1}[a-zA-Z0-9*/() \n]*[*]{1}[)]{1}'
t_ignore = ' '

def t_NUMBER(t):
    r'\d'
    t.value = int(t.value)
    return t

def t_ignore_newline(t):
    r'\n+'

    t.lexer.lineno += len(t.value)

def t_slash(t):
    r'[/]{1}[*]{1}'
    t.lexer.push_state('slash')

def t_paren(t):
    r'[(]{1}[*]{1}'
    t.lexer.push_state('paren')

def t_slash_again(t):
    r'[/]{1}[*]{1}'
    t.lexer.push_state('slash')

def t_slash_parenagain(t):
    r'[(]{1}[*]{1}'
    t.lexer.push_state('paren')

def t_slash_close(t):
    r'[*]{1}[/]{1}'
    if (t.lexer.current_state() == 'slash'):
        t.lexer.pop_state()
    else:
        exit('error')

def t_slash_middle(t):
    r'[a-zA-Z0-9 \n]'
    pass

# <===========================================================>
def t_paren_again(t):
    r'[(]{1}[*]{1}'
    t.lexer.push_state('paren')

def t_paren_slashagain(t):
    r'[/]{1}[*]{1}'
    t.lexer.push_state('slash')

def t_paren_close(t):
    r'[*]{1}[)]{1}'
    if (t.lexer.current_state() == 'paren'):
        t.lexer.pop_state()
    else:
        exit('error')

def t_paren_middle(t):
    r'[a-zA-Z0-9 \n]'
    pass

# Error handling rule
def t_error(t):
    print("Illegal character '%s'" % t.value[0])
    t.lexer.skip(1)

# Build the lexer
lexer = lex()

data = '''(* comment in /*dep
th*/*) eyo whatsup

 (*bye*) sa'''
lexer.input(data)
# Tokenize
while True:
    tok = lexer.token()
    if not tok:
        break  # No more input
    print(tok)


import matplotlib.pyplot as plt
import seaborn as sns
sns.set_palette("Set2")
from sklearn.metrics.pairwise import cosine_similarity

def get_feature_vector(song_name, year, dat, features_list):
    print(dat.head())
    # select dat with the song name and year
    dat_song = dat.query('name == @song_name and year == @year')
    song_repeated = 0
    if len(dat_song) == 0:
        raise Exception('The song does not exist in the dataset or the year is wrong! \
                        \n Use search function first if you are not sure.')
    if len(dat_song) > 1:
        song_repeated = dat_song.shape[0]
        print(f'Warning: Multiple ({song_repeated}) songs with the same name and artist, the first one is selected!')
        dat_song = dat_song.head(1)
    feature_vector = dat_song[features_list].values
    return feature_vector, song_repeated

# define a function to get the most similar songs
import pandas as pd
import urllib.parse
import matplotlib.pyplot as plt
import seaborn as sns

def show_similar_songs(song_name, year, dat, features_list, top_n=10):
    """
    A function to get the most similar songs based on the cosine similarity of the features.
    :param song_name: the name of the song (all letters)
    :param year: the year of the song [int]
    :param dat: the dataset
    :param features_list: the list of features to be used for similarity calculation
    :param top_n: the number of similar songs to be returned
    :return: DataFrame containing the most similar songs or an empty DataFrame if no similar songs are found
    """
    feature_vector, song_repeated = get_feature_vector(song_name, year, dat, features_list)
    feature_for_recommendation = dat[features_list].values
    # calculate the cosine similarity
    similarities = cosine_similarity(feature_for_recommendation, feature_vector).flatten()

    # get the index of the top_n similar songs not including itself
    if song_repeated == 0:
        related_song_indices = similarities.argsort()[-(top_n+1):][::-1][1:]
    else:
        related_song_indices = similarities.argsort()[-(top_n+1+song_repeated):][::-1][1+song_repeated:]

    # get the name, artist, and year of the most similar songs
    similar_songs = dat.iloc[related_song_indices][['name', 'artists', 'year']]
    similar_songs['Similarity'] = similarities[related_song_indices]
    # Add the Spotify link column
    # base_url = 'https://open.spotify.com/search/'
    # encoded_songs = similar_songs['name'].apply(lambda x: urllib.parse.quote(x))
    # encoded_artists = similar_songs['artists'].apply(lambda x: urllib.parse.quote(x))
    # spotify_links = base_url + encoded_songs + ' ' + encoded_artists

    # # Create the 'Click' column with clickable links
    # similar_songs['Click'] = spotify_links.apply(lambda x: f"[Click]({x})")

    # Update the column name to 'Click' for all songs
    # similar_songs.rename(columns={'Spotify Link': 'Click'}, inplace=True)

    similar_songs.reset_index(drop=True, inplace=True)

    return similar_songs


# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
        def dfs(stop):
            if preorder and inorder[-1] != stop:
                root = TreeNode(preorder.pop())
                root.left = dfs(root.val)
                inorder.pop()
                root.right = dfs(stop)
                return root
        preorder.reverse()
        inorder.reverse()
        return dfs(None)


from VGGnet.vgg16 import Vgg16
from imageio import imread
import tensorflow as tf
import numpy as np

import matplotlib.pyplot as plt

from deepIQA_evaluate import IQA

def EN(inputs):
	len = inputs.shape[0]
	entropies = np.zeros(shape = (len, 1))
	grey_level = 256
	patch_size = 64
	counter = np.zeros(shape = (grey_level, 1))

	for i in range(len):
		input_uint8 = (inputs[i, :, :, 0] * 255).astype(np.uint8)
		input_uint8 = input_uint8 + 1
		for m in range(patch_size):
			for n in range(patch_size):
				indexx = input_uint8[m, n]
				counter[indexx] = counter[indexx] + 1
		total = np.sum(counter)
		p = counter / total
		for k in range(grey_level):
			if p[k] != 0:
				entropies[i] = entropies[i] - p[k] * np.log2(p[k])
	return entropies

num_1 = 32
num_2 = 33
for idx in range(num_1, num_2):
	img1 = imread('Test_vi_low/%d.bmp' % idx)
	img2 = imread('Test_ir_low/%d.bmp' % idx)
	img3 = imread('Test_vi_low/%d.bmp' % idx)
	img4 = imread('Test_ir_low/%d.bmp' % idx)
	img5 = imread('Test_vi_high/%d.bmp' % idx)
	Shape1=img1.shape
	h1 = Shape1[0]
	w1 = Shape1[1]
	Shape2 = img2.shape
	h2 = Shape2[0]
	w2 = Shape2[1]
	assert (h1 == h2 and w1 == w2), 'Two images must have the same shape!'
	print('input shape:', img1.shape)
	img1 = img1.reshape([1, h1, w1, 1])
	img2 = img2.reshape([1, h1, w1, 1])

def W(inputs1,inputs2, trained_model_path, w_en, c):
	# with tf.device('/gpu:1'):
	iqa1 = IQA(inputs = inputs1, trained_model_path = trained_model_path)
	iqa2 = IQA(inputs = inputs2, trained_model_path = trained_model_path)
	with tf.device('/cpu:0'):
		en1 = EN(inputs1)
		en2 = EN(inputs2)
		score1 = w_en *iqa1 +  en1
		score2 = w_en *iqa2 +  en2
		w1 = np.exp(score1 / c) / (np.exp(score1 / c) + np.exp(score2 / c))
		w2 = np.exp(score2 / c) / (np.exp(score1 / c) + np.exp(score2 / c))
		print('IQA_1: %f, IQA_2: %f' % (iqa1[0], iqa2[0]))
		print('EN_1: %f, EN_2: %f' % (en1[0], en2[0]))
		print('score_1: %f, score_2: %f' % (score1, score2))
		print('w1: %s, w2: %s\n' % (w1[0], w2[0]))
	return (w1,w2)

IQA_model = './IQA/models/nr_tid_weighted.model'
w_en=2
c=30

valid_w1, valid_w2 = W(inputs1 = img1, inputs2 = img2, trained_model_path = IQA_model,w_en=w_en,c=c)
print('valid_w1: %s, valid_w2: %s\n' % (valid_w1, valid_w2))

fig = plt.figure()
fig1 = fig.add_subplot(221)
fig2 = fig.add_subplot(222)
fig3 = fig.add_subplot(223)
fig4 = fig.add_subplot(224)
fig1.imshow(img1[0, :, :, 0], cmap = 'gray')
fig2.imshow(img2[0, :, :, 0], cmap = 'gray')

fused_low=valid_w1*img3+valid_w2*img4
fig3.imshow(fused_low,cmap='gray')
fused=fused_low+img5
fig4.imshow(fused,cmap='gray')
plt.show()


from typing import Any, Dict, Type, TypeVar, Tuple, Optional, BinaryIO, TextIO, TYPE_CHECKING

from typing import List

import attr

from ..types import UNSET, Unset

from ..types import UNSET, Unset
from typing import Union

T = TypeVar("T", bound="NotFound")

@attr.s(auto_attribs=True)
class NotFound:
    """
        Attributes:
            message (str):
            path (Union[Unset, str]):
     """

    message: str
    path: Union[Unset, str] = UNSET
    additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict)

    def to_dict(self) -> Dict[str, Any]:
        message = self.message
        path = self.path

        field_dict: Dict[str, Any] = {}
        field_dict.update(self.additional_properties)
        field_dict.update({
            "message": message,
        })
        if path is not UNSET:
            field_dict["path"] = path

        return field_dict

    @classmethod
    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
        d = src_dict.copy()
        message = d.pop("message")

        path = d.pop("path", UNSET)

        not_found = cls(
            message=message,
            path=path,
        )

        not_found.additional_properties = d
        return not_found

    @property
    def additional_keys(self) -> List[str]:
        return list(self.additional_properties.keys())

    def __getitem__(self, key: str) -> Any:
        return self.additional_properties[key]

    def __setitem__(self, key: str, value: Any) -> None:
        self.additional_properties[key] = value

    def __delitem__(self, key: str) -> None:
        del self.additional_properties[key]

    def __contains__(self, key: str) -> bool:
        return key in self.additional_properties


import pandas as pd
import numpy as np
import pickle
import matplotlib.pyplot as plt
import statsmodels.api as sm
from statsmodels.stats.outliers_influence import variance_inflation_factor
from sklearn.preprocessing import StandardScaler, MinMaxScaler
import pickle
from sklearn.metrics.pairwise import euclidean_distances
from song_clustering import run_optimal_kmeans,standardize,run_pca

def plot_vif(features):
    X = features.copy()
    X.drop(columns=['id','labels'],inplace=True)
    vif = pd.DataFrame()
    vif["VIF_Factor"] = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]
    vif["features"] = X.columns
    plt.bar(vif["features"],vif['VIF_Factor'])
    plt.ylabel('VIF')
    plt.title('Variable Inflation Factor Test on Full Popular Data Set')
    plt.xticks(rotation=85)
    plt.tight_layout()
    plt.show()

def plot_histogram_discrete(df,feature):
    plt.hist(df[feature])
    plt.show()

#plot_vif(AF_with_id)
#plot_histogram_discrete(AF_with_id,'time_signature')
#plot_histogram_discrete(AF_with_id,'mode')

#Audio features matrix data with labels
with open('../data/AF_with_id.pkl','rb') as f2:
    AF_with_id = pickle.load(f2)

#Track info matrix with labels
with open('../data/track_info.pkl','rb') as f3:
    track_info = pickle.load(f3)

#Calulate feature averages by cluster & check cluster similarities
AF = AF_with_id.copy()
AF = AF.drop(columns=['id'])
grouped = AF.groupby(['labels']).mean()
grouped_copy = grouped.copy()
scaler = MinMaxScaler(feature_range=(0,1))
scaled = scaler.fit_transform(grouped_copy)

similarity = euclidean_distances(grouped,grouped) #cluster 5 & 7 have largest ED

c1 = 5
c2 = 7
cluster1_means = scaled[c1,:]
cluster2_means = scaled[c2,:]

x = np.arange(len(cluster1_means))
X_cols = grouped.columns
w = 0.5
fig = plt.figure(figsize=(10,6))
ax = fig.add_subplot(111)
p1 = ax.bar(x,cluster1_means,w,color='red')
p2 = ax.bar(x+w,cluster2_means,w,color='blue')
ax.set_xlabel('Audio Features',fontsize=12)
ax.set_ylabel('Cluster Averages',fontsize=12)
ax.set_title('Normalized Feature Averages For Two Distant Clusters')
ax.legend((p1[0], p2[0]), ('Cluster 6', 'Cluster 8'))
plt.axhline(0, color='blue')
ax.set_xticks(x)
ax.set_xticklabels(X_cols)
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

#Plot min and max of each AF for all songs in top 20% of popularity
high_pop_thresh = (AF_with_id['popularity'].max())*0.8
high_pop = AF_with_id[AF_with_id['popularity']>high_pop_thresh]
high_pop = AF_with_id.copy()
high_pop.drop(columns=['id','labels'],inplace=True)
std = standardize(high_pop)
std_df = pd.DataFrame(std,columns=high_pop.columns)
mins = np.array(std_df.min())
maxs = np.array(std_df.max())

x = np.arange(len(mins))
X_cols = high_pop.columns
w = 0.5
fig = plt.figure(figsize=(10,6))
ax = fig.add_subplot(111)
p1 = ax.bar(x,mins,w,color='red')
p2 = ax.bar(x,maxs,w,color='blue')
ax.set_xlabel('Audio Features',fontsize=12)
ax.set_ylabel('Scaled Value Range',fontsize=12)
ax.set_title("Feature Value Range of Scaled Audio Features For All Songs")
ax.legend((p1[0], p2[0]), ('Min', 'Max'))
plt.axhline(0, color='blue')
ax.set_xticks(x)
ax.set_xticklabels(X_cols)
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

#


from pathlib import Path
import re
import json
from flask import Blueprint, render_template, request, abort, make_response

from ..templates import template_root
from ..workspace import get_workspaces

workspace = Blueprint("workspace", __name__, template_folder=template_root)

@workspace.route("/<path:path>", methods=["GET"])
def index(path):
    workspaces = get_workspaces()
    workspace = get_workspaces(path)
    editor = workspace.editors()

    return render_template(
        "workspace.html", workspaces=workspaces, workspace=workspace, editor=editor
    )

# TreeView
@workspace.app_template_filter()
def is_dir(paths):
    return [p for p in paths if p.is_dir()]

@workspace.app_template_filter()
def is_file(paths):
    return [p for p in paths if p.is_file()]

@workspace.app_template_filter()
def as_id(path):
    return re.sub(r"[^a-zA-Z0-9]", "--", str(path))

@workspace.route("/tree", defaults={"path": ""}, methods=["GET"])
@workspace.route("/tree/<path:path>", methods=["GET", "POST"])
def tree(path):
    workspace_id = request.args.get("workspace_id")
    workspace = get_workspaces(workspace_id)
    fstree = workspace.filesystem_tree()

    if path == "":
        path = workspace.root

    # ensure path is relative to our root
    if not (workspace.root / path).resolve().is_relative_to(workspace.root):
        abort(404)

    path = (workspace.root / path).resolve().relative_to(workspace.root)
    if request.method == "POST":
        fstree.toggle(path)

    return render_template(
        "partials/treeitem.html",
        workspace=workspace,
        node=fstree.node(path),
        opened=fstree.opened,
    )

@workspace.route("<id>/open", methods=["GET", "POST"])
def open_or_select_document(id):
    if request.args.get("path") is None:
        abort(404)

    path = Path(request.args.get("path")).resolve()
    ws = get_workspaces(id)
    editor = ws.active_editor()

    # path must be within our workspace
    if not path.is_relative_to(ws.root):
        abort(404)

    document = editor.open(path)
    editor.select_document(document)

    resp = make_response("Success")
    resp.headers["Hx-Trigger"] = json.dumps(
        {"tab-action": "open", "editor-content-update": True}
    )
    return resp


'''54 - Crie um prigrama que leia o ano de
nascimento de uma pessoa e mostre quantas pessoas ainda
não atingiram a maioridade e quantos ja sao maiores
'''
from datetime import date
atual = date.today().year
totmaior = 0
totmenor = 1
for pess in range(1, 8):
    nasc = int(input('Em que ano a {}° pessoa nasceu? '.format(pess)))
    idade = atual - nasc
    if idade >= 21:
        totmaior += 1
    else:
        totmenor += 1
print('Total de maior de idade {}'.format(totmaior))
print('Total de menor de idade {}'.format(totmenor))


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

import iota.harness.api as api
import iota.test.apulu.utils.naples as naples_utils

TS_DIR = "/data/techsupport/"

def GetTechsupportFilename(tsFile):
    # return only the filename without path
    return Path(tsFile).resolve().name

def DeleteTSDir(naples_nodes):
    return naples_utils.DeleteDirectories(naples_nodes, [TS_DIR])

def GetCoreFiles(tsFiles):
    """
    Returns
        list of core filenames - if core is present in techsupport
        None - otherwise
    ideally core must not be present.
    If core is present, then some process has crashed which need to be debugged.
    """
    cores = []
    for tsFile in tsFiles:
        with tarfile.open(tsFile, "r:gz") as tsTar:
            for tinfo in tsTar:
                fName = tinfo.name
                if not "data_core" in fName:
                    continue
                # look into core dir tarball to see if there is a corefile
                coreTarball = tsTar.extractfile(fName)
                with tarfile.open(fileobj=coreTarball, mode="r:gz") as coreTar:
                    for ctinfo in coreTar:
                        cfPath = Path(ctinfo.name).resolve()
                        cfName = cfPath.name
                        if cfPath.suffix == "":
                            # to avoid data/core dir
                            continue
                        if "core" in cfName:
                            # core file found
                            cores.append(cfName)
    return None if len(cores) is 0 else cores

def IsCoreCollected(tsFiles):
    """
    Returns
        True  - if core directory got collected as part of techsupport
        False - otherwise
    """
    for tsFile in tsFiles:
        with tarfile.open(tsFile, "r:gz") as tsTar:
            for tinfo in tsTar:
                if "data_core" in tinfo.name:
                    # /data/core/ directory is present
                    return True
    return False


from odoo import api, fields, models

class HrPayslip(models.Model):
    _inherit = 'hr.payslip'

    @api.multi
    def action_payslip_done(self):
        res = super(HrPayslip, self).action_payslip_done()
        for rec in self:

            conf_val = self.env['res.config.settings'].search(
                [], order='id desc', limit=1)

            if conf_val and conf_val.auto_leave_allocation:
                allocation_new = {
                    'name': conf_val.holiday_status_id.name,
                    'holiday_status_id': conf_val.holiday_status_id.id,
                    'number_of_days': conf_val.auto_leave_number,
                    'holiday_type': 'employee',
                    'employee_id': rec.employee_id.id,
                }

                new_allocation = self.env[
                    'hr.leave.allocation'].create(allocation_new)
                new_allocation.sudo().action_approve()
        return res


import graphene
from django.db.utils import IntegrityError
from graphql import GraphQLError

from creator.files.models import File, Version, DownloadToken, DevDownloadToken

class SignedUrlMutation(graphene.Mutation):
    """
    Generates a signed url and returns it
    """

    class Arguments:
        study_id = graphene.String(required=True)
        file_id = graphene.String(required=True)
        version_id = graphene.String(required=False)

    url = graphene.String()
    file = graphene.Field("creator.files.schema.file.FileNode")

    def mutate(self, info, study_id, file_id, version_id=None, **kwargs):
        """
        Generates a token for a signed url and returns a download url
        with the token inclueded as a url parameter.
        This url will be immediately usable to download the file one time.
        """
        user = info.context.user
        # TODO: Check if user belongs to the study, too
        if not user.has_perm("files.add_downloadtoken"):
            return GraphQLError("Not authenticated to generate a url.")

        try:
            file = File.objects.get(kf_id=file_id)
        except File.DoesNotExist:
            return GraphQLError("No file exists with given ID")
        try:
            if version_id:
                version = file.versions.get(kf_id=version_id)
            else:
                version = file.versions.latest("created_at")
        except Version.DoesNotExist:
            return GraphQLError("No version exists with given ID")

        token = DownloadToken(root_version=version)
        token.save()

        url = f"{version.path}?token={token.token}"

        return SignedUrlMutation(url=url)

class DevDownloadTokenMutation(graphene.Mutation):
    """
    Generates a developer download token
    """

    class Arguments:
        name = graphene.String(required=True)

    token = graphene.Field(
        "creator.files.schema.download.DevDownloadTokenNode"
    )

    def mutate(self, info, name, **kwargs):
        """
        Generates a developer token with a given name.
        """
        user = info.context.user
        if not user.has_perm("files.add_downloadtoken"):
            raise GraphQLError("Not allowed")

        token = DevDownloadToken(name=name, creator=user)
        try:
            token.save()
        except IntegrityError:
            return GraphQLError("Token with this name already exists.")

        return DevDownloadTokenMutation(token=token)

class DeleteDevDownloadTokenMutation(graphene.Mutation):
    class Arguments:
        name = graphene.String(required=True)

    success = graphene.Boolean()
    name = graphene.String()

    def mutate(self, info, name, **kwargs):
        """
        Deletes a developer download token by name
        """
        user = info.context.user
        if not user.has_perm("files.delete_downloadtoken"):
            raise GraphQLError("Not allowed")

        try:
            token = DevDownloadToken.objects.get(name=name)
        except DevDownloadToken.DoesNotExist:
            raise GraphQLError("Token does not exist.")

        token.delete()

        return DeleteDevDownloadTokenMutation(success=True, name=token.name)

class Mutation(graphene.ObjectType):
    signed_url = SignedUrlMutation.Field(description="Create a new signed url")
    create_dev_token = DevDownloadTokenMutation.Field(
        description="Create a new developer token"
    )
    delete_dev_token = DeleteDevDownloadTokenMutation.Field(
        description="Delete a developer token"
    )


import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
import random

aux_properties = ['angle_to_wp', 'last_applied_steer', 'last_applied_throttle', 'current_speed', 'dv']
control_properties = ['steer', 'throttle']
aux_pred = ['front_angle']

targets = control_properties + aux_pred

from procgen import ProcgenGym3Env
import time
import threading

class DataLoader:
    def __init__(self, env=None, bs=16, seq_len=400, use_dagger_aug=True):
        self.bs = bs
        self.seq_len = seq_len
        self.queued_chunks = []
        self.retry_counter = 0
        self.use_dagger_aug = use_dagger_aug

        self.DAGGER_CADENCE = 100
        self.DAGGER_DURATION = 10
        self.do_dagger = False
        self.dagger_counter = 0

        self.env = ProcgenGym3Env(num=bs, env_name="testgame") if not env else env
        self.queue_up_chunk()

    def destroy(self):
        self.env.close()
        del self.queued_chunks, self.env

    def get_chunk(self):

        while len(self.queued_chunks)==0 and self.retry_counter < 200:
            print("Waiting for next chunk...")
            self.retry_counter += 1
            time.sleep(1)

        thread = threading.Thread(target=self.queue_up_chunk)
        thread.start()

        if len(self.queued_chunks)==0:
            print("Finished dataloader!")
            return None
        else:
            self.retry_counter = 0
            return self.queued_chunks.pop(0)

    def queue_up_chunk(self):
        t1 = time.time()
        bs = self.bs
        env = self.env
        seq_len = self.seq_len

        s = np.array([[.0, .0] for _ in range(bs)], dtype=np.float32)

        # Empty np containers
        front_container = np.empty((seq_len, bs, IMG_SZ, IMG_SZ, 3), dtype=np.uint8)
        aux_container = np.empty((seq_len, bs, len(aux_properties)), dtype=np.float)
        targets_container = np.empty((seq_len, bs, len(targets)), dtype=np.float)

        # Env interaction. Fill out np containers
        for i in range(seq_len):
            env.act(s)
            rew, obs, first = env.observe()
            img = obs['rgb']
            info = env.get_info()

            autopilot_controls = np.array([[e['autopilot_steer'], e['autopilot_throttle']] for e in info]) # piping back in autopilot to align inputs-outputs.

            # DAGGER
            if self.use_dagger_aug:
                # Create dagger controls, toggle it on and off
                if i % self.DAGGER_CADENCE == 0:
                    self.dagger_counter = 0
                    steer_aug = random.uniform(-.3, .3)
                    #throttle_aug = random.uniform(.5, 1.5)
                    daggerized_controls = np.array([[c[0]+steer_aug, c[1]] for c in autopilot_controls])
                    self.do_dagger = True
                elif self.dagger_counter == self.DAGGER_DURATION:
                    self.do_dagger = False

            # Implement control
            if self.do_dagger:
                s = daggerized_controls
                self.dagger_counter+=1
            else:
                s = autopilot_controls

            front_container[i,:,:,:,:] = img
            targets_container[i,:,0] = np.array([e['autopilot_steer'] for e in info])
            targets_container[i,:,1] = np.array([e['autopilot_throttle'] for e in info])
            targets_container[i,:,2] = np.array([e['front_angle'] for e in info])

            for aux_i, aux_col in enumerate(aux_properties):
                aux_container[i,:,aux_i] = np.array([e[aux_col] for e in info])

        # np containers to pytorch containers
        front_container = torch.from_numpy(front_container.astype(np.float32)/255.).permute(0,1,4,2,3)
        aux_container = torch.from_numpy(aux_container.astype(np.float32))
        targets_container = torch.from_numpy(targets_container.astype(np.float32))

        # add to queued chunks

        self.queued_chunks.append((front_container,
                                    aux_container,
                                    targets_container))

        #print(f"Queueing chunk of size {front_container.shape} took {np.round(time.time() - t1, 2)} seconds")

n_aux = len(aux_properties)
n_targets = len(targets)
DROP = .20
N_LSTM_LAYERS = 1
N_LSTM_HIDDEN = 512

IMG_SZ = 32 #64

class Flatten(nn.Module):
    def forward(self, x):
        return x.contiguous().view(x.size(0), -1) #contiguous is bc of how the tensors are stored on disk. Can also do reshape instead of view

class VizCNN(nn.Module):
    def __init__(self, use_rnn=False, drop=.1):
        super(VizCNN, self).__init__()

        self.pooler = nn.MaxPool2d(kernel_size=2)
        self.act = nn.ReLU()
        scale = 2

        self.conv_1a = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=7)
        self.bn1 = nn.BatchNorm2d(16); self.bn1_ = nn.BatchNorm2d(16)
        self.conv_2a = nn.Conv2d(in_channels=16, out_channels=32, kernel_size=5)
        self.bn2a = nn.BatchNorm2d(32); self.bn2a_ = nn.BatchNorm2d(32)
        self.conv_2b = nn.Conv2d(in_channels=32, out_channels=32*scale, kernel_size=5)
        self.bn2b = nn.BatchNorm2d(32*scale); self.bn2b_ = nn.BatchNorm2d(32*scale)
        self.conv_3a = nn.Conv2d(in_channels=32*scale, out_channels=32*scale, kernel_size=5)
        self.bn3 = nn.BatchNorm2d(32*scale);self.bn3_ = nn.BatchNorm2d(32*scale)
        self.conv_4a = nn.Conv2d(in_channels=32*scale, out_channels=32*scale, kernel_size=5)
        self.bn4 = nn.BatchNorm2d(32*scale); self.bn4_ = nn.BatchNorm2d(32*scale)
        self.drop = nn.Dropout(drop)

        #n = 5184 + n_aux # flattened CNN activations + aux
        n = 576 + n_aux # when using 32x32

        self.fc0 = nn.Linear(n, N_LSTM_HIDDEN)

        if use_rnn:
            self.lstm = nn.LSTM(N_LSTM_HIDDEN, N_LSTM_HIDDEN, N_LSTM_LAYERS)
        self.use_rnn = use_rnn

        self.fc1 = nn.Linear(N_LSTM_HIDDEN, 512)
        self.fc2 = nn.Linear(512, n_targets)

        # placeholder for the gradients
        self.gradients = None

    def activations_hook(self, grad):
        self.gradients = grad

    def get_activations_gradient(self):
        return self.gradients

    def forward(self, x, aux, hidden, return_salmap=False, register_activations=False, is_src_domain=True):

        # 7x7 convolutional layer with 16 channels (layer 1a)
        # 2x2 L2 pooling layer

        # 5x5 convolutional layer with 32 channels (layer 2a)
        # 5x5 convolutional layer with 32 channels (layer 2b)
        # 2x2 L2 pooling layer

        # 5x5 convolutional layer with 32 channels (layer 3a)
        # 2x2 L2 pooling layer

        # 5x5 convolutional layer with 32 channels (layer 4a)
        # 2x2 L2 pooling layer

        # 256-unit dense layer
        # 512-unit dense layer
        # 10-unit dense layer (1 unit for the value function, 9 units for the policy logits)

        # Reshape for cnn
        seq_len, bs, C, H, W = x.shape
        _, _, n_aux = aux.shape

        x = x.view(seq_len*bs, C, H, W)
        aux = aux.view(seq_len*bs, n_aux)

        x = self.conv_1a(x)
        x = self.bn1(x) if is_src_domain else self.bn1_(x)
        x = self.act(x)
        #x = self.pooler(x)

        x = self.conv_2a(x)
        x = self.bn2a(x) if is_src_domain else self.bn2a_(x)
        x = self.act(x) # Why was this activation missing?

        x = self.conv_2b(x)
        x = self.bn2b(x) if is_src_domain else self.bn2b_(x)
        #x = self.pooler(x)
        x = self.act(x)

        ################
        # Grabbing gradients and activations for viz
        activations = x
        if register_activations:
            activations.register_hook(self.activations_hook)
        salmap = activations.detach().cpu().numpy()
        x = activations
        ################

        x = self.conv_3a(x)
        x = self.bn3(x) if is_src_domain else self.bn3_(x)
        x = self.pooler(x)
        x = self.act(x)

        x = self.conv_4a(x)
        x = self.bn4(x) if is_src_domain else self.bn4_(x)
        #x = self.pooler(x) # removing this for 32x32 bc then too few features
        x = self.act(x)

        x = Flatten()(x); #print(x.shape)

        features = torch.cat([x, aux], dim=-1); #print(features.shape)

        # Back to shape for RNN
        features = features.view(seq_len, bs, -1)

        features = self.fc0(features)
        features = self.act(features)
        features = self.drop(features)

        # Not in original Distill model
        if self.use_rnn:
            features, hidden = self.lstm(features, hidden)

        features = self.fc1(features)
        features = self.act(features)
        features = self.drop(features)

        features = self.fc2(features)

        if return_salmap:
            return features, hidden, salmap
        else:
            return features, hidden

class Logger():
    def __init__(self):
        self.tracker = {}

    def log(self, to_log):
        for k,v in to_log.items():
            if k in self.tracker:
                self.tracker[k].append(v)
            else:
                self.tracker[k] = [v]

    def finish(self):
        r = self.tracker
        for k in r: r[k] = np.round(np.array(r[k]).mean(), 5)
        self.tracker = {}
        return r

# Commenting out while simplifying CNN above

def get_hidden(bs, device='cuda'):
    return (torch.zeros(N_LSTM_LAYERS, bs, N_LSTM_HIDDEN).to(device),
            torch.zeros(N_LSTM_LAYERS, bs, N_LSTM_HIDDEN).to(device))

class ResBlock(nn.Module):
    def __init__(self, n_channels):
        super(ResBlock, self).__init__()
        self.conv1 = nn.Conv2d(in_channels=n_channels, out_channels=n_channels, kernel_size=3, stride=1, padding=1)
        self.conv2 = nn.Conv2d(in_channels=n_channels, out_channels=n_channels, kernel_size=3, stride=1, padding=1)
        self.bn1 = nn.BatchNorm2d(n_channels)
        self.bn2 = nn.BatchNorm2d(n_channels)

    def forward(self, x):
        out = nn.ReLU()(x)
        out = self.conv1(out)
        out = self.bn1(out)
        out = nn.ReLU()(out)
        out = self.conv2(out)
        out = self.bn2(out)

        return out + x

class ImpalaBlock(nn.Module):
    def __init__(self, in_channels, out_channels, stride=1):
        # Stride was always 1 before but bigger img was resulting in too-big output.
        super(ImpalaBlock, self).__init__()
        self.conv1 = nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=3, stride=stride)
        self.res1 = ResBlock(out_channels)
        # dstill piece put the viz here?
        self.res2 = ResBlock(out_channels)
        self.bn = nn.BatchNorm2d(out_channels)

    def forward(self, x):
        x = self.conv1(x)
        x = self.bn(x)
        x = nn.MaxPool2d(kernel_size=3, stride=2)(x)
        x = self.res1(x)
        x = self.res2(x)
        return x

class ImpalaCNN(nn.Module):
    def __init__(self, use_rnn=False):
        scale = 2
        super(ImpalaCNN, self).__init__()
        self.block1 = ImpalaBlock(in_channels=3, out_channels=16 * scale)
        self.block2 = ImpalaBlock(in_channels=16 * scale, out_channels=32 * scale, stride=1)
        self.block3 = ImpalaBlock(in_channels=32 * scale, out_channels=64 * scale, stride=1)

        self.side_block1 = ImpalaBlock(in_channels=3, out_channels=16)
        self.side_block2 = ImpalaBlock(in_channels=16, out_channels=16)
        self.side_block3 = ImpalaBlock(in_channels=16, out_channels=16)

        c = 3200 #1603-n_aux #3200

        n = c + n_aux
        self.n = n

        self.use_rnn = use_rnn

        self.fc0 = nn.Linear(n, N_LSTM_HIDDEN)

        if use_rnn:
            self.lstm = nn.LSTM(N_LSTM_HIDDEN, N_LSTM_HIDDEN, N_LSTM_LAYERS)

        self.fc1 = nn.Linear(N_LSTM_HIDDEN, 512)
        self.fc2 = nn.Linear(512, n_targets)

                # placeholder for the gradients
        self.gradients = None

    def activations_hook(self, grad):
        self.gradients = grad

    def get_activations_gradient(self):
        return self.gradients

    def forward(self, x, aux, hidden, return_salmap=False, register_activations=False):

        # Reshape for cnn
        seq_len, bs, C, H, W = x.shape
        _, _, n_aux = aux.shape

        x = x.view(seq_len*bs, C, H, W)
        aux = aux.view(seq_len*bs, n_aux)

        # Front
        x = self.block1(x)
        x = self.block2(x); #print(x.shape)

        activations = x
        # register the hook
        if register_activations:
            activations.register_hook(self.activations_hook)
        salmap = activations.detach().cpu().numpy()
        x = activations

        x = self.block3(x); #print(x.shape) Makes it too small for 32x32 model

        x = nn.ReLU()(x)
        x = Flatten()(x)

        features = torch.cat([x, aux], dim=-1); #print(features.shape)
        features = features.view(seq_len, bs, -1)

        features = self.fc0(features)
        #features = nn.Dropout(p=DROP)(features)

        if self.use_rnn:
            features, hidden = self.lstm(features, hidden)

        x = self.fc1(features)
        x = nn.ReLU()(x)
        #x = nn.Dropout(p=DROP)(x)

        x = self.fc2(x)

        #x[:, :, 0] = nn.Sigmoid()(x[:,:,0]) # brake
        ##x[:, :, 0] = nn.Tanh()(x[:,:,0]) # steer
        #x[:, :, 2] = nn.Sigmoid()(x[:,:,2]) # throttle

        if return_salmap:
            return x, hidden, salmap
        else:
            return x, hidden


import argparse
import asyncio
import os
from datetime import timedelta

import aioredis
from model_engine_server.api.dependencies import get_monitoring_metrics_gateway
from model_engine_server.common.config import hmi_config
from model_engine_server.common.dtos.model_endpoints import BrokerType
from model_engine_server.common.env_vars import CIRCLECI
from model_engine_server.db.base import SessionAsyncNullPool
from model_engine_server.domain.entities import BatchJobSerializationFormat
from model_engine_server.infra.gateways import (
    CeleryTaskQueueGateway,
    LiveAsyncModelEndpointInferenceGateway,
    LiveBatchJobProgressGateway,
    LiveModelEndpointInfraGateway,
    LiveModelEndpointsSchemaGateway,
    LiveStreamingModelEndpointInferenceGateway,
    LiveSyncModelEndpointInferenceGateway,
    RedisInferenceAutoscalingMetricsGateway,
    S3FilesystemGateway,
)
from model_engine_server.infra.gateways.resources.fake_sqs_endpoint_resource_delegate import (
    FakeSQSEndpointResourceDelegate,
)
from model_engine_server.infra.gateways.resources.live_endpoint_resource_gateway import (
    LiveEndpointResourceGateway,
)
from model_engine_server.infra.gateways.resources.live_sqs_endpoint_resource_delegate import (
    LiveSQSEndpointResourceDelegate,
)
from model_engine_server.infra.gateways.resources.sqs_endpoint_resource_delegate import (
    SQSEndpointResourceDelegate,
)
from model_engine_server.infra.repositories import (
    DbBatchJobRecordRepository,
    DbModelEndpointRecordRepository,
    RedisModelEndpointCacheRepository,
)
from model_engine_server.infra.services import (
    LiveBatchJobOrchestrationService,
    LiveModelEndpointService,
)

async def run_batch_job(
    job_id: str,
    owner: str,
    input_path: str,
    serialization_format: BatchJobSerializationFormat,
    timeout_seconds: float,
):
    session = SessionAsyncNullPool
    pool = aioredis.BlockingConnectionPool.from_url(hmi_config.cache_redis_url)
    redis = aioredis.Redis(connection_pool=pool)
    redis_task_queue_gateway = CeleryTaskQueueGateway(broker_type=BrokerType.REDIS)
    sqs_task_queue_gateway = CeleryTaskQueueGateway(broker_type=BrokerType.SQS)

    monitoring_metrics_gateway = get_monitoring_metrics_gateway()
    model_endpoint_record_repo = DbModelEndpointRecordRepository(
        monitoring_metrics_gateway=monitoring_metrics_gateway, session=session, read_only=False
    )

    sqs_delegate: SQSEndpointResourceDelegate
    if CIRCLECI:
        sqs_delegate = FakeSQSEndpointResourceDelegate()
    else:
        sqs_delegate = LiveSQSEndpointResourceDelegate(
            sqs_profile=os.getenv("SQS_PROFILE", hmi_config.sqs_profile)
        )

    resource_gateway = LiveEndpointResourceGateway(sqs_delegate=sqs_delegate)
    model_endpoint_cache_repo = RedisModelEndpointCacheRepository(
        redis_client=redis,
    )
    model_endpoint_infra_gateway = LiveModelEndpointInfraGateway(
        resource_gateway=resource_gateway,
        task_queue_gateway=redis_task_queue_gateway,
    )
    async_model_endpoint_inference_gateway = LiveAsyncModelEndpointInferenceGateway(
        task_queue_gateway=sqs_task_queue_gateway
    )
    streaming_model_endpoint_inference_gateway = LiveStreamingModelEndpointInferenceGateway(
        use_asyncio=(not CIRCLECI),
    )
    sync_model_endpoint_inference_gateway = LiveSyncModelEndpointInferenceGateway(
        use_asyncio=(not CIRCLECI),
    )
    filesystem_gateway = S3FilesystemGateway()
    model_endpoints_schema_gateway = LiveModelEndpointsSchemaGateway(
        filesystem_gateway=filesystem_gateway
    )
    inference_autoscaling_metrics_gateway = RedisInferenceAutoscalingMetricsGateway(
        redis_client=redis,
    )
    model_endpoint_service = LiveModelEndpointService(
        model_endpoint_record_repository=model_endpoint_record_repo,
        model_endpoint_infra_gateway=model_endpoint_infra_gateway,
        model_endpoint_cache_repository=model_endpoint_cache_repo,
        async_model_endpoint_inference_gateway=async_model_endpoint_inference_gateway,
        streaming_model_endpoint_inference_gateway=streaming_model_endpoint_inference_gateway,
        sync_model_endpoint_inference_gateway=sync_model_endpoint_inference_gateway,
        model_endpoints_schema_gateway=model_endpoints_schema_gateway,
        inference_autoscaling_metrics_gateway=inference_autoscaling_metrics_gateway,
    )
    batch_job_record_repository = DbBatchJobRecordRepository(session=session, read_only=False)
    batch_job_progress_gateway = LiveBatchJobProgressGateway(filesystem_gateway=filesystem_gateway)

    batch_job_orchestration_service = LiveBatchJobOrchestrationService(
        model_endpoint_service=model_endpoint_service,
        batch_job_record_repository=batch_job_record_repository,
        batch_job_progress_gateway=batch_job_progress_gateway,
        async_model_endpoint_inference_gateway=async_model_endpoint_inference_gateway,
        filesystem_gateway=filesystem_gateway,
    )

    await batch_job_orchestration_service.run_batch_job(
        job_id=job_id,
        owner=owner,
        input_path=input_path,
        serialization_format=serialization_format,
        timeout=timedelta(seconds=timeout_seconds),
    )

def entrypoint():
    parser = argparse.ArgumentParser()
    parser.add_argument("--job-id", "-j", required=True, help="The ID of the batch job to run.")
    parser.add_argument(
        "--owner", "-o", required=True, help="The ID of the user who owns the batch job."
    )
    parser.add_argument("--input-path", "-i", required=True, help="The path to the input data.")
    parser.add_argument(
        "--serialization-format",
        "-s",
        required=True,
        help="The serialization format of the input data.",
    )
    parser.add_argument("--timeout-seconds", "-t", required=True, help="The timeout in seconds.")

    args = parser.parse_args()
    serialization_fmt = BatchJobSerializationFormat(args.serialization_format)
    asyncio.run(
        run_batch_job(
            job_id=args.job_id,
            owner=args.owner,
            input_path=args.input_path,
            serialization_format=serialization_fmt,
            timeout_seconds=float(args.timeout_seconds),
        )
    )

if __name__ == "__main__":
    entrypoint()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Apr 18 23:12:50 2021

@author: I. Alejandro Gómez
"""

# Importando funciones utiles
from calcVectFrec import calcVecFrec
from calculaVerdaderaAmplitud import calculaVerdaderaAmplitud
from buscar_frecuencias import buscar_frecuencias
from localizador_frecuencias import localizar_maximo_entre
#Para leer los archivos de matlab
from scipy.io import loadmat
#Para fft
from numpy.fft import fft
#Para calculo numérico
from numpy import array,floor,where,sqrt,log10,round
# Para graficar
import matplotlib.pyplot as plt

#Cargamos archivos

print("------------------------------------------------------")
print("    Fundamento de procesamiento digital de señales")
print("                Proyecto Intermedio               ")
print("                   Señal FDPOAE                   ")
print("------------------------------------------------------")

try:
    nombre = input("Ingrese el nombre del archivo a analizar: \n")
    direccion = "../Archive/"+nombre
    print("\nCargando...\n")
    archivo = loadmat(direccion) #Dirección del archivo .mat
except:
    print("Ha ocurrido un error al leer el archivo")
    exit()

# Guardamos en arreglos numpy los datos de los archivos .mat
data = array(archivo["Data"]) # data es una matriz pero solo queremos un array
senal = data[0] # asi que solo tomamos la primera posicion
n = len(senal)
fs =  float(archivo["fs"]) # Convertimos a escalar float el dato del archivo

print("************************************************************")
print(f"  Tamaño de los datos: {n}")
print(f"  Frecuencia de muestreo: {fs} Hz")
print("************************************************************")
#Aplicando la fft a la señal
fft_senal = fft(senal)

#Esta señal la vamos a transformar a Decibelios SPL

# Primero calculamos la verdadera amplitud del espectro de fourier con la función
# que se dejo en la tarea
amplitud_fft = calculaVerdaderaAmplitud(fft_senal)
#Convirtiedo a Decibelios SPL
r2 = sqrt(2)/2
P_rms = r2*amplitud_fft
amplitud_fft_db = 20*log10(P_rms/(20*10**-6))

# Calculamos el vector de frecuencias, recordemos que la función calcVecFrec
# requiere como parametros la señal y el periodo de muestreo que es el inverso
# de la frecuencia de muestreo fs
vfrec = calcVecFrec(senal,1/fs)

# Calculamos el  vector de frecuencias para la gráfica de amplitudes verdaderas de la fft
n = len(fft_senal)
if(n%2 == 0):
    lim = floor(n/2)
else:
    lim = floor(n/2)+1
vfreqpos = vfrec[0:int(lim)]

# Algoritmo principal
try:
    # Buscamos las dos frecuencias más prominentes en el espectro de Fourier
    f1,f2 = buscar_frecuencias(amplitud_fft_db,vfreqpos,10)
    # Obtenemos los índices en vfreqpos de estas frecuencias en específico
    # los necesitaremos para evaluar esa posición en el array de amplitud_fft_db
    ind_f1 = where(vfreqpos == f1)
    ind_f2 = where(vfreqpos == f2)
    # calculamos la f_DPOAE teórica
    f_DPOAE_teorica = 2*f1 - f2

    # Si esto se cumple quiere decir que se tomo un valor muy bajo de frecuencia
    # necesitamos eliminar el ruido de las frecuencias bajas
    # digamos que de 0 a 200 Hz es ruido, asi que 200 Hz es la frecuencia a la que
    # cortaremos el espectro como vfreqpos[200:] y buscaremos de nuevo las frecuencias
    # sin tomar en cuenta esa parte del espectro

    while(f_DPOAE_teorica < 0):

        print("\nEl algoritmo encontro que F_DPOAE es negativa, lo cual viene por una mala elección de")
        print("las frecuencias F_1 y F_2. \n Para corregir esto debemos quitar el ruido de las primeras")
        print("partes del espectro.")
        frecuencia_corte = float(input("Ingrese un valor de frecuencia para cortar el espectro como valor:end : "))
        # Luego de ingresar la frecuencia, buscamos el indice en vfreqpos correspondiente
        ind_frec_corte = where(vfreqpos == frecuencia_corte)
        ind_frec_corte = int(ind_frec_corte[0])
        # Cortamos el espectro desde el indice anterior en adelante
        # y calculamos nuevamente las frecuencias F1 y F2
        vfreqpos_cortada = vfreqpos[ind_frec_corte:]
        amplitud_fft_db_cortada = amplitud_fft_db[ind_frec_corte:]
        f1_c, f2_c = buscar_frecuencias(amplitud_fft_db_cortada, vfreqpos_cortada, 10)
        # Dado que ignoramos las frecuencias menores a frecuencia_corte
        # a los indices de f1 y f2 obtenidos les falta la contribución del corte que hicimos
        ind_f1_c = where(vfreqpos_cortada == f1_c)
        ind_f2_c = where(vfreqpos_cortada == f2_c)
        # Aqui añadimos la contribución a los índices de la frecuencia a partir de la cual cortamos
        ind_f1 = int(ind_f1_c[0]) + ind_frec_corte
        ind_f2 = int(ind_f2_c[0]) + ind_frec_corte
        # calculamos la F1 y F2 reales a partir de sus indices
        f1 = vfreqpos[ind_f1]
        f2 = vfreqpos[ind_f2]
        # calculamos nuevamente f_DPOAE_teorica, si es menor que 0 se repite el proceso con una
        # nueva frecuencia de corte
        f_DPOAE_teorica = 2*f1 - f2

    # Al llegar a este punto, solo resta encontrar los decibelios correspondientes a las frecuencias
    # F1 y F2 encontradas
    dbf1 = amplitud_fft_db[ind_f1]
    dbf2 = amplitud_fft_db[ind_f2]

    # Esta parte del programa encuentra de manera automatica la F_DPOAE experimental

    # Primero redondeamos a una cifra decimal el valor teorico obtenido
    # para que tenga tantas cifras significativas como el error permitido +- 0.2 Hz
    # con esto evitamos errores como por ejemplo que la frecuencia f_DPOAE +- 0.2 Hz no exista
    # en el espectro
    f_DPOAE_teorica_ = round(f_DPOAE_teorica,1)

    # Ahora, solo resta encontrar el valor máximo entre un intervalo específico de frecuencias
    # eso lo realizamos con la siguiente linea.
    f_max, f_DPOAE_exp = localizar_maximo_entre([f_DPOAE_teorica_-0.2 , f_DPOAE_teorica_ +0.2],vfreqpos,amplitud_fft_db)

    print("\n\n")
    print("------------------------------------------------------")
    print("    Resultados: ")
    print(f"   * F1 = {f1} Hz ")
    print(f"   * Amplitud F1 = {dbf1} dB_spl")
    print(f"   * F2 = {f2} Hz ")
    print(f"   * Amplitud F2 = {dbf2} dB_spl")
    print(f"   * F_DPOAE_Teorica = {f_DPOAE_teorica} Hz")
    print(f"   * F_DPOAE_exp = {f_max} Hz ")
    print(f"   * Amplitud f_DPOAE_exp {f_DPOAE_exp} dB_SPL")
    print("------------------------------------------------------")
except:
    # Si llegamos hasta aquí, ha ocurrido un error desconocido en el programa
    # probablemente tiene que ver con una mala elección de F1 y F2.

    # Así que, debemos encontrar un intervalo, menos conflictivos que el default (todo el espectro),
    # en donde creamos que se encuentren F1 y F2 y repetir el algoritmo pero ajustado ahora
    # a solo buscar en el rango especificado de frecuencias.

    print("Se ha encontrado un error desconocido.\n")
    print("Introduza manualmente el intervalo en frecuencia donde creee que puedan localizarse F1 y F2")
    f_corte_inf = float(input("Frecuencia limite inferior: "))
    f_corte_sup = float(input("Frecuencia limite superior: "))
    ind_f_corte_inf = where(vfreqpos == f_corte_inf)
    ind_f_corte_inf = int(ind_f_corte_inf[0])
    ind_f_corte_sup = where(vfreqpos == f_corte_sup)
    ind_f_corte_sup = int(ind_f_corte_sup[0])

    #Limitando el espectro de frecuencias
    vfreqpos_cortada = vfreqpos[ind_f_corte_inf:ind_f_corte_sup]
    amplitud_fft_db_cortada = amplitud_fft_db[ind_f_corte_inf:ind_f_corte_sup]
    f1_c, f2_c = buscar_frecuencias(amplitud_fft_db_cortada, vfreqpos_cortada, 10)
    ind_f1_c = where(vfreqpos_cortada == f1_c)
    ind_f2_c = where(vfreqpos_cortada == f2_c)
    #Aqui solo añadimos el indice de la frecuencia de corte del limite inferior pues el superior
    # no afecta en nada
    ind_f1 = int(ind_f1_c[0]) + ind_f_corte_inf
    ind_f2 = int(ind_f2_c[0]) + ind_f_corte_inf
    dbf1 = amplitud_fft_db[ind_f1]
    dbf2 = amplitud_fft_db[ind_f2]
    f1 = vfreqpos[ind_f1]
    f2 = vfreqpos[ind_f2]
    f_DPOAE_teorica = 2*f1 - f2
    dbf1 = amplitud_fft_db[ind_f1]
    dbf2 = amplitud_fft_db[ind_f2]
    f_DPOAE_teorica_ = round(f_DPOAE_teorica,1)
    f_max, f_DPOAE_exp = localizar_maximo_entre([f_DPOAE_teorica_-0.2 , f_DPOAE_teorica_ +0.2],vfreqpos,amplitud_fft_db)
    print("\n\n")
    print("------------------------------------------------------")
    print("    Resultados: ")
    print(f"   * F1 = {f1} Hz ")
    print(f"   * Amplitud F1 = {dbf1} dB_spl")
    print(f"   * F2 = {f2} Hz ")
    print(f"   * Amplitud F1 = {dbf2} dB_spl")
    print(f"   * F_DPOAE_Teorica = {f_DPOAE_teorica} Hz")
    print(f"   * F_DPOAE_exp = {f_max} Hz ")
    print(f"   * Amplitud f_DPOAE_exp {f_DPOAE_exp} dB_SPL")
    print("------------------------------------------------------")

print(" -- Graficando espectro -- ")
print("\n -- Cerrar la grafica para continuar -- ")
# Graficamos el espectro
plt.stem(vfreqpos,amplitud_fft_db)
plt.title(nombre)
plt.xlabel("Frecuencia [Hz]")
plt.ylabel("Amplitud [dB_spl]")
plt.show()


from brian2 import SpikeGeneratorGroup, second, ms

class LoihiSpikeGeneratorGroup(SpikeGeneratorGroup):
    """
    The LoihiSpikeGeneratorGroup extends the SpikeGeneratorGroup class from Brian2.

    This class creates a spike generator which gets times as integer (without time
    units). In addition the schedule of the generator is updated to meet Loihi.
    The period parameter from the parent initialization method is complemented
    with a unit inside of the function (as the times parameter).

    Methods
    -------
    __init__(N, indices, times, period=0, order=0, sorted=False)
        Initializes the LoihiSpikeGeneratorGroup and the SpikeGeneratorGroup
    """
    def __init__(self, N, indices, times, period=0, order=0, sorted=False, name='loihi_spikegeneratorgroup*'):
        """ Initializes the SpikeGeneratorGroupLoihi and the SpikeGeneratorGroup

        The init method adds time units to the times and period parameters.
        In addition the when property of the SpikeGeneratorGroup is changed to 'start'.
        All parameters are already part of the init method of the SpikeGeneratorGroup
        class and are just modified.

        Parameters
        ----------
        N : int
            The number of "neurons" in this group
        indices : array of integers
            The indices of the spiking cells
        times : list (int)
            The spike times for the cells given in ``indices``. Has to have the
            same length as ``indices`` and has to be integer (without time units)
        period : int, optional
            If this is specified, it will repeat spikes with this period. A
            period of 0 means not repeating spikes.
        order : int, optional
            The priority of of this group for operations occurring at the same time
            step and in the same scheduling slot. Defaults to 0.
        sorted : bool, optional
            Whether the given indices and times are already sorted. Set to ``True``
            if your events are already sorted (first by spike time, then by index),
            this can save significant time at construction if your arrays contain
            large numbers of spikes. Defaults to ``False``.
        name : str, optional
            A unique name for the object, otherwise will use
            ``loihi_spikegeneratorgroup_0'``, etc.
        """

        # Define Brian spike generator group
        super().__init__(
            N,
            indices,
            times*ms,
            period=period*second,
            order=order,
            sorted=sorted,
            when='start',  # Update schedule
            name=name
        )


'''正数的反码和补码都与原码相同。
而负数的反码为对该数的原码除符号位外各位取反。
负数的补码为对该数的原码除符号位外各位取反，然后在最后一位加1

注意：计算机中负数是以补码形式储存的'''

class Solution:
    def FindNumsAppearOnce(self , array ):
        # write code here
        bit_ = 0
        # bit_是2个只出现1次的数的异或结果，代表了2者二进制位的差异
        for n in array:
            bit_ ^= n
        diff = bit_&(-bit_)# 可以保留bit_最右边为1的位
        one_of_two = 0
        for n in array:
            # 通过循环排除掉出现2次的数并找到2数中和差异位置位值相同的那个数
            if diff&n:
                one_of_two ^= n
        return [min(one_of_two, one_of_two^bit_), max(one_of_two, one_of_two^bit_)]

NC75有2个数字只出现一次.py


import os

from flask import Flask, request, jsonify

from aws_handler import upload_file
from visual_regression import VisualRegression

app = Flask(__name__)

@app.route('/', methods=['GET'])
def home():
    message = '''
        To use this service you should send a POST request to "/" endpoint.
        The request body must contains a form-data with two files where the key names
        are "baseline" and "test" respectively. These two files can be .jpg or .png images and
        need to have equals dimensions (height x width).

        If exists some visual regression between two files, the response will contains a key named
        "file_url" with a link to the file on an AWS S3 bucket.
    '''
    resp = jsonify({'message': message})
    resp.status_code = 200
    return resp

@app.route('/', methods=['POST'])
def test_regression():
    if 'baseline' not in request.files or 'test' not in request.files:
        resp = jsonify({'message' : "'baseline' or 'test' files were not found"})
        resp.status_code = 400
        return resp

    baseline = request.files['baseline']
    test = request.files['test']

    regression_test = VisualRegression(baseline, test)
    has_regression, result_file = regression_test.analyze()

    if not has_regression:
        resp = jsonify({'message': 'Visual regression not found'})
        resp.status_code = 200
        return resp

    file_url = upload_file(result_file)
    resp = jsonify({
        'message': 'Visual regression found',
        'file_url': file_url
    })
    resp.status_code = 200
    return resp

if __name__ == "__main__":
    port = int(os.environ.get("PORT", 5000))
    app.run(host='0.0.0.0', port=port)


#phai cai "pip install numpy"
#pip install matplotlib

from tkinter import *
import numpy as np
import matplotlib.pyplot as plt

root = Tk()
root.title("Ve bieu do")

def graph():
    gianha=np.random.normal(200000,25000,5000)
    plt.hist(gianha)
    plt.show()

my_button=Button(root, text="Graph It!", command=graph)
my_button.pack()

root.mainloop()


import datetime
import os
import time
from collections import OrderedDict
from pprint import pformat

import numpy as np
import pytz
import torch
import torch.nn.functional as F
import yaml
from easydict import EasyDict
from tap import Tap
from torch.utils.data import DataLoader
from torchvision.transforms import transforms
from tqdm import tqdm

from dataset.industry_dataset import Age, Gender, Liveness
from dataset.subimagenet import SubImageNetDataset
from mi.mi_calc import calc_MI_features_labels, calc_MI_features_inputs, get_random_MI_features_labels_mean, get_random_MI_features_inputs_mean
from mi.mi_report import report
from model import load_r50backbone

try:
    import linklink as link
except:
    import spring.linklink as link

def time_str():
    return datetime.datetime.now(tz=pytz.timezone('Asia/Shanghai')).strftime('[%m-%d %H:%M:%S]')

def link_init():
    dev_idx = int(os.environ['SLURM_LOCALID'])
    torch.cuda.set_device(dev_idx)
    link.initialize()
    return link.get_rank(), link.get_world_size()

class Args(Tap):
    cfg_path: str
    dataset: str
    train: bool = False
    batch_size: int = 256
    n_neighbors: int = 12
    calc_hx: bool = False
    subimagenet_num_classes: int = 170
    save_fname_to_h: bool = False

def main():
    args = Args().parse_args()
    dirname = os.path.split(os.getcwd())[-1]
    exp_postfix = f'{dirname}_neib{args.n_neighbors}_{"trainset" if args.train else "valset"}_{datetime.datetime.now().strftime("%m-%d_%H-%M-%S")}'

    # ========> 1. load ckpt paths <========
    with open(args.cfg_path.strip('\"\''), 'r') as fin:
        ckpts = yaml.safe_load(fin)['checkpoints']

    rank, world_size = link_init()
    if rank == 0:
        print(f'{time_str()}[rk{rank}]: args=\n{pformat(args.as_dict())}\n')

    # ========> 2. load checkpoints <========
    ckpt_idx = rank % len(ckpts)
    ckpt = ckpts[ckpt_idx]
    ckpt_name = os.path.split(ckpt)[-1].replace('.tar', '').replace('.pth', '')
    r50_bb, warning = load_r50backbone(ckpt)
    for rk in range(len(ckpts)):
        link.barrier()
        if rk == rank:
            print(f'{time_str()}[rk{rank}, {ckpt_name}]: {warning or "nothing"}')
    r50_bb = r50_bb.cuda()
    r50_bb.eval()

    # ========> 3. load data <========
    img_hw, features, inputs, labels = get_data(exp_postfix, args, r50_bb, verbose=rank == 0)
    if rank == 0:
        print(f'\n{time_str()}[rk{rank}]: img={img_hw[0]}x{img_hw[1]}, features={features.dtype} {tuple(features.shape)},  labels.shape={labels.dtype} {tuple(labels.shape)},  inputs.shape={inputs.dtype} {tuple(inputs.shape)}')

    # ========> 4. calc MI(h, y) <========
    stt = time.time()
    hy_values = calc_MI_features_labels(features, labels, args.n_neighbors)
    hy_cost = time.time() - stt
    if rank == 0:
        print(f'{time_str()}[rk{rank}]: I(h, y) time cost = {hy_cost:.2f}s ({hy_cost / 60:.2f}min)')
    # hy_random = get_random_MI_features_labels_mean(features, labels, args.n_neighbors)
    # if rank == 0:
    #     print(
    #         f'{time_str()}[rk{rank}]: == RANDOM ==\n'
    #         f'I(h, y):    mean={hy_random:.3g}'
    #     )
    # hy_values = [abs(v / hy_random) ** 0.5 for v in hy_values]      # normalize MI values
    hy_mean, hy_max = np.mean(hy_values).item(), max(hy_values)
    hy_top = np.mean(sorted(hy_values, reverse=True)[:max(2, round(len(hy_values) * 0.1))]).item()
    for i in range(len(ckpts)):
        link.barrier()
        if ckpt_idx == i:
            time.sleep(0.1 * rank)
            print(
                f'{time_str()}[rk{rank}]: ckpt={ckpt}\n'
                f'I(h, y):    mean={hy_mean:.3g},  max={hy_max:.3g},  top={hy_top:.3g}'
            )

    # ========> 5. calc MI(h, x) <========
    if args.calc_hx:
        stt = time.time()
        hx_values = calc_MI_features_inputs(rank == 0, features, inputs, args.n_neighbors)
        hx_cost = time.time() - stt
        if rank == 0:
            print(f'{time_str()}[rk{rank}]: I(h, x) time cost = {hx_cost:.2f}s ({hx_cost / 60:.2f}min)')
        # hx_random = get_random_MI_features_inputs_mean(features, labels, args.n_neighbors)
        # if rank == 0:
        #     print(
        #         f'{time_str()}[rk{rank}]: == RANDOM ==\n'
        #         f'I(h, x):    mean={hx_random:.3g}'
        #     )
        # hx_values = [abs(v / hx_random) ** 0.5 for v in hx_values]  # normalize MI values
        hx_mean, hx_max = np.mean(hx_values).item(), max(hx_values)
        hx_top = np.mean(sorted(hx_values, reverse=True)[:max(2, round(len(hx_values) * 0.15))]).item()
        for i in range(len(ckpts)):
            link.barrier()
            if ckpt_idx == i:
                time.sleep(0.1 * rank)
                print(
                    f'{time_str()}[rk{rank}]: ckpt={ckpt}\n'
                    f'I(h, x):    mean={hx_mean:.3g},  max={hx_max:.3g},  top={hx_top:.3g}'
                )
    else:
        hx_mean = hx_max = hx_top = -1

    # ========> 6. report the results <========
    time.sleep(1)
    report(exp_postfix, ckpts, hy_mean, hy_max, hy_top, hx_mean, hx_max, hx_top)

    link.barrier()
    link.finalize()

def get_data(exp_postfix: str, args: Args, r50_bb, verbose=False):
    test_transform = transforms.Compose([
        transforms.Resize(256),
        transforms.CenterCrop(224),
        transforms.ToTensor(),
        transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225), inplace=True),
    ])
    data_clz, data_kw = {
        'subimagenet': (SubImageNetDataset, dict(
            num_classes=args.subimagenet_num_classes,
            train=args.train, transform=test_transform
        )),
        'liveness': (Liveness, dict(train=args.train)),
        'gender': (Gender, dict(train=args.train)),
        'age': (Age, dict(train=args.train)),
    }[args.dataset]
    test_data = data_clz(**data_kw)
    test_ld = DataLoader(test_data, batch_size=args.batch_size, shuffle=True, drop_last=False, num_workers=2, pin_memory=True)
    tot_bs, tot_correct, inputs, features, labels = 0, 0, [], [], []

    # if r50_bb.fc is not None:
    #     assert r50_bb.fc.bias.numel() == test_data.cls_task_dim

    with torch.no_grad():
        bar = tqdm(test_ld) if verbose else test_ld
        h_dict = {}
        saved = False
        for d in bar:
            inp, tar, im_idx, fnames = d['image'], d['gt'], d['image_id'], d['filename']
            img_hw = tuple(inp.shape[-2:])
            bs = inp.shape[0]
            tot_bs += bs
            desc = '[extracting features]'
            postfix = OrderedDict({'tot_bs': tot_bs, 'cur_bs': bs})
            oup = r50_bb(inp.cuda())
            if tot_bs <= 8000:
                inputs.append(F.avg_pool2d(inp, kernel_size=8).view(bs, -1))
                h = oup['layer4'].cpu()
                for single_f, single_h, label in zip(fnames, h, tar.view(-1)):
                    h_dict[single_f] = [single_h, label]
                features.append(h)
                labels.append(tar.view(bs, 1).int())
            else:
                break

                # if verbose and args.save_fname_to_h and not saved:
                #     saved = True
                #     ckpt_name = f'fname_to_h_{exp_postfix}.pth.tar'
                #     torch.save(h_dict, ckpt_name)
                #     print(f'rk[00] ==> fname_to_h saved @ {ckpt_name}')

                # if r50_bb.fc is None:
                #     break   # calc MI on a subset for saving time

            # if r50_bb.fc is not None:
            #     tot_correct += oup['logits'].argmax(dim=1).eq(tar.cuda()).sum().item()
            #     postfix['acc'] = f'{100. * tot_correct/tot_bs:5.2f}'
            #     desc = '[inference]'

            if verbose:
                bar.set_description_str(desc)
                bar.set_postfix(postfix)
    if verbose:
        bar.clear()
        bar.close()
        # if r50_bb.fc is not None:
        #     print(f'rk[00] ==> final acc: {100. * tot_correct/tot_bs:5.2f}')

    features = torch.cat(features, dim=0)
    labels = torch.cat(labels, dim=0).reshape(-1)
    inputs = torch.cat(inputs, dim=0)
    assert features.shape[0] == labels.shape[0] == inputs.shape[0]

    return img_hw, features, inputs, labels

if __name__ == '__main__':
    main()


#   Nome: Pedro Victor Rodrigues de Carvalho
#   Matrícula: 17/0113043
#   Universidade de Brasília, 2º semestre de 2018
#   Curso: Engenharia de Computação
#   Matéria: Introdução ao Processamento de Imagens
#   Professor: Alexandre Zaghetto

#   Primeira parte do Assignment 1: Processamento de caminho em imagem topológica
#   Linguagem de programação: Python 3

import cv2
import operator

# --------------------------------
#   Start of functions and classes

#       The Pixel class was created so that the program can handle pixels as variables, rather than avulse numbers.
#       It has two built-in functions: setCoordinates and calcDist2Objective.
#       ->setCoordinates: Receives two numbers that will be stored in the instance to be used as the pixel's position
#   coordinates.
#       ->calcDist2Objective: Also receives coordinates, but instead calculates the distance between the instance's
#   coordinates and the "objective" coordinates it received.
class Pixel:
    def __init__(self):
        self.coordinates = [0, 0]
        self.distance = 0

    def setCoordinates(self, coordi, coordj):
        self.coordinates = [coordi, coordj]

    def calcDist2Objective(self, objectivei, objectivej):
        self.distance = (((self.coordinates[0]-objectivei)**2)+((self.coordinates[1]-objectivej)**2))**0.5

#       The bgr2gray function uses the equation used to calculate the Y value in RGB -> YCbCr conversion to succesfully
#   produce a grayscale version of the original image it received in its arguments.
#       Equation: Y = (R*0.299)+(G*0.587)+(B*0.114)
def bgr2gray(image):
    for i in range(0, image.shape[0]):
        for j in range(0, image.shape[1]):
            image[i, j]=(image[i, j, 2]*0.299)+(image[i, j, 1]*0.587)+(image[i, j, 0]*0.114)

#       The equalize function receives a grayscaled image and creates an array with its histogram of gray levels, then
#   computes the Cumulative Probability Function (CDF) in another array. After that, using the CDF, equalizes the image
#   to maximize the level of detail within 8 bits of gray levels.
def equalizeGrayscale(image):
    sum = 0             # Initializing variables
    histogram = [0] * 256
    CDF = [0] * 256

    for i in range(0, image.shape[0]):      # Creating histogram
        for j in range(0, image.shape[1]):
            histogram[image[i, j, 0]] += 1

    for i in range (0, 256):                # Computing CDF
        sum += ((histogram[i]*3)/image.size)
        CDF[i] = sum

    for i in range(0, image.shape[0]):      # Equalizing image
        for j in range(0, image.shape[1]):
            image[i, j] = CDF[image[i, j, 0]]*255

#       The finds3Closest function computes the surrounding pixels given a center pixel. Then, it removes the previous
#   pixel used so that there is no backtracking. After that, it computes the Euclidean distance from the surrounding
#   pixels to the objective and sorts the array that contains these pixels. Lastly, the 3 pixels with the smaller
#   distance are stored in an array to be used by the function's caller.
def finds3Closest(center, objective, previous, pixList):
    neigh1 = Pixel()            # Define neighbours' variables.
    neigh2 = Pixel()
    neigh3 = Pixel()
    neigh4 = Pixel()
    neigh5 = Pixel()
    neigh6 = Pixel()
    neigh7 = Pixel()
    neigh8 = Pixel()

    neigh1.setCoordinates(center.coordinates[0] - 1, center.coordinates[1] - 1)
    neigh2.setCoordinates(center.coordinates[0] - 1, center.coordinates[1]    )
    neigh3.setCoordinates(center.coordinates[0] - 1, center.coordinates[1] + 1)
    neigh4.setCoordinates(center.coordinates[0],     center.coordinates[1] + 1)
    neigh5.setCoordinates(center.coordinates[0] + 1, center.coordinates[1] + 1)
    neigh6.setCoordinates(center.coordinates[0] + 1, center.coordinates[1]    )
    neigh7.setCoordinates(center.coordinates[0] + 1, center.coordinates[1] - 1)
    neigh8.setCoordinates(center.coordinates[0]    , center.coordinates[1] - 1)

    list = [neigh1, neigh2, neigh3, neigh4, neigh5, neigh6, neigh7, neigh8]     # Arrange them in a list of candidates.

    index2eliminate=-1
    for i in range(0, list.__len__()):              # Eliminate previous pixel from candidates to prevent backtracking.
        if list[i].coordinates == previous.coordinates:
            index2eliminate = i
    if index2eliminate > 0:
        del list[index2eliminate]

    for i in range(0, list.__len__()):              # Calculate distance to objective for each candidate.
        list[i].calcDist2Objective(objective.coordinates[0], objective.coordinates[1])

    list.sort(key=operator.attrgetter('distance'))  # Sort list by distance to objective.

    for i in range(0, 3):                           # The 3 first are the 3 closest to the objective.
        pixList[i].setCoordinates(list[i].coordinates[0], list[i].coordinates[1])

#    The choosesDarkestGray function compares 3 pixels in an array and returns the one with the darkest gray level.
def choosesDarkestGray(image, pixList):
    darkest = pixList[0]
    if image[pixList[1].coordinates[0], pixList[1].coordinates[1], 0] < image[darkest.coordinates[0], darkest.coordinates[1], 0]:
        darkest = pixList[1]
    if image[pixList[2].coordinates[0], pixList[2].coordinates[1], 0] < image[darkest.coordinates[0], darkest.coordinates[1], 0]:
        darkest = pixList[2]
    return darkest

#       The colorsPath function receives two images, a pixel and a level of gray to color the corresponding pixels in
#   these two images.
def colorsPath(original, image, pixel, graylvl):
    original[pixel.coordinates[0], pixel.coordinates[1]] = graylvl
    image[pixel.coordinates[0], pixel.coordinates[1]] = graylvl

#   End of functions and classes
# ------------------------------
#   Start of main program

original = cv2.imread("Mars.bmp")   # Load image.
img = cv2.imread("Mars.bmp")

bgr2gray(img)               # Convert image to grayscale.
equalizeGrayscale(img)      # Equalize the grayscaled image.

originPix = Pixel()         # Define origin and objective pixels.
objectivePix = Pixel()
originPix.setCoordinates(260, 415)
objectivePix.setCoordinates(815, 1000)
originPix.calcDist2Objective(objectivePix.coordinates[0], objectivePix.coordinates[1])

candidate1 = Pixel()        # Define pixel candidates to use in path-searching.
candidate2 = Pixel()
candidate3 = Pixel()
candidates = [candidate1, candidate2, candidate3]   # Create array with them.

previousPix = currentPix = originPix    # Define auxiliary variables.
counter = 0

while currentPix.coordinates != objectivePix.coordinates:   # Loops until the current pixel is the objective.
    colorsPath(original, img, currentPix, 255)              # Colors the current pixel white.
    finds3Closest(currentPix, objectivePix, previousPix, candidates)    # Finds 3 candidates for next move.
    nextPix = choosesDarkestGray(img, candidates)           # Determines the darkest between the 3 candidates.
    previousPix = currentPix
    currentPix = nextPix                                    # Moves the current pixel.
    counter += 1

#   Display the image with the path and save the image. Also save an equalized version of the path for analysis.
cv2.imshow("path", original)
cv2.waitKey(0)
cv2.imwrite("path.bmp", original)
cv2.imwrite("pathEQ.bmp", img)
print("Image file with path saved in program directory.")
print("Actual path length (in pixels):")    # Print the path's length in pixels in the terminal.
print(counter)
print("Straight distance between origin and objective (Euclidean distance):")    # Prints the origin's euclidean
print(originPix.distance)                                               # distance to the objective in the terminal.
cv2.destroyAllWindows()

#   End of main program


# TensorFlow and tf.keras
import os
import struct

import tensorflow as tf
from tensorflow import keras

# Helper libraries
import numpy as np
import matplotlib.pyplot as plt
import datetime

import read_local_mnist

epochs_time = 100

def train():

    # you can download mnist from http://yann.lecun.com/exdb/mnist/
    train_images = read_local_mnist.load_train_images('input_data/train-images.idx3-ubyte')
    train_labels = read_local_mnist.load_train_labels('input_data/train-labels.idx1-ubyte')
    test_images = read_local_mnist.load_test_images('input_data/t10k-images.idx3-ubyte')
    test_labels = read_local_mnist.load_test_labels('input_data/t10k-labels.idx1-ubyte')

    class_names = ['0', '1', '2', '3', '4',
                   '5', '6', '7', '8', '9']

    train_images = train_images / 255.0
    test_images = test_images / 255.0

    print(train_images[0])

    model = keras.Sequential([
        keras.layers.Flatten(input_shape=(28, 28)),
        keras.layers.Dense(128, activation=tf.nn.relu),
        keras.layers.Dense(10, activation=tf.nn.softmax)
    ])

    model.compile(optimizer='adam',
                  loss='sparse_categorical_crossentropy',
                  metrics=['accuracy'])
    model.fit(train_images, train_labels, epochs=epochs_time)

    test_loss, test_acc = model.evaluate(test_images, test_labels)

    print('Test accuracy:', test_acc)

    modelname = "keras_mnist_model" + str(datetime.datetime.now().strftime('%m%d%H%M%S')) + \
                "_epochs" + str(epochs_time) + ".h5"
    model.save(modelname)

    predictions = model.predict(test_images)

    print(predictions[0])
    print(np.argmax(predictions[0]))
    print(test_labels[0])

    def plot_image(i, predictions_array, true_label, img):
        predictions_array, true_label, img = predictions_array[i], true_label[i], img[i]
        true_label = int(true_label)
        plt.grid(False)
        plt.xticks([])
        plt.yticks([])

        plt.imshow(img, cmap=plt.cm.binary)
        print("prediction array:", predictions_array)
        print("true_label:", true_label)
        predicted_label = np.argmax(predictions_array)
        if predicted_label == true_label:
            color = 'blue'
        else:
            color = 'red'

        plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label],
                                             100 * np.max(predictions_array),
                                             class_names[true_label]),
                   color=color)

    def plot_value_array(i, predictions_array, true_label):
        predictions_array, true_label = predictions_array[i], true_label[i]
        true_label = int(true_label)
        plt.grid(False)
        plt.xticks([])
        plt.yticks([])
        thisplot = plt.bar(range(10), predictions_array, color="#777777")
        plt.ylim([0, 1])
        predicted_label = np.argmax(predictions_array)

        thisplot[predicted_label].set_color('red')
        thisplot[true_label].set_color('blue')

    i = 0
    plt.figure(figsize=(6, 3))
    plt.subplot(1, 2, 1)
    plot_image(i, predictions, test_labels, test_images)
    plt.subplot(1, 2, 2)
    plot_value_array(i, predictions, test_labels)
    plt.show()

    # Plot the first X test images, their predicted label, and the true label
    # Color correct predictions in blue, incorrect predictions in red
    num_rows = 5
    num_cols = 3
    num_images = num_rows * num_cols
    plt.figure(figsize=(2 * 2 * num_cols, 2 * num_rows))
    for i in range(num_images):
        plt.subplot(num_rows, 2 * num_cols, 2 * i + 1)
        plot_image(i, predictions, test_labels, test_images)
        plt.subplot(num_rows, 2 * num_cols, 2 * i + 2)
        plot_value_array(i, predictions, test_labels)
    plt.show()

    # Grab an image from the test dataset
    img = test_images[0]
    print(img.shape)

    # Add the image to a batch where it's the only member.
    img = (np.expand_dims(img, 0))
    print(img.shape)

    predictions_single = model.predict(img)
    print(predictions_single)

    plot_value_array(0, predictions_single, test_labels)
    _ = plt.xticks(range(10), class_names, rotation=45)
    plt.show()

def showimage():
    train_images, train_labels = load_mnist('input_data', 'train')

    print(train_images[0])

    plt.figure()
    plt.imshow(train_images[0])
    plt.colorbar()
    plt.grid(False)
    plt.show()

    fig, ax = plt.subplots(
        nrows=5,
        ncols=5,
        sharex=True,
        sharey=True, )

    ax = ax.flatten()
    for i in range(25):
        img = train_images[train_labels == 6][i].reshape(28, 28)
        ax[i].imshow(img, cmap='Greys', interpolation='nearest')

    ax[0].set_xticks([])
    ax[0].set_yticks([])
    plt.tight_layout()
    plt.show()

    fig, ax = plt.subplots(
        nrows=2,
        ncols=5,
        sharex=True,
        sharey=True, )
    ax = ax.flatten()
    for i in range(10):
        img = train_images[train_labels == i][0].reshape(28, 28)
        ax[i].imshow(img, cmap='Greys', interpolation='nearest')

    ax[0].set_xticks([])
    ax[0].set_yticks([])
    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    # showimage()
    train()