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

# # Desafio 4
#
# Neste desafio, vamos praticar um pouco sobre testes de hipóteses. Utilizaremos o _data set_ [2016 Olympics in Rio de Janeiro](https://www.kaggle.com/rio2016/olympic-games/), que contém dados sobre os atletas das Olimpíadas de 2016 no Rio de Janeiro.
#
# Esse _data set_ conta com informações gerais sobre 11538 atletas como nome, nacionalidade, altura, peso e esporte praticado. Estaremos especialmente interessados nas variáveis numéricas altura (`height`) e peso (`weight`). As análises feitas aqui são parte de uma Análise Exploratória de Dados (EDA).
#
# > Obs.: Por favor, não modifique o nome das funções de resposta.

# ## _Setup_ geral

# In[1]:

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as sct
import statsmodels.api as sm
import seaborn as sns

# In[3]:

'''%matplotlib inline

from IPython.core.pylabtools import figsize

figsize(12, 8)

sns.set()'''

# In[2]:

athletes = pd.read_csv("athletes.csv")

# In[3]:

def get_sample(df, col_name, n=100, seed=42):
    """Get a sample from a column of a dataframe.

    It drops any numpy.nan entries before sampling. The sampling
    is performed without replacement.

    Example of numpydoc for those who haven't seen yet.

    Parameters
    ----------
    df : pandas.DataFrame
        Source dataframe.
    col_name : str
        Name of the column to be sampled.
    n : int
        Sample size. Default is 100.
    seed : int
        Random seed. Default is 42.

    Returns
    -------
    pandas.Series
        Sample of size n from dataframe's column.
    """
    np.random.seed(seed)

    random_idx = np.random.choice(df[col_name].dropna().index, size=n, replace=False)

    return df.loc[random_idx, col_name]

# ## Inicia sua análise a partir daqui

# In[7]:

amostra = get_sample(athletes, 'height', n=3000)

# ## Questão 1
#
# Considerando uma amostra de tamanho 3000 da coluna `height` obtida com a função `get_sample()`, execute o teste de normalidade de Shapiro-Wilk com a função `scipy.stats.shapiro()`. Podemos afirmar que as alturas são normalmente distribuídas com base nesse teste (ao nível de significância de 5%)? Responda com um boolean (`True` ou `False`).

# In[6]:

def q1():
    result_q1 = sct.shapiro(amostra)
    return result_q1[1] > 0.05

# __Para refletir__:
#
# * Plote o histograma dessa variável (com, por exemplo, `bins=25`). A forma do gráfico e o resultado do teste são condizentes? Por que?
#
#     Não, pois apenas pela análise do gráfico poderíamos dizer que se trata de uma distribuição próxima à uma distribuição normal.
#
#
# * Plote o qq-plot para essa variável e a analise.
#
#     Mais uma vez o gráfico aponta uma distribuição próxima do normal, o que pode indicar estarmos diante de um erro tipo I.
#
#
# * Existe algum nível de significância razoável que nos dê outro resultado no teste? (Não faça isso na prática. Isso é chamado _p-value hacking_, e não é legal).
#
#     Não, pois o valor de $p$ encontrado é muito baixo nessa amostra. Entretanto, se pegássemos uma amostra com tamanho bem menor (abaixo de 350) começamos a encontrar valores diferentes para o mesmo teste, com o mesmo nível de significância.

# In[5]:

#Histograma da variável
sns.distplot(amostra, bins=25);

# In[6]:

#QQ-plot da variável
sm.qqplot(amostra, fit=True, line="45");

# ## Questão 2
#
# Repita o mesmo procedimento acima, mas agora utilizando o teste de normalidade de Jarque-Bera através da função `scipy.stats.jarque_bera()`. Agora podemos afirmar que as alturas são normalmente distribuídas (ao nível de significância de 5%)? Responda com um boolean (`True` ou `False`).

# In[7]:

def q2():
    result_q2 = sct.jarque_bera(amostra)
    return bool(result_q2[1] > 0.05)

# __Para refletir__:
#
# * Esse resultado faz sentido?
#
#     Esse resultado foi o mesmo obtido com o teste de Shapiro, o que afirma que há evidências que a amostra não se trata de uma distruibição normal.

# ## Questão 3
#
# Considerando agora uma amostra de tamanho 3000 da coluna `weight` obtida com a função `get_sample()`. Faça o teste de normalidade de D'Agostino-Pearson utilizando a função `scipy.stats.normaltest()`. Podemos afirmar que os pesos vêm de uma distribuição normal ao nível de significância de 5%? Responda com um boolean (`True` ou `False`).

# In[7]:

amostra2 = get_sample(athletes, 'weight', n=3000)

# In[ ]:

def q3():
    result_q3 = sct.normaltest(amostra2)
    return bool(result_q3.pvalue > 0.05)

# __Para refletir__:
#
# * Plote o histograma dessa variável (com, por exemplo, `bins=25`). A forma do gráfico e o resultado do teste são condizentes? Por que?
#
#     Sim, o formato do gráfico mostra uma média descentralizada dos dados, havendo a formação de uma cauda mais longa de um dos lados do histograma, o que indica não se tratar de uma distribuição normal.
#
#
# * Um _box plot_ também poderia ajudar a entender a resposta.

# In[18]:

sns.distplot(amostra2, bins=25);

# In[19]:

#Boxplot da amostra, mostrando haver vários outliers e um posicionamento da mediana mais próximo do valor mínimo da amostra.
sns.boxplot(amostra2);

# ## Questão 4
#
# Realize uma transformação logarítmica em na amostra de `weight` da questão 3 e repita o mesmo procedimento. Podemos afirmar a normalidade da variável transformada ao nível de significância de 5%? Responda com um boolean (`True` ou `False`).

# In[21]:

amostra2_log = np.log(amostra2)

# In[ ]:

def q4():
    result_q4 = sct.normaltest(amostra2_log)
    return bool(result_q4[1] > 0.05)

# __Para refletir__:
#
# * Plote o histograma dessa variável (com, por exemplo, `bins=25`). A forma do gráfico e o resultado do teste são condizentes? Por que?
#
#     Apesar de o gráfico ter diminuído a cauda alongada, a média dos dados ainda não está bem centralizada, de maneira que o gráfico está condizente com o resultado.
#
#
# * Você esperava um resultado diferente agora?
#
#     Talvez. A tranformação logarítimica pode diminuir o viés de uma distribuição que possui um dos lado elevados ou uma cauda alongada, mas não é certo.

# In[22]:

sns.distplot(amostra2_log);

# > __Para as questão 5 6 e 7 a seguir considere todos testes efetuados ao nível de significância de 5%__.

# ## Questão 5
#
# Obtenha todos atletas brasileiros, norte-americanos e canadenses em `DataFrame`s chamados `bra`, `usa` e `can`,respectivamente. Realize um teste de hipóteses para comparação das médias das alturas (`height`) para amostras independentes e variâncias diferentes com a função `scipy.stats.ttest_ind()` entre `bra` e `usa`. Podemos afirmar que as médias são estatisticamente iguais? Responda com um boolean (`True` ou `False`).

# In[23]:

bra = athletes.loc[athletes.nationality == 'BRA', ['height']]
usa = athletes.loc[athletes.nationality == 'USA', ['height']]
can = athletes.loc[athletes.nationality == 'CAN', ['height']]

# In[ ]:

def q5():
    stats, p = sct.ttest_ind(bra, usa, equal_var = False, nan_policy = 'omit')
    #(stats == -3.2232436467501855, p == 0.0013080041830140115)
    return float(p) > 0.05

# ## Questão 6
#
# Repita o procedimento da questão 5, mas agora entre as alturas de `bra` e `can`. Podemos afimar agora que as médias são estatisticamente iguais? Reponda com um boolean (`True` ou `False`).

# In[11]:

def q6():
    stats, p = sct.ttest_ind(bra, can, equal_var = False, nan_policy = 'omit')
    #(stats == 0.6389304914365109, p == 0.5230827295440921)
    return float(p) > 0.05

# ## Questão 7
#
# Repita o procedimento da questão 6, mas agora entre as alturas de `usa` e `can`. Qual o valor do p-valor retornado? Responda como um único escalar arredondado para oito casas decimais.

# In[12]:

def q7():
    stats, p = sct.ttest_ind(usa, can, equal_var = False, nan_policy = 'omit')
    #(stats == 3.516987632488539, p == 0.0004660129347389851)
    return float(np.round(float(p), 8))

# __Para refletir__:
#
# * O resultado faz sentido?
#
#     A diferença entre as médias das amostras apresentadas fica de cerca de 2cm a 3 cm entre brasileiros e americanos e canadenses e americanos, e portanto nesses casos há evidências para rejeitar a hipótese nula, que é de que as médias de altura dos atletas são iguais. Já entre a média de alturas da amostra de brasileiros e canadenses, a diferença ficou em 0.05. Desta forma, não podemos rejeitar a hipótese nula apenas diante dessa amostra apresentada. Desta forma, o resultado apresentado faz sentido, tendo em vista, principalmente, que realizamos o experimento apenas com uma amostra da população uma única vez.
#
#
# * Você consegue interpretar esse p-valor?
#
#     O p-valor é interpretado como o que se espera que aconteça com o mesmo experimento quando feito diversas vezes com amostras diferentes. Desta forma, espera-se que com amostras diferentes das alturas dos atletas dessas nacionalidades, a comparação das médias saia da diferença aceitável apenas 5% das vezes tentadas. Fazendo-se vários testes em que aponta-se que não se pode rejeitar a hipótese nula, portanto, não há provas que as médias são iguais, mas há boa chance de ser.
#
#
# * Você consegue chegar a esse valor de p-valor a partir da variável de estatística?
#
#     No teste da questão 5 o p-valor encontrado foi de __0.0013__, e localizado através do t-valor na tabela t o p-valor ficou __entre 0.002 e 0.001__.
#     No teste da questão 6 o p-valor encontrado foi de __0.5230__, e localizado através do t-valor na tabela t o p-valor ficou __entre 1.0 e 0.5__.
#     No teste da questão 7 o p-valor encontrado foi de __0.00046__, e localizado através do t-valor na tabela t o p-valor ficou __abaixo de 0.001__.

# In[51]:

bra.mean() - usa.mean()

# In[49]:

bra.mean() - can.mean()

# In[50]:

usa.mean() - can.mean()

# In[ ]:


import unittest
from src.backends import poeofficial, poetrade
from src.constants import currencies

class BackendTest(unittest.TestCase):

    def test_currency_mappings(self):
        for key in currencies.keys():
            assert (poeofficial.map_currency(key) is not None)

    def test_fetch_offers(self):
        league = "Standard"
        want = "Chaos Orb"
        have = "Chromatic Orb"

        poe_official_single = poeofficial.fetch_offers_for_pair(
            league, want, have)
        poe_official_many = poeofficial.fetch_offers(league, [(want, have)])
        poe_trade_single = poetrade.fetch_offers_for_pair(league, want, have)
        poe_trade_many = poetrade.fetch_offers(league, [(want, have)])

        for struct in [poe_official_single] + poe_official_many + [poe_official_single] + poe_trade_many:
            assert ("offers" in struct.keys()) == True
            assert len(struct["offers"]) > 0
            assert struct["want"] == want
            assert struct["have"] == have
            assert struct["league"] == league


class Solution:
    def coinChange(self, coins: list[int], amount: int) -> int:
        #dp[i]是指，金额为i时候，最少需要几个硬币，于是，推导公式变成
        #dp[i] = min(dp[i],dp[i-coin[j]]+1),例如我是11，我可以用6元钱时候最小个数，+一个5元就可以
        #初始化为amount+1，就是说比全1元硬币还要多一个1
        dp = [amount+1]*(amount+1)
        dp[0]=0
        for i in range(1,amount+1):
            for coin in coins:
                if coin<=i:
                    dp[i] = min(dp[i],dp[i-coin]+1)
        return dp[amount] if dp[amount]<=amount else -1
'''
322. Coin Change
Medium
You are given an integer array coins representing coins of different denominations and an integer amount representing a total amount of money.

Return the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.

You may assume that you have an infinite number of each kind of coin.

Example 1:

Input: coins = [1,2,5], amount = 11
Output: 3
Explanation: 11 = 5 + 5 + 1
Example 2:

Input: coins = [2], amount = 3
Output: -1
Example 3:

Input: coins = [1], amount = 0
Output: 0

Constraints:

1 <= coins.length <= 12
1 <= coins[i] <= 231 - 1
0 <= amount <= 104
'''


"""Module to handle the Podcast object"""

import random
import names

from agent.ai_agent import AiAgent

GENDERS = ["female", "male"]

class Podcast:
    """class to manage the interaction between the user and the AI agent
    the class will output the text to the user"""

    def __init__(self, user_name) -> None:
        self.user_name = user_name
        self.topic = None
        self.expert = None

    def set_topic(self, topic):
        """sets the topic of the podcast"""
        self.topic = topic

    def generate_ai_agent(self):
        """creates an ai agent on the defined topic"""
        if self.topic is not None:
            agent_gender = random.choice(GENDERS)
            agent_name = names.get_full_name(gender=agent_gender)
            self.expert = AiAgent(agent_name, agent_gender, self.topic)
        else:
            print("You need to select a topic first")

    def introduce_agent(self):
        """generates and returns an introduction string"""
        introduction = f""" Hello {self.expert.name}, please meet {self.user_name}.
        {self.expert.name} will be today's episode expert on the topic {self.topic}.
        {self.expert.name}, do you mind giving an introduction about yourself?"""
        print(introduction)
        self.expert.receive_message(introduction)

    def start_conversation(self):
        self.expert.start_chat()


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

class HAR(nn.Module):
    def __init__(self):
        super(HAR, self).__init__()
        self.shared_conv = nn.Sequential(
            nn.Conv1d(in_channels=1, out_channels=16, kernel_size=2, stride=1, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool1d(2, 2),
            nn.Conv1d(in_channels=16, out_channels=16, kernel_size=2, stride=1, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool1d(2, 2),
            nn.Conv1d(in_channels=16, out_channels=32, kernel_size=2, stride=1, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool1d(2, 2),
            nn.Conv1d(in_channels=32, out_channels=32, kernel_size=2, stride=1, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool1d(2, 2),
            nn.Flatten()
        )

        self.shared_clf = nn.Sequential(
            nn.Linear(1184, 256),
            nn.ReLU(inplace=True),
            nn.Linear(256, 6)
        )

    def forward(self, x):
        x = self.shared_conv(x)
        x = self.shared_clf(x)
        return x

if __name__ == '__main__':
    import torch
    model = HAR()
    _x = torch.rand((50, 1, 561))
    _output = model(_x)
    print(f'{_x.shape}->{_output.shape}')
    print("Parameters in total {}".format(sum(x.numel() for x in model.parameters())))


import os,sys
import pdb

all_fn = sys.argv[1]
test_fn = sys.argv[2]

tmp = open(test_fn,"r").read().strip("\n").split("\n")

test_text = []
for line in tmp[1:]:
	line = line.replace('""','"')
	if line[0] == '"':
		line = line[1:]
	test_text.append(line)

test_file = open("test.tsv","w")

# pdb.set_trace()

found = set()

for line in open(all_fn,"r"):
	line = line.strip("\n")
	if line=="": continue
	text,label = line.split("\t")
	is_in = False
	for test_chars in test_text:
		if any([
				 text[:20] == test_chars[:20],
				 text[:30] == test_chars[:30],
				]):
			is_in = True
			found.add(test_chars)
			break
	#
	if is_in:
		print(line,file=test_file)
#
test_file.close()

# for test_chars in test_text:
# 	if test_chars not in found:
# 		print(test_chars)
# 		pdb.set_trace()


'''
Created on 2 Jul 2017

@author: david
'''
import numpy as np
import os, cv2, sys
os.environ["TF_CPP_MIN_LOG_LEVEL"]="2"
import tensorflow as tf
import os.path
import pickle as pi
import logging
logging.getLogger("tensorflow").setLevel(logging.ERROR)
tf.logging.set_verbosity(tf.logging.ERROR)

from model.config import cfg
from model.test import _get_blobs
from davelib.compression_stats import CompressionStats
from davelib.profile_stats import ProfileStats
from davelib.base_net import BaseNetWrapper
from davelib.separable_net import SeparableNet
from davelib.pluripotent_net import PluripotentNet
from davelib.layer_name import *
from davelib.optimise_compression import OptimisationResults, plot_results_from_file
from davelib.utils import show_all_variables, show_all_nodes, colour, timer, TimingResults
from davelib.optimisation_manager import OptimisationManager
from davelib.compressed_net_description import *

from tensorflow.python.framework import constant_op, dtypes
from tensorflow.python.ops import math_ops, array_ops, control_flow_ops
from tensorflow.python.framework.test_util import TensorFlowTestCase

sys.path.append('/home/david/Project/35_tf-faster-rcnn/tools')

def get_blobs(im_names):
    blobs_list = []
    for im_name in im_names:
      im_file = os.path.join(cfg.DATA_DIR, 'demo', im_name)
      im = cv2.imread(im_file)
      blobs, im_scales = _get_blobs(im)
      assert len(im_scales) == 1, "Only single-image batch implemented"
      im_blob = blobs['data']
      blobs['im_info'] = np.array([[im_blob.shape[1], im_blob.shape[2], im_scales[0]]], dtype=np.float32)
      blobs_list.append(blobs)
    return blobs_list

class ExperimentController(TensorFlowTestCase):

  def __init__(self, base_net, sess, saved_model_path, tfconfig, stats_file_suffix):
#     show_all_variables(True, base_net.get_scope())
    self._compressed_layers = None
    self._base_net = base_net
    self._base_net_wrapper = BaseNetWrapper(base_net)
    self._sess = sess
    self._saved_model_path = saved_model_path
    self._tfconfig = tfconfig
#     im_names = ['000456.jpg', '000542.jpg']
#     im_names = ['000456.jpg', '000542.jpg', '001150.jpg', '001763.jpg', '004545.jpg']
    im_names = ['000456.jpg']

    self._blobs_list = get_blobs(im_names)
#     self._final_layers = [LayerName('cls_score')]
    self._final_layers = [LayerName('cls_prob'), LayerName('bbox_pred'),
                          LayerName('cls_score'), LayerName('rois')]
#     self._final_layers = [LayerName('cls_prob'), LayerName('bbox_pred'), LayerName('rois')]

    if os.path.isfile('base_outputs.pi') and os.path.isfile('base_profile_stats.pi'):
#     if False and os.path.isfile('base_outputs.pi') and os.path.isfile('base_profile_stats.pi'):
      self._base_outputs_list = pi.load( open( 'base_outputs.pi', "rb" ) )
      self._base_profile_stats = pi.load( open( 'base_profile_stats.pi', "rb" ) )
    else:
      self._base_outputs_list, run_metadata_list = base_net.get_outputs_multi_image(self._blobs_list,
                                         self._final_layers, sess)
      self._base_profile_stats = ProfileStats(run_metadata_list, tf.get_default_graph())
      pi.dump( self._base_outputs_list, open( 'base_outputs.pi', "wb" ) )
      pi.dump( self._base_profile_stats, open( 'base_profile_stats.pi', "wb" ) )

    self._base_variables = tf.global_variables()
    self._all_Kmaxs_dict = calc_all_Kmaxs()
    self._compression_stats = CompressionStats(filename_suffix=stats_file_suffix,
                                               load_from_file=False)
    self.get_var_dicts()

  def get_var_dicts(self):
    self._all_comp_weights_dict = {}
    self._comp_bn_vars_dict = {}
    self._comp_bias_vars_dict = {}
    names_to_vars = {}
    with self._sess.as_default():
      with tf.variable_scope(self._base_net._resnet_scope, reuse=True):
        for layer_name in get_all_compressible_layers():
          weights = tf.get_variable(layer_name.layer_weights())
          names_to_vars[layer_name] = weights

          for bn_type in ['beta','gamma','moving_mean','moving_variance']:
            bn_var_name = layer_name+'/BatchNorm/'+bn_type
            try:
              bn_var = tf.get_variable(bn_var_name)
            except ValueError:
              continue #means this compressed layer doesn't have BatchNorm
            names_to_vars[bn_var_name] = bn_var

          bias_var_name = layer_name+'/biases'
          try:
            bias_var = tf.get_variable(bias_var_name)
          except ValueError:
            continue #means this compressed layer doesn't have biases
          names_to_vars[bias_var_name] = bias_var

      names = list(names_to_vars.keys())
      vars_ = list(names_to_vars.values())
      tensor_values = self._sess.run( vars_ )

      for name, tensor_value in zip(names, tensor_values):
        if 'BatchNorm' in name:
          self._comp_bn_vars_dict[name] = tensor_value
        elif 'biases' in name:
          self._comp_bias_vars_dict[name] = tensor_value
        else:
          self._all_comp_weights_dict[name] = tensor_value

  def _get_next_model(self, layer_K_dict, efficiency_dict, performance_dict,
                      perf_metric_increases_with_degradation, simple=True):
    def get_K_old_new(layer):
      def get_next_K(K_old):
        idx = sorted_keys.index( K_old )
        if idx+1 < len(sorted_keys):
          K_new = sorted_keys[idx + 1]
        else:
          K_new = 0
        return K_new

      sorted_keys = list(reversed(sorted(efficiency_dict[layer].keys())))
      if layer in layer_K_dict:
        K_old = layer_K_dict[layer]
        K_new = get_next_K(K_old)
      else:
        K_old = 0
        K_new = sorted_keys[0] #start with the largest K value
        efficiency_delta = efficiency_dict[layer][K_new]
        if efficiency_delta == 0:
          K_new = get_next_K(K_new) #hack to skip the first flops item
      return K_old, K_new

    grad_dict = {}
    perf_delta_dict = {}
    efficiency_delta_dict = {}
    for layer in efficiency_dict:
      K_old, K_new = get_K_old_new(layer)
      if K_new == 0: #max compression reached for this layer
        continue
      elif K_old != 0: #already compressed this layer a bit
        efficiency_delta = efficiency_dict[layer][K_new] - efficiency_dict[layer][K_old]
        performance_delta = performance_dict[layer][K_new] - performance_dict[layer][K_old]
      else: #this layer hasn't been compressed at all yet
        efficiency_delta = efficiency_dict[layer][K_new]
        performance_delta = performance_dict[layer][K_new]

      if simple:
        efficiency_grad = efficiency_delta
      else:
        efficiency_grad = efficiency_delta / performance_delta
      if not perf_metric_increases_with_degradation:
        efficiency_grad *= -1.0
      grad_dict[efficiency_grad] = layer
      perf_delta_dict[layer] = performance_delta
      efficiency_delta_dict[layer] = efficiency_delta

    grad_min = list(sorted(grad_dict))[0]
    layer_with_min_grad = grad_dict[grad_min]
    K_old, K_new = get_K_old_new(layer_with_min_grad)
    layer_K_dict[layer_with_min_grad] = [K_new]
    expected_perf_delta = perf_delta_dict[layer_with_min_grad]
    expected_efficiency_delta = efficiency_delta_dict[layer_with_min_grad]

    print(colour.RED + '%s: K:%d\u2192%d'%(layer_with_min_grad,K_old,K_new) + colour.END)

    return layer_K_dict, expected_perf_delta, expected_efficiency_delta, \
            CompressionStep(layer_with_min_grad, K_old, K_new)

  def _get_next_Kfrac(self, Kfrac):
    print('All layers Kfrac=%.3f'%(Kfrac))
    return self.build_net_desc([Kfrac]), None

  def run_optimise_mgr(self, max_iter, stats_file_suffix):
    opt_mgr = OptimisationManager(stats_file_suffix, self)
    opt_mgr.run_search(max_iter)

  def optimise_with_plurinet(self, max_iter, stats_file_suffix):
    guide_compression_stats = CompressionStats(filename_suffix=stats_file_suffix,
                                load_from_file=True, all_Kmaxs_dict=self._all_Kmaxs_dict)

    guide_compression_stats.add_missing_mAP_deltas( self.get_mAP_base_net([100]) )

    stats_dict = guide_compression_stats.build_label_layer_K_dict()
#     efficiency_label = 'float_ops_frac_delta'
    efficiency_label = 'output_bytes_frac_delta'
#     efficiency_label = 'param_output_bytes_frac_delta'
    performance_label = 'mAP_10_top150_delta'
    guide_performance_label = 'mAP_100_top150_delta'
#     performance_label = 'diff_mean_cls_score'
    perf_metric_increases_with_degradation = False
#     performance_label = 'diff_mean_cls_prob'
    use_simple = False #if false use the compound greedy serach

    compressed_layers = get_all_compressible_layers()
    compressed_layers = remove_all_conv_1x1(compressed_layers)
    comp_layer_label='noconv1x1'
#     compressed_layers = keep_only_conv_not_1x1(compressed_layers)
#     compressed_layers = [LayerName('conv1')]
#     comp_layer_label='conv1'
#     compressed_layers = [LayerName('block4/unit_3/bottleneck_v1/conv2')]
#     comp_layer_label='b4_u3_conv2'
    Kfracs = [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]
    Kfracs_label='0.1-1.0'
#     Kfracs = [0.5]
    num_imgs_list=[10]
    output_layers = []
#     output_layers = self._final_layers
    old_performance_metric = 0

    filename = 'pluri_net_' + Kfracs_label + '_' + comp_layer_label

    pluri_net, mAP_base_net = self.init_plurinet(num_imgs_list, compressed_layers, Kfracs, filename)

    efficiency_dict = stats_dict[efficiency_label] #layer->K
    performance_dict = stats_dict[guide_performance_label]
    compression_stats = CompressionStats(load_from_file=False)

    efficiency_dict_keys = remove_all_conv_1x1(efficiency_dict.keys())
    efficiency_dict_keys.remove('bbox_pred') #must remove or it will always 'win' as has no effect on cls_score
    efficiency_dict = { k: efficiency_dict[k] for k in efficiency_dict_keys }
#     efficiency_dict = remove_all_except_conv2_first_conv1(efficiency_dict)

    def remove_positive_delta_compressions(efficiency_dict):
      new_dict = {}
      for k, d in efficiency_dict.items():
        d2 = {K: val for K, val in d.items() if val<0}
        if len(d2) > 0:
          new_dict[k] = d2
      return new_dict

    efficiency_dict = remove_positive_delta_compressions(efficiency_dict)
    cum_efficiency_delta = 0
    opt_results = []
    layer_K_dict = {}

    for itern in range(max_iter):#each iteration compresses 1 layer (a bit more)
      print(str(itern+1), end=' ')
      layer_K_dict, expected_perf_delta, expected_efficiency_delta, net_change = \
                    self._get_next_model(layer_K_dict, efficiency_dict, performance_dict,
                                         perf_metric_increases_with_degradation, use_simple)
#     for Kfrac in reversed(Kfracs):
#       layer_K_dict, expected_perf_delta = self._get_next_Kfrac(Kfrac)
#
      net_desc = CompressedNetDescription(layer_K_dict)
      pluri_net.set_active_path_through_net(net_desc, self._sess)

      pluri_net.run_performance_analysis(net_desc, self._blobs_list, self._sess, self._base_outputs_list,
                                     output_layers, compression_stats,
                                     self._base_profile_stats, mAP_base_net, num_imgs_list,
                                     run_profile_stats=False)

      new_performance_metric = compression_stats.get(net_desc, performance_label)
      actual_perf_delta = new_performance_metric - old_performance_metric
      print('\t%s=%f'%(performance_label,new_performance_metric))

      opt_results.append( OptimisationResults(expected_efficiency_delta, actual_perf_delta, expected_perf_delta,
                          net_desc, net_change, performance_label, efficiency_label) )

      cum_efficiency_delta += expected_efficiency_delta
      print('\t%s=%f'%(efficiency_label,cum_efficiency_delta))
      if expected_perf_delta:
        print('\texpected/actual \u0394perf=%.3f / %.3f'%(expected_perf_delta,actual_perf_delta))
      old_performance_metric = new_performance_metric

      pi.dump( opt_results, open( 'opt_results_output_bytes_clsscore', "wb" ) )

    print('Final optimised net description:\n' + str(net_desc))

    type_labels = ['float_ops_frac_delta','float_ops_count_delta',
                   'output_bytes_frac_delta','output_bytes_count_delta',
                   'parameters_frac_delta','parameters_count_delta']
    compression_stats.plot_data_type_by_Kfracs(type_labels)

  def run_split_net_exp(self, num_imgs, ):
    compressed_layers_all = get_all_compressible_layers()
    compressed_layers_all = keep_only_conv_not_1x1(compressed_layers_all)
    layer_idxs = [0]
    mAP_base_net = self._base_net_wrapper.mAP(num_imgs, cfg.TEST.RPN_POST_NMS_TOP_N, self._sess)

    def run_this_split(compressed_layers):
      scope_idx=1
      for l, layer_name in enumerate(compressed_layers):
        if l not in layer_idxs:
          continue
        self._compressed_layers = compressed_layers

        Kfracs = np.arange(0.7, 1.0, 0.05)
#         Kfracs = [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]
#         Kfracs = [0.5]
        for Kfrac in Kfracs:
          self._sess.close() #restart session to free memory and to reset profile stats
          tf.reset_default_graph()
          self._sess = tf.Session(config=self._tfconfig)

          net_desc = self.build_net_desc(Kfrac)

          sep_net = SeparableNet(scope_idx, self._base_net, self._sess, self._saved_model_path,
                                 self._all_comp_weights_dict, net_desc, self._base_variables)

          sep_net.run_performance_analysis(self._blobs_list, self._sess, self._base_outputs_list,
                                           self._final_layers, self._compression_stats,
                                           self._base_profile_stats, mAP_base_net, num_imgs,
                                           run_profile_stats=False)
          self._compression_stats.set(net_desc, 'Kfrac', Kfrac)
          self._compression_stats.save()
          print(layer_name + ' Kfrac=' + str(Kfrac) + ' complete')
          scope_idx += 1
  #         show_all_variables(True, sep_net._net_sep.get_scope())

    self._final_layers = [LayerName('rois')]
    compressed_layers = remove_all_layers_after_rois(compressed_layers_all)
    run_this_split(compressed_layers)

    self._final_layers = [LayerName('cls_prob'), LayerName('bbox_pred')]
    num_imgs = 0 #stops calc of mAP
    compressed_layers = remove_all_layers_before_rois(compressed_layers_all)
    run_this_split(compressed_layers)

  def get_mAP_base_net(self, num_imgs_list):
    if len(num_imgs_list) > 0:
      mAP_dict = self._base_net_wrapper.mAP(num_imgs_list, cfg.TEST.RPN_POST_NMS_TOP_N, self._sess)
      max_num_imgs = sorted(num_imgs_list)[-1]
      mAP_base_net = mAP_dict[max_num_imgs]

      base_net_desc = CompressedNetDescription({})
      for num_imgs, mAP in mAP_dict.items():
        self._compression_stats.set(base_net_desc, 'mAP_%d_top%d'%(num_imgs,cfg.TEST.RPN_POST_NMS_TOP_N), mAP)
      self._compression_stats.save()
    else:
      mAP_base_net = 0
    return mAP_base_net

  def init_plurinet(self, num_imgs_list, compressed_layers, Kfracs, filename):
    mAP_base_net = self.get_mAP_base_net(num_imgs_list)
    self._compressed_layers = compressed_layers
    net_desc_pluri = build_pluri_net_desc(Kfracs, compressed_layers)

    self._sess.close() #restart session to free memory and to reset profile stats
    tf.reset_default_graph()
    self._sess = tf.Session(config=self._tfconfig)

    pluri_net = PluripotentNet(self._base_net, self._sess, self._saved_model_path,
                             self._all_comp_weights_dict, self._comp_bn_vars_dict, self._comp_bias_vars_dict,
                             net_desc_pluri, self._base_variables, filename=filename)

    return pluri_net, mAP_base_net

  def mAP_for_net(self, net_desc, num_imgs):
    self._sess.close() #restart session to free memory and to reset profile stats
    tf.reset_default_graph()
    self._sess = tf.Session(config=self._tfconfig)

    num_imgs_list = [num_imgs]
    sep_net = SeparableNet(self._base_net, self._sess, self._saved_model_path,
                         self._all_comp_weights_dict, self._comp_bn_vars_dict,
                         self._comp_bias_vars_dict, net_desc, self._base_variables)

    mAP_base_net = self.get_mAP_base_net(num_imgs_list)
    compression_stats = CompressionStats(load_from_file=False)

    with timer('run_performance_analysis'):
      sep_net.run_performance_analysis(net_desc, self._blobs_list, self._sess, self._base_outputs_list,
                                     [], compression_stats,
                                     self._base_profile_stats, mAP_base_net,
                                     num_imgs_list, run_profile_stats=False)

    mAP = compression_stats.get(net_desc, 'mAP_%d_top%d'%(num_imgs,cfg.TEST.RPN_POST_NMS_TOP_N))
    mAP_delta = compression_stats.get(net_desc, 'mAP_%d_top%d_delta'%
                                                (num_imgs,cfg.TEST.RPN_POST_NMS_TOP_N))
    return mAP

  def run_exp(self, num_imgs_list):
    compressed_layers = get_all_compressible_layers()
    compressed_layers = remove_all_conv_1x1(compressed_layers)
    comp_layer_label='noconv1x1'
#     compressed_layers = remove_layers_after_block3(compressed_layers)
#     comp_layer_label='block1-3'

#     compressed_layers = keep_only_conv_not_1x1(compressed_layers)
#     compressed_layers = [LayerName('conv1/weights')]
#     self._final_layers = []

    #     Ks = range(1,11)
#     layer_idxs = range(7)
    layer_idxs = [0]

    mAP_base_net = self.get_mAP_base_net(num_imgs_list)

#     timing_results = TimingResults('timing_results')
    timing_results = TimingResults()

    for l, layer_name in enumerate(sorted(compressed_layers)):
      if l not in layer_idxs:
        continue
#       self._compressed_layers = [layer_name]
      self._compressed_layers = compressed_layers

#       Kfracs = [0.5, 0.6]
#       Kfracs_label='0.5'
#       Kfracs = np.arange(0.01, 1.0, 0.025)
      Kfracs = [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]
      Kfracs_label='0.1-1.0'
#       Ks = self.get_Ks(layer_name, Kfracs)

      use_plurinet = True
      if use_plurinet:
        net_desc_pluri = build_pluri_net_desc(Kfracs, compressed_layers)

        self._sess.close() #restart session to free memory and to reset profile stats
        tf.reset_default_graph()
        self._sess = tf.Session(config=self._tfconfig)

        filename = 'pluri_net_' + Kfracs_label + '_' + comp_layer_label

        pluri_net = PluripotentNet(self._base_net, self._sess, self._saved_model_path,
                                 self._all_comp_weights_dict, self._comp_bn_vars_dict,
                                 self._comp_bias_vars_dict,
                                 net_desc_pluri, self._base_variables, filename, timing_results=timing_results)

      for Kfrac in Kfracs:
        net_desc = build_net_desc(Kfrac, compressed_layers)

        if use_plurinet:
          with timer('PluripotentNet run_performance_analysis', timing_results) as t:
            pluri_net.run_performance_analysis(net_desc, self._blobs_list, self._sess, self._base_outputs_list,
                                             self._final_layers, self._compression_stats,
                                             self._base_profile_stats, mAP_base_net,
                                             num_imgs_list, run_profile_stats=False)
        else:
          self._sess.close() #restart session to free memory and to reset profile stats
          tf.reset_default_graph()
          self._sess = tf.Session(config=self._tfconfig)

          sep_net = SeparableNet(self._base_net, self._sess, self._saved_model_path,
                                 self._all_comp_weights_dict, self._comp_bn_vars_dict,
                                 self._comp_bias_vars_dict, net_desc, self._base_variables,
                                 timing_results=timing_results)

          with timer('SeparableNet run_performance_analysis', timing_results):
            sep_net.run_performance_analysis(net_desc, self._blobs_list, self._sess, self._base_outputs_list,
                                           self._final_layers, self._compression_stats,
                                           self._base_profile_stats, mAP_base_net,
                                           num_imgs_list, run_profile_stats=False)

#         flops = self._compression_stats.get(net_desc, 'float_ops_count_delta')
#         print('flops delta=%d'%(flops))
#         self._compression_stats.save('no1x1conv_0.1-1.0')
        timing_results.save('timing_results')
        print(layer_name + ' Kfrac=' + str(Kfrac) + ' complete\n')

def calc_reconstruction_errors(base_net, sess, saved_model_path, tfconfig):

  exp_controller = ExperimentController(base_net, sess, saved_model_path, tfconfig, '16')
#   exp_controller.run_optimise_mgr(max_iter=10000, stats_file_suffix='allLayersKfrac0.1_1.0')
  exp_controller.run_exp(num_imgs_list=[])
#   exp_controller.run_exp(num_imgs_list=[25])
#   exp_controller.run_exp(num_imgs_list=[5,10,25,50,100,250,500,1000,2000,4952])
#   exp_controller.run_split_net_exp(num_imgs=100)
#   exp_controller.optimise_with_plurinet(max_iter=50,stats_file_suffix='allLayersKfrac1.0')
#   exp_controller.optimise_with_plurinet(max_iter=10,stats_file_suffix='allLayersKfrac0.1_1.0')
#   exp_controller.optimise_with_plurinet(max_iter=50,stats_file_suffix='no1x1conv_0.1-1.0')


#!/usr/bin/env python3
"""NCBI functions."""

import ujson
from tolkein import tofetch
from tolkein import tolog

LOGGER = tolog.logger(__name__)

GBIF_API = "https://www.gbif.org/api"

def fetch_gbif_taxlist(params):
    """Fetch gbif taxon entries."""
    limit = params.get("limit", 5)
    offset = params.get("offset", 0)
    highertaxon_key = params.get("root", None)
    url = (
        "%s/species/search?advanced=false&rank=SPECIES&rank=SUBSPECIES&status=ACCEPTED&status=DOUBTFUL"
        % GBIF_API
    )
    if highertaxon_key is not None:
        url += "&highertaxon_key=%s" % highertaxon_key
    url += "&limit=%d&offset=%d" % (limit, offset)
    page = tofetch.fetch_url(url)
    data = ujson.decode(page)
    return data

def stream_gbif_taxa(root=None):
    """Stream gbif taxon entries."""
    params = {"root": root, "limit": 50, "offset": 0}
    data = {"results": [], "endOfRecords": False}
    while not data["endOfRecords"]:
        data = fetch_gbif_taxlist(params)
        for entry in data.get("results", []):
            yield (entry["key"], entry)
        params["offset"] += params["limit"]

def prepare_xref_rows(identifiers, meta):
    """Convert identifiers to a set of rows for output."""
    rows = []
    common = {"species": meta["species"]}
    if "family" in meta:
        common.update({"family": meta["family"]})
    if "subspecies" in meta:
        common.update({"subspecies": meta["subspecies"]})
    if "NCBI" in identifiers:
        common.update({"ncbiTaxonId": identifiers["NCBI"]["id"]})
    else:
        common.update({"gbifTaxonId": "GBIF:%s" % identifiers["GBIF"]["id"]})
    for db, entry in identifiers.items():
        row = {**common}
        row.update({"xref": "%s:%s" % (db, str(entry["id"]))})
        row.update({"sourceUrl": entry["url"]})
        row.update({"source": entry["source"]})
        row.update({"sourceSlug": entry["id"]})
        row.update({"sourceStub": entry["url"].replace(str(entry["id"]), "")})
        rows.append(row)
    return rows

def fetch_gbif_identifiers(taxon, *, xrefs=None):
    """Fetch gbif identifiers for a taxon."""
    if xrefs is None:
        xrefs = []
    xrefs = set(["NCBI"] + xrefs)
    url = "%s/wikidata/species/%s?locale=en" % (GBIF_API, str(taxon))
    page = tofetch.fetch_url(url)
    identifiers = {
        "GBIF": {
            "id": taxon,
            "url": "https://www.gbif.org/species/%s" % taxon,
            "source": "GBIF taxonKey",
        }
    }
    if page is not None:
        data = ujson.decode(page)
        for entry in data.get("identifiers", []):
            label = entry.get("label", {}).get("value", "None")
            db = label.split(" ")[0]
            if db in xrefs:
                identifiers.update(
                    {db: {"id": entry["id"], "url": entry["url"], "source": label}}
                )
    return identifiers

def gbif_parser(_params, opts, *args, **kwargs):
    """Parse GBIF taxa and identifiers."""
    parsed = []
    for root in opts["gbif-root"]:
        for key, meta in stream_gbif_taxa(root):
            identifiers = fetch_gbif_identifiers(key, xrefs=opts["gbif-xref"])
            parsed += prepare_xref_rows(identifiers, meta)
    return parsed


from datetime import datetime

def getweekday(m, d, y):
    dtedict = {'month': m, 'day': d, 'year': y}
    mrange = list(range(1, 13))
    drange = list(range(1, 32))
    yrange = list(range(1900, 2300))

    for i in dtedict.values():
        try:
           for ii in dtedict.values():
               int(ii)
        except ValueError:
            print("Dude. The inputs must be integers.")
            return True
        else:
            if int(dtedict["month"]) not in mrange:
                print("Invalid Month Entered. Must be 1 to 12. TRY AGAIN. You entered: ", dtedict)
                return True
            elif int(dtedict["day"]) not in drange:
                print("Invalid Day Entered. Must be 1 to 31. TRY AGAIN. You entered: ", dtedict)
                return True
            elif int(dtedict["year"]) not in yrange:
                print("The year you entered is out of range. Must be between 1900 and 2300. TRY AGAIN. You entered: ", dtedict)
                return True
            else:
                prelimdate = datetime(int(y), int(m), int(d))
                wkday = prelimdate.weekday()
                wkdaylist = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
                print(wkdaylist[wkday])
                return False

def main():
    oloop = True
    while oloop:
        print()
        m = input("Enter the month in integer format, or Q to END:")
        d = input("Enter the day in integer format, or Q to END:")
        y = input("Enter the year in integer format, or Q to END:")
        ex = [m, d, y]
        if "q" in [l.lower() for l in ex]:
            print("END")
            break
        oloop = getweekday(m, d, y)

if __name__ == "__main__":
    main()


import simplegui
import math, random

WIDTH, HEIGHT = 800, 600
HEIGHT = 600
lives, score = 3, 0
time = 0.5

class ImageInfo:
  def __init__(self, image, center, size, radius=0, animated=False):
    self.image = image
    self.center, self.size, self.radius = center, size, radius
    self.animated = animated

debris_source = simplegui.load_image("http://dl.dropbox.com/s/mweiyzhblrg1qxm/debris.png")
debris_image = ImageInfo(debris_source, [400, 300], [800, 600])
nebula_source = simplegui.load_image("http://dl.dropbox.com/s/u1zc7wne2xzquim/background.png")
nebula_image = ImageInfo(nebula_source, [400, 300], [800, 600])
sprite_source = simplegui.load_image("http://dl.dropbox.com/s/5235h827al08dhx/sprites.png")
ship_plain_image = ImageInfo(sprite_source, [70.5, 36.5], [135, 63], 35)
ship_thrust_image = ImageInfo(sprite_source, [70.5, 108.5], [135, 63], 35)
missile_image = ImageInfo(sprite_source, [162.5, 108], [55, 22], 3, 50)
rock_image = ImageInfo(sprite_source, [175.5, 34], [61, 64], 40)
images = [debris_source, nebula_source, sprite_source]
soundtrack = simplegui.load_sound(
    "http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/soundtrack.mp3")
missile_sound = simplegui.load_sound(
    "http://dl.dropbox.com/s/57vppejin937joy/shoot.a.mp3?")
missile_sound.set_volume(0.5)
ship_thrust_sound = simplegui.load_sound(
    "http://dl.dropbox.com/s/5e4dbwc2bz6aebd/thrust.b.mp3")
explosion_sound = simplegui.load_sound(
    "http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/explosion.mp3")

class Ship:
  def __init__(self, pos, vel, plain_image, thrust_image):
    self.pos, self.vel = list(pos), list(vel)
    self.plain_image, self.thrust_image = plain_image, thrust_image
    self.thrusting = False
    self.angle = 0
    self.friction = 0.01
    self.thrust = 0.2
    self.shoot_timer = None

  def draw(self, canvas):
    if keys['up']:
      if not self.thrusting:
        self.thrusting = True
      image = self.thrust_image
      ship_thrust_sound.play()
    else:
      if self.thrusting:
        self.thrusting = False
        ship_thrust_sound.rewind()
      image = self.plain_image
    canvas.draw_image(image.image,
        image.center, image.size, self.pos, image.size, self.angle)

  def shoot(self):
    pos = self.pos
    speed = 7.5
    vel = [self.vel[0] + math.cos(self.angle)*speed,
         self.vel[1] + math.sin(self.angle)*speed]
    missile = Sprite(pos, vel, self.angle, 0, missile_image, 50)
    missiles.append(missile)
    missile_sound.rewind()
    missile_sound.play()

  def update(self, canvas):
    if keys['space']:
      if not self.shoot_timer:
        self.shoot()
        self.shoot_timer = simplegui.create_timer(300, self.shoot)
        self.shoot_timer.start()
    elif self.shoot_timer:
      self.shoot_timer.stop()
      self.shoot_timer = None
    if keys['left'] and not keys['right']:
      self.angle = (self.angle - 0.1) % (2*math.pi)
    if keys['right'] and not keys['left']:
      self.angle = (self.angle + 0.1) % (2*math.pi)
    if keys['up']:
      self.vel[0] += math.cos(self.angle)*self.thrust
      self.vel[1] += math.sin(self.angle)*self.thrust
    for i in range(2):
      self.vel[i] *= 1-self.friction
    self.pos[0] = (self.pos[0] + self.vel[0]) % WIDTH
    self.pos[1] = (self.pos[1] + self.vel[1]) % HEIGHT
    self.draw(canvas)

class Sprite:
  def __init__(self, pos, vel, angle, angle_delta, image, lifespan=-1, sound=None):
    self.pos, self.vel = list(pos), list(vel)
    self.angle, self.angle_delta = angle, angle_delta
    self.image = image
    self.lifespan = lifespan
    self.age = 0
    if sound:
      sound.rewind()
      sound.play()

  def draw(self, canvas):
    image = self.image
    canvas.draw_image(image.image,
        image.center, image.size, self.pos, image.size, self.angle)

  def update(self, canvas):
    self.pos[0] = (self.pos[0] + self.vel[0]) % WIDTH
    self.pos[1] = (self.pos[1] + self.vel[1]) % HEIGHT
    self.angle = (self.angle + self.angle_delta) % (2*math.pi)
    self.age += 1
    self.draw(canvas)

def draw(canvas):
  global time, missiles
  for image in images:
    if image.get_width() == 0:
      canvas.draw_text('loading images...', (200, 200), 36, '#fff', 'sans-serif')
      return
  time += 1
  wtime = (time / 4.0) % WIDTH
  center = debris_image.center
  size = debris_image.size
  canvas.draw_image(nebula_image.image, nebula_image.center, nebula_image.size,
      [WIDTH / 2, HEIGHT / 2], [WIDTH, HEIGHT])
  canvas.draw_image(debris_image.image, center, size,
      (wtime - WIDTH / 2, HEIGHT / 2), (WIDTH, HEIGHT))
  canvas.draw_image(debris_image.image, center, size,
      (wtime + WIDTH / 2, HEIGHT / 2), (WIDTH, HEIGHT))
  canvas.draw_text('%d lives' % lives, (30, 50), 36, '#fff', 'sans-serif')
  score_text = 'score %d' % score
  score_width = frame.get_canvas_textwidth(score_text, 36, 'sans-serif')
  canvas.draw_text(score_text, (WIDTH-30-score_width, 50), 36, '#fff', 'sans-serif')
  a_rock.update(canvas)
  next_missiles = []
  for missile in missiles:
    if missile.age != missile.lifespan:
      missile.update(canvas)
      next_missiles.append(missile)
  missiles = next_missiles
  my_ship.update(canvas)

keys = {'left': False, 'up': False, 'right': False, 'space': False}

def keydown(code):
  for key in keys:
    if code == simplegui.KEY_MAP[key]:
      keys[key] = True

def keyup(code):
  for key in keys:
    if code == simplegui.KEY_MAP[key]:
      keys[key] = False

def spawn_rock():
  global a_rock
  pos = [random.randrange(WIDTH+1), random.randrange(HEIGHT+1)]
  speed = random.randrange(5, 26) / 10.0
  angle = (random.randrange(100)/100.0 * 4 - 2) * math.pi
  vel = [math.cos(angle)*speed, math.sin(angle)*speed]
  angle_delta = (random.randrange(21) - 10)/100.0
  #print('speed = %.3f, angle = %.3f, angle_delta = %.3f' % (speed, angle, angle_delta))
  a_rock = Sprite(pos, vel, 0, angle_delta, rock_image)

frame = simplegui.create_frame("Asteroids", WIDTH, HEIGHT)

spawn_rock()
missiles = []
my_ship = Ship([WIDTH / 2, HEIGHT / 2], [0, 0], ship_plain_image, ship_thrust_image)

frame.set_draw_handler(draw)
frame.set_keydown_handler(keydown)
frame.set_keyup_handler(keyup)
simplegui.create_timer(1000.0, spawn_rock).start()
frame.start()


import os

with open("datasets_to_use.txt","r") as f:
	lines = f.readlines()

import sys
sys.path.append('/Users/joelhogg/Documents/disertation stuff/bench_datasets/EXPERIMENTATION/METHODS/DAG_GNN/DAG_from_GNN')

for path in lines:
	print(path)
	os.system(f'python3.9 choose_dataset.py "{path}"')
	os.system(f'python3.9 -m "DAG_from_GNN"')
print("finished!")


from typing import Any
from django import forms
from event.models import CreateEvent, EventRegistration
from django.utils import timezone

# ============================ CREATE EVENT FORM ====================================
class CreateEventForm(forms.ModelForm):
    class  Meta:
        model = CreateEvent
        fields = ['eventOwnerName', 'eventTitle', 'eventDate', 'eventTime', 'totalSeat', 'eventLocation', 'eventDescription']

        labels = {
            'eventOwnerName': 'Event Creator Name',
            'eventTitle': 'Event Title',
            'eventDate': 'Event Date',
            'eventTime': 'Event Time',
            'totalSeat': 'Total Seats',
            'eventLocation': 'Event Location',
            'eventDescription': 'Event Description',
        }

        # set format of calender and time
        widgets = {
            'eventDate': forms.DateInput(attrs={'type': 'date'}),
            'eventTime': forms.TimeInput(attrs={'type': 'time'}),
        }

    # set place holder by overriding
    def __init__(self, *args, **kwargs):
        super(CreateEventForm, self).__init__(*args, **kwargs)
        self.fields['eventOwnerName'].widget.attrs['placeholder'] = 'Enter academic name'
        self.fields['eventTitle'].widget.attrs['placeholder'] = 'Enter the event title'
        self.fields['eventDate'].widget.attrs['placeholder'] = 'Select the event date'
        self.fields['eventTime'].widget.attrs['placeholder'] = 'Select the event time'
        self.fields['totalSeat'].widget.attrs['placeholder'] = 'Enter total number of seats'
        self.fields['eventLocation'].widget.attrs['placeholder'] = 'Enter the event location'
        self.fields['eventDescription'].widget.attrs['placeholder'] = 'Enter a brief description of the event'

    def clean(self):
        cleaned_data = super().clean()
        input_date = cleaned_data.get('eventDate')
        input_time = cleaned_data.get('eventTime')
        current_date = timezone.now().date()

        if input_date and input_date < current_date:
            raise forms.ValidationError('Invalid Date! Date must be in future')

        if input_time:
            current_time = timezone.localtime(timezone.now()).time()
            if not (9 <= input_time.hour <= 17):
                raise forms.ValidationError('Event must be 9am and 5pm')
            elif input_date == timezone.now().date() and input_time <= current_time:
                raise forms.ValidationError('Invalid Time! Time must be in future')

    def clean_totalSeat(self):
        input_seat = self.cleaned_data['totalSeat']

        if input_seat > 50:
            raise forms.ValidationError("Total seat can not be take more the 50.")
        elif input_seat < 0:
            raise forms.ValidationError('The seat can not be negative!')

        return input_seat

# ======================== EVENT REGISTRATION FORM =================================
class EventRegistrationForm(forms.ModelForm):
    class Meta:
        model = EventRegistration
        fields = ['firstName', 'lastName', 'email', 'phoneNumber', 'totalPerson']

        labels = {
            'firstName': 'First name',
            'lastName': 'Last name',
            'email': 'Email',
            'phoneNumber': 'Mobile number',
            'totalPerson': 'Person',

        }
    # set placeholder by overriding
    def __init__(self, *args, **kwargs):
        super(EventRegistrationForm, self).__init__(*args, **kwargs)
        self.fields['firstName'].widget.attrs['placeholder'] = 'Enter your first name'
        self.fields['lastName'].widget.attrs['placeholder'] = 'Enter your last name'
        self.fields['email'].widget.attrs['placeholder'] = 'Enter your email'
        self.fields['phoneNumber'].widget.attrs['placeholder'] = 'Enter your mobile number'
        self.fields['totalPerson'].widget.attrs['placeholder'] = 'How many person you are?'

    def clean_totalPerson(self):
        input_person = self.cleaned_data['totalPerson']

        if input_person > 2:
            raise forms.ValidationError('The person should not be more then 2.')

        return input_person


import matplotlib as mpl
mpl.use('TkAgg')
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as scstat
import pickle
from sklearn import linear_model
import pandas as pd

expt = 'CircleSquare'

BinNb = 12  # for place maps
TimeBinSize = 1 * 1000
TimeBinSize_TAU = 1000
x_day = np.array([1, 2, 3, 8, 9, 10, 15, 16, 17])

threshMult = 2
doPerc = False

pathAll = '/Users/eliott/Dropbox/dDocuments/NYU/Fenton/MNS_ANALYSIS/Data/' + expt + '/'
pathFigure = '/Users/eliott/Dropbox/dDocuments/NYU/Fenton/MNS_ANALYSIS/Figures/' + expt + '/savedFigs/'

# TAU/WEIGHTS
if doPerc:
    pathLoad = pathAll + 'analysisFiles/' + 'CS_Decoder_SVM_' + str(
        int(TimeBinSize)) + 'msBins_' + str(
        int(TimeBinSize_TAU)) + 'msKT_perc_thresh' + str(int(threshMult))+ '.file'
else:
    pathLoad = pathAll + 'analysisFiles/' + 'CS_Decoder_SVM_' + str(
        int(TimeBinSize)) + 'msBins_' + str(
        int(TimeBinSize_TAU)) + 'msKT_seg_thresh' + str(int(threshMult))+ '.file'

print(pathLoad)

with open(pathLoad, 'rb') as f:
    output = pickle.load(f)
animalList, corrTauWeightAll, SegWeightRatioAll, tauBins = output

perfSum = []

# TAU/WEIGHTS
corrTauWeighPick = []
corrTauWeighPickAll = []
RatioSegWeightPick = []
RatioSegWeightPickAll = []
RatioSegWeightPickWeek = []

nAni = len(animalList)

fSeg, aSeg = plt.subplots(nAni, 2)

# TAU/WEIGHTS
nSeg = len(SegWeightRatioAll[0][7])
if doPerc:
    xPlot = [*range(nSeg)]
    idPick = [[0, 1], [9, 10], [18, 19]]
    pickList = ['<10%', '45-55%', '>90%']
else:
    xPlot = [tauBins[0] - (tauBins[1] - tauBins[0]) / 2]
    xPlot.extend([b + d / 2 for b, d in zip(tauBins, np.diff(tauBins))])
    xPlot.extend([tauBins[-1] - (tauBins[-2] - tauBins[-1]) / 2])

    if TimeBinSize_TAU == 300:
        idPick = [np.where([x < -0.025 for x in xPlot])[0][-1:],
                  np.where([- 0.012 < x < -0.005 for x in xPlot])[0][-1:],
                  np.where([x == 0 for x in xPlot])[0],
                  np.where([0.1 < x < 0.2 for x in xPlot])[0],
                  np.where([0.2 < x for x in xPlot])[0]]
        pickList = ['<-0.025', '-0.01', '0', '0.1-0.2', '>0.2']

    elif TimeBinSize_TAU == 1000:
        idPick = [np.where([x < -0.05 for x in xPlot])[0],
                  np.where([- 0.025 < x < -0.015 for x in xPlot])[0],
                  np.where([x == 0 for x in xPlot])[0],
                  np.where([0.1 < x < 0.2 for x in xPlot])[0],
                  np.where([0.2 < x for x in xPlot])[0]]
        pickList = ['<-0.05', '-0.02', '0', '0.1-0.2', '>0.2']
        print(xPlot)
        print(idPick)

for iAni, animal in enumerate(animalList):
    for iDay in range(9):
        if np.size(corrTauWeightAll[iAni][0][iDay])>1:
            aSeg[iAni][0].plot(xPlot, SegWeightRatioAll[iAni][iDay], color=[1 - iDay / 8, iDay / 8, iDay / 8])
            aSeg[iAni][1].plot(xPlot, corrTauWeightAll[iAni][0][iDay], 'r')
            aSeg[iAni][1].plot(xPlot, corrTauWeightAll[iAni][1][iDay], 'k')

    aSeg[iAni][0].plot(xPlot, [1 for x in range(nSeg)], 'y--')
    aSeg[iAni][1].plot(xPlot, [0 for x in range(nSeg)], 'y--')

    # remove nans
    cEnv1 = [-c if (np.size(c) > 1 and np.sum(np.isfinite(c))>1) else [np.nan for _ in range(9)] for c in corrTauWeightAll[iAni][0]]
    cEnv2 = [c if (np.size(c) > 1 and np.sum(np.isfinite(c))>1) else [np.nan for _ in range(9)] for c in corrTauWeightAll[iAni][1]]
    ratio = [np.array(c) if (np.size(c) > 1 and np.sum(np.isfinite(c)) > 1) else [] for c in SegWeightRatioAll[iAni]]

    #take average of first 2, last 2, middle 2 and then average over days
    cPick = [np.nanmean([[np.nanmean([cc[i] for i in iId]) for iId in idPick] for cc in cEnv1], 0),
             np.nanmean([[np.nanmean([cc[i] for i in iId]) for iId in idPick] for cc in cEnv2], 0)]
    cPickAll = [[[np.nanmean([cc[i] for i in iId]) for iId in idPick] for cc in cEnv1],
             [[np.nanmean([cc[i] for i in iId]) for iId in idPick] for cc in cEnv2]]

    rPickAll = [[np.nanmean([cc[i] for i in iId]) for iId in idPick] if len(cc) > 0 else [np.nan for x in range(nSeg)] for cc in ratio]
    rPick = np.nanmean([[np.nanmean([cc[i] for i in iId]) for iId in idPick] for cc in ratio if len(cc) > 0],0)
    rPickWeek = [np.nanmean([[np.nanmean([cc[i] for i in iId]) for iId in idPick] for cc in ratioWeek if len(cc)>0],0)
                 for ratioWeek in [[ratio[x] for x in days] for days in [[0,1,2],[3,4,5],[6,7,8]]]]

    # save for plotting and average calculation
    corrTauWeighPick.append(cPick)
    corrTauWeighPickAll.append(cPickAll)
    RatioSegWeightPick.append(rPick)
    RatioSegWeightPickAll.append(rPickAll)
    RatioSegWeightPickWeek.append(rPickWeek)

fTauAverage = plt.figure(figsize=[12.8,9.6])
ax1 = fTauAverage.add_subplot(413)
ax2 = fTauAverage.add_subplot(414)
ax3 = fTauAverage.add_subplot(241)
ax4 = fTauAverage.add_subplot(242)
axBox1 = fTauAverage.add_subplot(243)
axBox2 = fTauAverage.add_subplot(244)

nPick = len(RatioSegWeightPick[0])

ratioCorrBoxPlot = [[rDay[iSeg] for rAni in RatioSegWeightPickAll for rDay in rAni if np.isfinite(rDay[iSeg])] for iSeg in range(5)]
tagRatioCorr = [[[animalList[iAni], iDay, pickList[iSeg]] for iAni, rAni in enumerate(RatioSegWeightPickAll) for iDay,rDay in enumerate(rAni) if np.isfinite(rDay[iSeg])] for iSeg in range(5)]
axBox1.boxplot(ratioCorrBoxPlot)

envList = ['RCT', 'CYL'] #got from SvmDecodeCs_tauSegments.py (line 349, 362)
corrWeightBoxPlot = [[cDay[iSeg] for cAni in corrTauWeighPickAll for iEnv in range(2) for cDay in cAni[iEnv] if np.isfinite(cDay[iSeg])] for iSeg in range(nPick)]
tagCorrWeight = [[[animalList[iAni], envList[iEnv], iDay, pickList[iSeg]] for iAni, cAni in enumerate(corrTauWeighPickAll) for iEnv in range(2) for iDay, cDay in enumerate(cAni[iEnv]) if np.isfinite(cDay[iSeg])] for iSeg in range(nPick)]
axBox2.boxplot(corrWeightBoxPlot, positions=[2*x-0.3 for x in range(nPick)])
# axBox2.boxplot([[cDay[iSeg] for cAni in corrTauWeighPickAll for cDay in cAni[0]] for iSeg in range(nPick)],
#                positions=[2*x-0.3 for x in range(nPick)])
# axBox2.boxplot([[cDay[iSeg] for cAni in corrTauWeighPickAll for cDay in cAni[1]] for iSeg in range(nPick)],
#                positions=[2*x+0.3 for x in range(nPick)])
axBox2.set_xlim([-1,9])

for iDay in range(9):
    if len([s[0] for s in SegWeightRatioAll if np.size(s[0]) > 1])>0:
        ax1.plot(xPlot, np.nanmean([s[iDay] for s in SegWeightRatioAll if np.size(s[iDay]) > 1], 0),
                            '.-', color=[1 - iDay / 8, iDay / 8, iDay / 8])

for SegWeightRatioAni in SegWeightRatioAll:
    ax2.plot(xPlot, np.nanmean([s for s in SegWeightRatioAni if np.size(s) > 1], 0), '.-')

ax1.set_title('average per day')
ax2.set_title('average per ani')

ax3.bar([*range(nPick)], np.mean(RatioSegWeightPick,0))
ax3.errorbar([*range(nPick)], np.mean(RatioSegWeightPick,0), np.std(RatioSegWeightPick,0)/np.sqrt(nAni), color='k', ls = '')

ax4.bar([x-0.15 for x in range(nPick)], np.mean(corrTauWeighPick,0)[0], 0.2)
ax4.bar([x+0.15 for x in range(nPick)], np.mean(corrTauWeighPick,0)[1], 0.2)
ax4.errorbar([x-0.15 for x in range(nPick)], np.mean(corrTauWeighPick,0)[0],
                     np.std(corrTauWeighPick,0)[0]/np.sqrt(6), color='k', ls = '')
ax4.errorbar([x+0.15 for x in range(nPick)], np.mean(corrTauWeighPick,0)[1],
                     np.std(corrTauWeighPick,0)[1]/np.sqrt(6), color='k', ls = '')

# plot
for rPickAni in RatioSegWeightPickWeek:
    ax3.plot([x - 0.15 for x in range(nPick)], rPickAni[0], 'k.')
    ax3.plot([x for x in range(nPick)], rPickAni[1], 'k.')
    ax3.plot([x + 0.15 for x in range(nPick)], rPickAni[2], 'k.')

for rPickAni in RatioSegWeightPick:
    # ax3.plot(rPickAni, 'k.')
    ax3.plot(rPickAni, '--', color=[0.7, 0.7, 0.7])
    ax3.set_xticks([])
    ax3.set_xticks([*range(nPick)])
    ax3.set_xticklabels(pickList)

for cPickAni in corrTauWeighPick:
    ax4.plot([x-0.15 for x in range(nPick)], cPickAni[0], 'r.')
    ax4.plot([x+0.15 for x in range(nPick)], cPickAni[1], 'k.')
    ax4.set_xticks([])
    ax4.set_xticks([*range(nPick)])
    ax4.set_xticklabels(pickList)

#exporting data
df = pd.DataFrame()

dataStr = ['ratioCorr']  # create index string
df = df.append(pd.DataFrame(data=np.concatenate(ratioCorrBoxPlot), columns=dataStr).transpose())
dataStr = [s + '_tag_ratioCorr' + s for s in ['ani', 'day', 'pick']]  # create index string
df = df.append(pd.DataFrame(data=np.concatenate(tagRatioCorr), columns=dataStr).transpose())

dataStr = ['CorrWeight']  # create index string
df = df.append(pd.DataFrame(data=np.concatenate(corrWeightBoxPlot), columns=dataStr).transpose())
dataStr = [s + '_tag_CorrWeight' + s for s in ['ani', 'env', 'day', 'pick']]  # create index string
df = df.append(pd.DataFrame(data=np.concatenate(tagCorrWeight), columns=dataStr).transpose())

df.to_csv(pathFigure + 'dataSvmTauSegments.csv')

fTauAverage.savefig(pathFigure + 'TauSegmentAverage.eps', format='eps')
fSeg.savefig(pathFigure + 'TauSegmentAllAni.eps', format='eps')

print('done done done')
plt.show(block=True)


import subprocess
import argparse
import sys
from pathlib import Path
from zipfile import BadZipFile, ZipFile
import os
import shutil
from subprocess import STDOUT
import time
import pandas as pd

def get_csv_json_from_folder(folder):
    '''
    Helper function for retrieving json and csv files from a folder
    '''
    csvs = []
    jsons = []
    for filename in os.listdir(folder):
        if filename.endswith('.csv'):
            csvs.append(filename)
        if filename.endswith('.json'):
            jsons.append(filename)
    return csvs, jsons

def extract_build_solution(zipped_folder_path, destination_folder_name):
    '''
    Principle: give as an input a zipped folder containing the solution to compile, along with a destination folder where the solution will be extracted.
    The script compiles the entire unzipped solution.
    '''
    try:
        if not zipped_folder_path.exists():
            print(f'No zippped folder {zipped_folder_path.name} available on path')
            sys.exit(1)
        unzipped_folder = zipped_folder_path.stem
        if not unzipped_folder.startswith('Group'):
            print('*********************************************************************')
            print('*** WARNING: expecting a zipped file and folder of the form *Group_i*')
            print('*** still proceeding')
            print('*********************************************************************')
        print(f"Unzipping zipped folder at {zipped_folder_path} into {destination_folder_name}")
        with ZipFile(zipped_folder_path, 'r') as zip_obj:
            zip_obj.extractall(destination_folder_name)
            print('Done with extraction')
        new_folder = Path(destination_folder_name).joinpath(unzipped_folder)
        if not Path(new_folder).exists():
            print(f'Wrong extracted folder name, expected {new_folder.stem}')
            sys.exit(1)
        os.chdir(new_folder)
        print(f'Building solution in folder {unzipped_folder} (platform x64)')
        subprocess.run("dotnet build /nowarn:msb3246,msb3270 /p:Platform=x64 -v q", check=True)
        print(f"Done building solution in folder {unzipped_folder}")
        return True, new_folder
    except BadZipFile:
        print(f'Invalid zipped folder: {zipped_folder_path.name}')
        return False, None
    except subprocess.CalledProcessError as e:
        print(f'Error when building solution in folder {unzipped_folder}')
        return False, None
    except subprocess.TimeoutExpired:
        print('Timeout')
        return False, None
    except SystemExit:
        print('Exiting...')
        return False, None

def console_tests(console_folder, test_prop_folder, output_folder):
    '''
    Execution of a set of tests from an application console
    '''
    try:
        print('Running tests on console')
        Path.mkdir(output_folder, parents=True)
        for test_folder in test_prop_folder.iterdir():
            if test_folder.is_dir():
                run_single_console_test(console_folder, test_folder, output_folder)
    except SystemExit:
        print('Exiting...')

def run_single_console_test(solution_folder, test_folder, out_folder):
    '''
    Main method for running a console test on a given set of parameters and market data.
    '''
    print(f'Running test in folder {test_folder}')
    os.chdir(solution_folder)
    csvs, jsons = get_csv_json_from_folder(test_folder)
    if len(csvs) != 1 or len(jsons) != 1:
        print(f'wrong number of csv or json files in {test_folder}, skipping.')
    else:
        csv_file = test_folder.joinpath(csvs[0])
        json_file = test_folder.joinpath(jsons[0])
        result_file = str(out_folder.joinpath(test_folder.name))
        subprocess.run(f"BacktestConsole.exe {json_file} {csv_file} {result_file}_output.json", check=True)

def grpc_console_tests(grpc_server_folder, test_prop_folder, output_folder, client_path):
    '''
    Execution of a set of tests from a grpc server
    '''
    try:
        print('Running grpc tests on console')
        os.chdir(grpc_server_folder)
        print('starting grpc folder')
        process= subprocess.Popen("GrpcBacktestServer.exe")
        time.sleep(3)
        for test_folder in test_prop_folder.iterdir():
            if test_folder.is_dir():
                run_single_grpc_test(test_folder, output_folder, client_path)
        print('killing server')
        process.kill()
    except SystemExit:
        print('killing server on exception')
        process.kill()
        print('Exiting...')
    except FileNotFoundError as e:
        print('killing server on file not found exception')
        print(e)
        process.kill()
        print('Exiting...')

def run_single_grpc_test(test_folder, out_folder, client_path):
    '''
    Main method for running a grpc test on a given set of parameters and market data.
    '''
    print(f'Running grpc test in folder {test_folder}')
    csvs, jsons = get_csv_json_from_folder(test_folder)
    if len(csvs) != 1 or len(jsons) != 1:
        print(f'wrong number of csv or json files in {test_folder}, skipping.')
    else:
        csv_file = test_folder.joinpath(csvs[0])
        json_file = test_folder.joinpath(jsons[0])
        result_file = str(out_folder.joinpath(test_folder.name))
        os.chdir(client_path)
        proc_2 = subprocess.Popen(["GrpcEvaluation.exe", json_file, csv_file, f"{result_file}_grpc_output.json"], stderr=STDOUT)
        proc_2.communicate()
        print('killing client')
        proc_2.kill()
        print('done with grpc test')

def create_grpc_client_path(grpc_folder_path):
    '''
    Helper method for building the grpc and accessing the executable path.
    '''
    client_source_path = Path.cwd().joinpath('GrpcEvaluation')
    if  Path(grpc_folder_path).exists():
        shutil.rmtree(grpc_folder_path)
    shutil.copytree(client_source_path, grpc_folder_path)
    os.chdir(grpc_folder_path)
    print(f'Building client in folder {grpc_folder_path} (platform x64)')
    subprocess.run("dotnet build /nowarn:msb3246,msb3270 /p:Platform=x64 -v q", check=True)
    print(f"Done building client in folder {grpc_folder_path}")
    grpc_client_path=grpc_folder_path.joinpath('GrpcEvaluation/bin/x64/Debug/net6.0')
    return grpc_client_path

def check_output_structure(output_folder):
    '''
    Helper method to make sure the application outputs are in the correct format.
    '''
    EXPECTED_FIELDS = ['date', 'value', 'deltas', 'deltasStdDev', 'price', 'priceStdDev']
    for result_file in output_folder.iterdir():
        print(f'  File {result_file}')
        try:
            df = pd.read_json(result_file)
            columns = df.columns
            for field in EXPECTED_FIELDS:
                if field not in columns:
                    print(f'** Warning: missing field {field}. Make sure the field names are camelcased.')
            print('  --> OK')
        except ValueError:
            print('Unable to parse json file.')

def create_output_for_project(zipped_project_path, tests_folder_path, build_folder_path, out_folder_path, grpc_client_path):
    '''
    Parameters:
    - zipped_project_path: path to the zipped project for which the output will be created
    - test_folder_path: path to the folder containing the tests to be run
    - build_folder_path: path to the folder where the project will be extracted and built
    - out_folder_path: path to the folder where the output results will be stored
    - grpc_client_path: path to the folder containing the grpc client (if it exists), None otherwise
    '''
    build_ok, solution_folder = extract_build_solution(zipped_project_path, build_folder_path)
    if build_ok:
        solution_folder_path = Path(solution_folder)
        solution_name = solution_folder_path.name
        console_bin_path = 'BacktestConsole/bin/x64/Debug/net6.0'
        console_folder = solution_folder_path.joinpath(console_bin_path)
        if not Path(console_folder).exists():
            print(f'Wrong path {console_folder}')
            sys.exit(1)
        output_folder = out_folder_path.joinpath(solution_name).joinpath('output')
        console_tests(console_folder, tests_folder_path, output_folder)
        if not (grpc_client_path is None):
            grpc_path = Path(solution_folder).joinpath('GrpcBacktestServer')
            if grpc_path.exists():
                print('Grpc server exists, running tests')
                server_bin_path = 'GrpcBacktestServer/bin/x64/Debug/net6.0'
                grpc_folder = solution_folder_path.joinpath(server_bin_path)
                grpc_console_tests(grpc_folder, tests_folder_path, output_folder, grpc_client_path)
        print('Checking output structure')
        check_output_structure(output_folder)

def run_tests():
    '''
    Main orchestrator for tests
    '''
    parser = argparse.ArgumentParser()
    parser.add_argument("--sln", help="Path to the folder containing the zipped solution.", type=str)
    parser.add_argument("--tests", help="Path to folder containing tests to run", type=str)
    parser.add_argument("--build", help="Path to folder where the solution will be extracted and built")
    parser.add_argument("--out", help="Path to folder where the results will be stored")
    parser.add_argument("--grpc", help="Optional. Path to folder where the grpc client will be stored")
    parser.add_argument("--force", action='store_true', help="Force output folder to be erased if it already exists. Default: false")
    args = parser.parse_args()
    if not args.sln:
        print('Missing "--sln" parameter')
        sys.exit(1)
    if not args.tests:
        print('Missing "--tests" parameter')
        sys.exit(1)
    if not args.build:
        print('Missing "--build" parameter')
        sys.exit(1)
    if not args.out:
        print('Missing "--out" parameter')
        sys.exit(1)
    else:
        if not args.grpc:
            grpc_client_path=None
        else:
            grpc_folder_path = Path(args.grpc)
            grpc_client_path = create_grpc_client_path(grpc_folder_path)
        zipped_folder_path = Path(args.sln)
        tests_folder_path = Path(args.tests)
        build_folder_path = Path(args.build)
        out_folder_path = Path(args.out)
        if  Path(out_folder_path).exists():
            if args.force:
                shutil.rmtree(out_folder_path)
            else:
                print('Error: output folder already exists')
                sys.exit(1)
        Path.mkdir(out_folder_path)
        for filename in zipped_folder_path.iterdir():
            if filename.suffix == '.zip':
                create_output_for_project(zipped_folder_path.joinpath(filename), tests_folder_path, build_folder_path, out_folder_path, grpc_client_path)

if __name__ == "__main__":
    run_tests()


# 进程池：mp.Pool()，将要运行的函数放入池子，Python会自动解决多进程的问题
# 且pool有返回值，而Process要自己获取

import multiprocessing as mp

def job(x):
    return x * x

def multicore():
    # mp.Pool(processes=) 定义进程池，processes为调用进程数（使用核的数量），默认为CPU的核数
    pool = mp.Pool(processes=3)

    # 用map传递任务和参数，返回一个list。
    res = pool.map(job, range(10))
    print(res)
    print(type(res))

    # 也可以用apply_async()来传递任务和参数，但是只能传递一个参数（注意,表示迭代）
    res = pool.apply_async(job, (2, ))
    print(res.get())
    # 为了传递多个参数，可以用列表来框起多个apply_async()
    res_list = [pool.apply_async(job, (i, )) for i in range(10)]
    print([res.get() for res in res_list])

if __name__ == '__main__':
    multicore()


#!/usr/bin/env python

import os
import time
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException

class GolfBot():
    """describes the framework of the automated system"""

    def __init__(self, hr, min, sec, opentime):
        self.hr = hr
        self.min = min
        self.sec = sec
        self.opentime = opentime

    def countdown(self, now):
        # TODO -!--> refactor to reduce redundancy
        # only print every 5 seconds
        if not int(now[6:8]) % 5:
            if int(now[:2]) == self.hr:
                if int(now[3:5]) == min:
                    print("T- " +
                        str(self.sec - int(now[6:8])) + " sec")
                else:
                    print("T- " +
                        str(self.min - int(now[3:5])) + " min " +
                        str(self.sec - int(now[6:8])) + " sec"  )
            else:
                print("T- " +
                    str(self.hr  - int(now[ :2])) + " hr "  +
                    str(self.min - int(now[3:5])) + " min " +
                    str(self.sec - int(now[6:8])) + " sec"  )

    def findTimes(self, webPage, webPage2, h, m):
        # loop through all possible timeslots, and determine if it can be clicked
        meridian = "A"
        while m < 51:
            if meridian == "P": # stop searching for times past 6pm
                if h > 5:
                    break
            if h > 12: # switch from AM to PM
                h = 1
                meridian = "P"

            if not m: # if m is 0, make it a string with a leading 0 to fit time format
                m = "00"
            # TODO -!--> not a big problem, but the stop bool does not work as expected, and all times are clicked
            switch = True
            stop = False
            if switch: # every other time, switch between the two webpages
                if webPage.findLink(f"{h}:{m} {meridian}M"):
                    webPage.clickLink(f"{h}:{m} {meridian}M")
                    print(f"selected {h}:{m} {meridian}M")
                    if stop: break # ensure both pages click a time before breaking the loop
                    else: stop = True
                switch = False
            else:
                if webPage2.findLink(f"{h}:{m} {meridian}M"):
                    webPage2.clickLink(f"{h}:{m} {meridian}M")
                    print(f"selected {h}:{m} {meridian}M")
                    if stop: break
                    else: stop = True
                switch = True
            if not isinstance(m, int):
                m = 0
            m += 10
            if m == 60: m = 0; h += 1

    def timedLaunch(self):

        now = time.ctime()[11:19]

        while now != self.opentime:

            self.countdown(now)

            # ---> stop counting a couple seconds before opentime
            now = time.ctime()[11:19]
            if ( int(now[:2]) == self.hr ) and ( int(now[3:5]) == self.min) and ( int(now[6:]) >= self.sec - 3):
                break

            # otherwise, sleep 1 sec
            time.sleep(1)

        # ---> loop until it is exactly 7:30 am
        while time.ctime()[11:19] != self.opentime:
            continue

        print("golf")
        print(time.ctime()[11:19])

class WebPage():
    """describes a web page for use with selenium"""

    def __init__(self, url, browser="safari"):
        self.url = url
        if browser == "safari":
            self.driver = webdriver.Safari(executable_path="/usr/bin/safaridriver") # safari executable is found in usr/bin
        else:
            self.driver = webdriver.Chrome("./chromedriver") # chromedriver executable needs to be in the parent directory

    def openPage(self):
        self.driver.get(self.url)

    def closePage(self):
        self.driver.quit()

    def findLink(self, name):
        # locate button by the link text
        if not (self.driver.find_elements(webdriver.common.by.By.LINK_TEXT, name)):
            print(f"{name} not found")
            return False

        return self.driver.find_element(webdriver.common.by.By.LINK_TEXT, name)

    def clickLink(self, name=""):
        # locate button by the link text and click it if it exists
        try:
            self.driver.find_element(webdriver.common.by.By.LINK_TEXT, name).click()
        except NoSuchElementException:
            # if link can't be found
            print("Link does not exist")
            time.sleep(0.5)
            self.clickLink(name)

    def loginButton(self, href):
        self.driver.find_element(webdriver.common.by.By.XPATH,f'//a[contains(@href,"{href}")]').click()

    def setURL(self, url):
        self.url = url

def main():

    # initialize golfbot instance
    golf = GolfBot(7, 29, 60, "07:30:00")

    teetime = input("Please enter the earliest time you want to play in multiples of 10min (e.g. 7:50): ")
    date = input("Please enter the day of the month to schedule (e.g. 16): ")

    cwd = os.path.abspath(os.getcwd())
    url = f"file://{cwd}/GolfLogin.html"
    #url = ""
    pageA = WebPage(url, "chrome")
    pageA.openPage()
    pageB = WebPage(url, "chrome")
    pageB.openPage()
    time.sleep(1)

    # login to renew session

    href = "./MemberIdentification.html"
    #href = "/SiteDesign/ForeTeesScript.aspx"
    pageA.loginButton(href)
    pageB.loginButton(href)
    time.sleep(1)

    # click austin
    # all buttons onward are <a> tags
    pageA.clickLink("Austin Copley")
    pageB.clickLink("Member 1")
    time.sleep(1)

    # TODO -!--> move the countdown here once testing is done, or move it after a refresh calendar click

    # click on the inputted date

    pageA.clickLink(date)
    pageB.clickLink(date)
    time.sleep(1)

    # pass the webpage to the golfbot instance to locate tee times
    h, m = int(teetime.split(":")[0]), int(teetime.split(":")[1])
    golf.findTimes(pageA, pageB, h, m)

    # TODO -!--> either give user opportunity to select their own players and methods of transport
    #            or autofill fields, or leave the page open for the user to do it manually

    # ---> give user time reference while waiting for schedule to open
    golf.timedLaunch()

    input("Press Enter to end program and close browser pages...")

    pageA.closePage()
    pageB.closePage()

if __name__ == "__main__":
    main()


import os, json

def clean():

    os.system('cls')

barangbelanja = []
hargabarang = []
totalharga = 0

def baca_laporan():
    try:
        with open("hasilbelanja.json", "r") as file:
            data = json.load(file)
            return data
    except FileNotFoundError:
        with open("hasilbelanja.json", "w") as file:
            kosong = []
            json.dump(kosong, file, indent=2)
            return kosong

def tulis_ulangJson(baru):
    with open("hasilbelanja.json", "w") as file:
        json.dump(baru, file, indent=2)

def laporan():
    with open("hasilbelanja.json", "r") as data:
        reader = json.load(data)
        print ('Berikut adalah laporan pembelian anda')
        print ( '-' * 50 )
        print(reader)

def belanjatani():
 while True :
    baca_laporan()
    clean()
    print("\nhalo", nama)
    print('Apa Yang Ingin Anda Beli?')
    print("Kategori:\n 1. Pupuk \n 2. Bibit \n")
    pilihan = int(input('Masukkan kode 1-2 untuk memilih kategori yang diinginkan:'))
    if pilihan == 1:
        pupuk()
    elif pilihan == 2 :
        bibit()
    print(" \n 1.Lanjut Berbelanja\n 2.Checkout \n ")
    user = int(input("Masukkan Angka 1-2yang anda inginkan:"))
    if user == 1 :
        belanjatani()
    elif user == 2 :
        checkout()
        print('Terima kasih telah berbelanja di Tanipedia, laporan pembelian anda akan tercetak secara otomatis')
    break

def pupuk():
    clean()
    print ('Beberapa Produk teratas dari kami :')
    print (' 1. Pupuk Kandang Setia Tani\n 2. Pupuk Digrow Hijau\n 3. Pupuk Kompos Bokhasi\n 4. Pupuk Kompos Bokhasi\n 5. Pupuk Humic Acid Humus\n 6. Kembali')
    pupuk1 = ['Pupuk Kandang Setia Tani', 34000]
    pupuk2 = ['Pupuk Digrow Hijau', 43000]
    pupuk3 = ['Pupuk Kompos Bokhasi', 21000]
    pupuk4 = ['Pupuk Hayati Organik Micorin', 27000]
    pupuk5 = ['Pupuk Humic Acid Humus', 68000]
    new_4 = int(input('\nMasukkan barang yang ingin dibeli:'))
    if new_4 == 1 :
        print(" Pupuk Kandang Setia Tani (Rp34.000,-)\n \n> dari kotoran hewan \n> memperbaiki kesuburan dan struktur tanah \n> perbaikan struktur tanah \n> penyediaan unsur hara")
        print ( '-' * 50 )
        print('Masukkan keranjang? \n 1. Ya \n 2. Batal')
        beli = int(input('\nMasukkan (1/2): '))
        if beli == 1:
            barangbelanja.append(pupuk1[0])
            hargabarang.append(pupuk1[1])
        else:
            pupuk()
    elif new_4 == 2 :
        print(" Pupuk Digrow Hijau (Rp43.000,-)\n  \n> dari tumbuhan \n> menambah unsur hara tanah, terutama nitrogen \n> perbaikan sifat fisik, kimia dan biologi tanah \n> ketahanan tanah terhadap erosi")
        print ( '-' * 50 )
        print('Masukkan keranjang? \n 1. Ya \n 2. Batal')
        beli = int(input('\nMasukkan (1/2): '))
        if beli == 1:
            barangbelanja.append(pupuk2[0])
            hargabarang.append(pupuk2[1])
        else:
            pupuk()
    elif new_4 == 3 :
        print(" Pupuk Kompos Bokhasi (Rp21.000,-)\n \n> dari sisa bahan organik: tumbuhan, hewan, dan limbah organik secara alami dengan cara dekomposisi atau fermentasi \n> memberikan nutrisi pada tanaman. \n> meningkatkan Kapasitas Tukar Kation (KTK) \n> mampu meningkatkan pH tanah pada tanah asam. \n> meningkatkan ketersediaan unsur mikro.")
        print ( '-' * 50 )
        print('Masukkan keranjang? \n 1. Ya \n 2. Batal')
        beli = int(input('\nMasukkan (1/2): '))
        if beli == 1:
            barangbelanja.append(pupuk3[0])
            hargabarang.append(pupuk3[1])
        else:
            pupuk()
    elif new_4 == 4 :
        print(" Pupuk Hayati Organik Micorin (Rp27.000,-)\n \n> pupuk mikrobiologis (biofertilizer) \n> membantu memperbaiki struktur tanah \n> memproduksi nutrisi bagi tanah dan tanaman \n> memangkas pertumbuhan parasit bagi tanaman")
        print ( '-' * 50 )
        print('Masukkan keranjang? \n 1. Ya \n 2. Batal')
        beli = int(input('\nMasukkan (1/2): '))
        if beli == 1:
            barangbelanja.append(pupuk4[0])
            hargabarang.append(pupuk4[1])
        else:
            pupuk()
    elif new_4 == 5 :
        print("Pupuk Humic Acid Humus (Rp68.000,-)\n \n> dari pelapukan daun-daunan dan ranting tanaman yang membusuk \n> membantu meningkatkan kadar air tanah \n> mencegah erosi \n> mempercepat proses penghancuran senyawa beracun dalam tanah")
        print ( '-' * 50 )
        print('Masukkan keranjang? \n 1. Ya \n 2. Batal')
        beli = int(input('\nMasukkan (1/2): '))
        if beli == 1:
            barangbelanja.append(pupuk5[0])
            hargabarang.append(pupuk5[1])
        else:
            pupuk()
    elif new_4 == 6 :
        belanjatani()
    else :
         print(str (input (' \nTekan enter untuk memasukkan angka yang benar' )))
         pupuk()

def bibit():
    clean()
    print ('Beberapa Produk teratas dari kami :')
    print (' 1. Padi\n 2. Jagung\n 3. Kembang kol\n 4. Sawi\n 5. Terong\n 6. Kembali')
    bibit1 = ['Padi', 34000]
    bibit2 = ['Jagung', 47000]
    bibit3 = ['Kembang kol', 49000]
    bibit4 = ['Sawi', 98000]
    bibit5 = ['Terong', 51000]
    new_5 = int(input('\nMasukkan barang yang ingin dibeli:'))
    if new_5 == 1 :
        print(" Padi (Rp34.000,-) \nTanah yang cocok: mengandung lempung, pasir, dan debu.")
        print ( '-' * 50 )
        print('Masukkan keranjang? \n 1. Ya \n 2. Batal')
        beli = int(input('\nMasukkan (1/2): '))
        if beli == 1:
            barangbelanja.append(bibit1[0])
            hargabarang.append(bibit1[1])
        else:
            bibit()
    elif new_5 == 2 :
        print("Jagung (Rp47.000,-) \nTanah yang cocok: andosol (berasal dari gunung berapi), latosol, grumosol, tanah berpasir.")
        print ( '-' * 50 )
        print('Masukkan keranjang? \n 1. Ya \n 2. Batal')
        beli = int(input('\nMasukkan (1/2): '))
        if beli == 1:
            barangbelanja.append(bibit2[0])
            hargabarang.append(bibit2[1])
        else:
            bibit()
    elif new_5 == 3:
        print(" Kembang kol (Rp49.000,- \n Tanah yang cocok: kaya nutrisi dan berdrainase baik.")
        print ( '-' * 50 )
        print('Masukkan keranjang? \n 1. Ya \n 2. Batal')
        beli = int(input('\nMasukkan (1/2): '))
        if beli == 1:
            barangbelanja.append(bibit3[0])
            hargabarang.append(bibit3[1])
        else:
            bibit()
    elif new_5 == 4 :
        print(" Sawi (Rp98.000,-) \nTanah yang cocok: memiliki bahan dasar berupa endapan debu atau liat.")
        print ( '-' * 50 )
        print('Masukkan keranjang? \n 1. Ya \n 2. Batal')
        beli = int(input('\nMasukkan (1/2): '))
        if beli == 1:
            barangbelanja.append(bibit4[0])
            hargabarang.append(bibit4[1])
        else:
            bibit()
    elif new_5 == 5 :
        print(" Terong (Rp51.000,-) \nTanah yang cocok: berlempung pasir dengan kisaran pH 6,5-7.")
        print ( '-' * 50 )
        print('Masukkan keranjang? \n 1. Ya \n 2. Batal')
        beli = int(input('\nMasukkan (1/2): '))
        if beli == 1:
            barangbelanja.append(bibit5[0])
            hargabarang.append(bibit5[1])
        else:
            bibit()
    elif new_5 == 6 :
        belanjatani()
    else :
        print(str (input (' \nTekan enter untuk memasukkan angka yang benar' )))
        bibit()

def checkout() :
    clean()
    baca_laporan()
    print('List barang yang akan anda beli: \n')
    ket = ['No', 'Nama', 'Harga']
    print(f'{ket[0]:<5}{ket[1]:<38}{ket[2]:<18}')
    print('='*60)
    totalharga = sum(hargabarang)
    for j in range(len(barangbelanja)):
            print(f'{j+1:<5}{barangbelanja[j]:<38}','Rp'+ f'{hargabarang[j]:<18}')
    print('='*60)
    total = sum(hargabarang)
    print('Total Harga :' + ' Rp' + str(total))
    print('='*60)
    clean()
    print('Apakah Anda Yakin ? \n 1. Ya\n 2. Tidak, Kembali ke Menu Awal \n')
    user = int(input('Inputkan angka yang anda inginkan :'))
    if user == 1 :
        total = sum(hargabarang)
        total = int(total)
        print("Total Belanja Anda Sementara : Rp" + str(totalharga))
        ket = ['No', 'Nama', 'Harga']
        print(f'{ket[0]:<5}{ket[1]:<38}{ket[2]:<18}')
        print('='*60)
        totalharga = sum(hargabarang)
        for j in range(len(barangbelanja)):
            print(f'{j+1:<5}{barangbelanja[j]:<38}','Rp'+ f'{hargabarang[j]:<18}')
        print('='*60)
        total = sum(hargabarang)
        totalharga = totalharga
        print('Total Harga Belanja :' + ' Rp' + str(total))
        print("Total Akhir :" + ' Rp' + str(totalharga))
        print('='*60)
        Program = {'barang' : barangbelanja}
        program1 = {'harga' : hargabarang}
        program4 = {'total' : totalharga}

        hitungan = baca_laporan()
        hitungan.append(Program)
        hitungan.append(program1)
        hitungan.append(program4)
        tulis_ulangJson(hitungan)
    else :
        belanjatani()

print ( 'Selamat Datang di Tanipedia' )
print ( '-' * 50 )
nama =  input ( "Silakan Masukkan Nama Anda:" )
print ( '-' * 50 )
print ( 'Selamat Datang' ,  nama )
print ( 'Silahkan Pilih Menu' )
while True :
    print("Menu:\n 1. Belanja Tani \n 2. Laporan Pembelian")
    pilihan = int(input('Masukkan kode 1-2 untuk memilih menu yang diinginkan:'))
    print('-'*50)
    if pilihan == 1 :
        belanjatani()
        break
    elif pilihan == 2 :
        laporan()
        os.remove("hasilbelanja.json")
        break
    else :
        print ('Masukkan inputan sesuai nomer yang tersedia')


import support

import phones
support.print_func("John")

Money = 2000
def AddMoney():
   # Uncomment the following line to fix the code:
    global Money
    Money = Money + 1

# Package Import and module-sub module use
phones.Pots()
phones.Isdn()
phones.G3()


from win32api import CloseHandle, GetLastError, SetConsoleCtrlHandler
import imp
import os
import sys
import time
import pythoncom
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import pkgutil
import inspect
from shotgun_api3 import Shotgun

class AppServerSvc (win32serviceutil.ServiceFramework):
    _svc_name_ = "timelog"
    _svc_display_name_ = "shotgun time log"

    def __init__(self,args):
        win32serviceutil.ServiceFramework.__init__(self,args)
        SetConsoleCtrlHandler(lambda x: True, True)
        self.hWaitStop = win32event.CreateEvent(None,0,0,None)

        self.count = 0
        self.estinmins = 0
        self.isAlive = True
        self.envv = ''
        self.prlist = []

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)
        self.run = False

    def SvcDoRun(self):
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                              servicemanager.PYS_SERVICE_STARTED,
                              (self._svc_name_,''))
        self.sg = Shotgun('https://xxxxxxxxxxxxxxxx.shotgunstudio.com' , 'timelogservice', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
        self.main()

    def updateProject(self, projectid):
        servicemanager.LogWarningMsg( unicode(projectid))
        filters = [["project.Project.id", "is", projectid]]
        fields = ["time_logs_sum","est_in_mins"]
        for eventTimeLog in self.sg.find('Task', filters, fields):
            self.count = self.count + eventTimeLog['time_logs_sum']
            if eventTimeLog['est_in_mins'] is not None:
                self.estinmins = self.estinmins + eventTimeLog['est_in_mins']

        data = { 'sg_artisttimelog':self.count/600 }
        asset = self.sg.update("Project",projectid,data)
        data = { 'sg_total_bid':self.estinmins/600}
        asset = self.sg.update("Project",projectid,data)

    def main(self):
        while self.isAlive:
            filters = [["sg_status", "is", "active"]]
            fields = ['id']
            for f in self.sg.find('Project',filters,fields):
                self.prlist.append(f['id'])

            for prid in self.prlist:
                self.updateProject(prid)
                self.count = 0
                self.estinmins = 0
                if win32event.WaitForSingleObject(self.hWaitStop, 3000) == win32event.WAIT_OBJECT_0:
                    break

if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(AppServerSvc)


from typing import Dict, List, Any

from bs4 import BeautifulSoup
from flask import session

from src.etc import Utils

def get_shows() -> Dict[str, any]:
    resp = Utils.get('https://www.tvtime.com/en/user/{}/profile'.format(session['username']['user_id']),
                     cookies=Utils.get_tvtime_cookies())
    series = parse_series_list(resp.text)
    return {'series': series, 'count': len(series)}

def parse_series_list(shows_page: str) -> List[any]:
    parser = BeautifulSoup(shows_page, 'html.parser')
    series = list()
    for element in parser.select('div#all-shows ul.shows-list.posters-list div.show'):
        show_name = element.select_one('div.poster-details > h2 > a').text.strip()
        if show_name == '':
            continue
        show_id = element.select_one('a.show-link')['href'].split('/')[3]
        progress = element.select_one('a.show-link div.progress-bar')['style'].split(':')[1].strip()
        time = element.select_one('div.poster-details > h3').text.strip()
        series.append({'id': int(show_id), 'progress': progress, 'name': show_name, 'time': time})
    return series

def get_show(show_id: int) -> Dict[str, Any]:
    resp = Utils.get('https://www.tvtime.com/en/show/{}'.format(show_id), cookies=Utils.get_tvtime_cookies())
    seasons = parse_season_list(resp.text)
    return {"count": len(seasons), "seasons": seasons}

def parse_season_list(show_page: str) -> List[Any]:
    parser = BeautifulSoup(show_page, 'html.parser')
    seasons = list()
    for season_element in parser.select("div#show-seasons > div.seasons > div.season-content"):
        season_name = season_element.select_one("span[itemprop='name']").text.strip()
        num_episodes = season_element.select_one("span[itemprop='numberOfEpisodes']").text.strip()
        episodes = list()
        for episode_element in season_element.select("ul.episode-list > li.episode-wrapper > div.infos > div.row"):
            episode_id = episode_element.select_one('a')['href'].split('/')[5]
            episode_number = episode_element.select_one('span.episode-nb-label').text.strip()
            episode_name = episode_element.select_one('span.episode-name').text.strip()
            episode_air_date = episode_element.select_one('span.episode-air-date').text.strip()
            watched = 'active' in episode_element.parent.parent.select_one('div.actions > div.row > a')['class']
            episodes.append(
                {"id": episode_id, "number": episode_number, "name": episode_name, "air_date": episode_air_date,
                 "watched": watched})
        seasons.append({"name": season_name, "number_of_episodes": num_episodes, "episodes": episodes})
    return seasons


# Breakfast: 7AM - 9AM
# Lunch: 12PM - 2PM
# Dinner: 7PM - 9PM
# Hammer: 10PM - 4AM

time = input('What time is it (HH:AM/PM)?: ')
time_split = time.split(':')
hour = int(time_split[0])
meridian = time_split[1].lower()

if hour in range(7, 10):
    if meridian == 'am':
        print("It's Breakfast!")
    else:
        print("It's Dinner!")
elif hour in [12, 1, 2] and meridian == 'pm':
    print("It's Lunch!")
elif hour in range(10, 12) and meridian == 'pm' or (hour == 12 or hour in range(1, 5)) and meridian == 'am':
    print("It's Hammer TIME!")


"""clear

Revision ID: 0856da4f1911
Revises: 16c917fc83ca
Create Date: 2023-01-19 14:15:59.463988

"""
from alembic import op
from sqlalchemy import delete
from sqlalchemy.orm import Session

from lib.db.models import Client, Balance
from lib.db.models.trade import Trade
from lib.db.models.transfer import Transfer

# revision identifiers, used by Alembic.
revision = '0856da4f1911'
down_revision = '16c917fc83ca'
branch_labels = None
depends_on = None

def upgrade():
    session = Session(bind=op.get_bind())
    for client in session.query(Client):
        client.last_execution_sync = None
        client.last_transfer_sync = None
    session.execute(delete(Trade))
    session.execute(delete(Balance))
    session.execute(delete(Transfer))

def downgrade():
    session = Session(bind=op.get_bind())
    pass


def inorder(p, N):  # N은 완전 이진트리의 마지막 정점

    if p <= N:
        inorder(p * 2, N)
        print(tree[p], end='')
        inorder(p * 2 + 1, N)

T = 10

for tc in range(1, T + 1):
    N = int(input())

    # 어떻게 저장해야 문제를 풀 때 편할까를 생각해야한다.

    tree = [0] * (N + 1)  # N번 노드까지 있는 완전이진트리
    for _ in range(N):
        arr = list(input().split())
        tree[int(arr[0])] = arr[1]

    print(f'#{tc}', end=' ')
    inorder(1, N)   # root = 1
    print()