""" Deep RL Algorithms for OpenAI Gym environments
"""
import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from utils import create_output_video
from semantic_encoding.utils import load_checkpoint
from semantic_encoding._utils.experiment_to_video_mapping import Experiment2VideoMapping
from REINFORCE.agent import Agent
from envs import VideoEnvironment
import argparse
import numpy as np
import socket
import torch
import json
import random
import pandas as pd
import config
from tqdm import tqdm
from datetime import datetime as dt

import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
random.seed(123)

# os.environ['CUDA_LAUNCH_BLOCKING'] = '1' # This is for debugging errors only (https://lernapparat.de/debug-device-assert/), uncomment it when necessary
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'

def parse_args(args):
    """ Parse arguments from command line input
    """
    parser = argparse.ArgumentParser(description='Training parameters')

    # General training input
    parser.add_argument('-s', '--semantic_encoder_model_filename', type=str, required=True, help='Semantic encoder model path filename')
    parser.add_argument('-m', '--reinforce_model_filename', type=str, help='Policy Model path filename to resume training... (If not provided, the agent learns from scratch)')
    parser.add_argument('-febs', '--feature_extraction_batch_size', type=int, default=16, help="Batch size for feature extraction")

    # General testing inputs
    parser.add_argument('-x', '--speedup', type=int, default=0, help='Desired speed-up to be achieved by the agent (WARNING: For training, leave it as default=0 for random selection)')
    parser.add_argument('-u', '--user_document_filename', type=str, default=None, help="Name (complete path) of the sentences document file")
    parser.add_argument('-i', '--input_video_filename', type=str, help="Name (complete path) of the input video file")
    parser.add_argument('-e', '--experiment', type=str, help="Name of the experiment video file [e.g. T2lxCGJ9ekg]")

    # Dataset params
    parser.add_argument('-d', '--dataset', type=str, help="Name of the dataset that will be used for training [e.g., YouCook2, COIN]")
    parser.add_argument('--cvpr2020_subset', dest='cvpr2020_subset', action='store_true', help="Use the CVPR'20 YouCook2's subset (videos with at most 25 percent composed of relevant frames)")
    parser.add_argument('-dm', '--domain', type=str, dest='domain', help="One of the following domains: ['NC', 'V', 'LP', 'G', 'EA', 'FD', 'SC', 'PF', 'DS', 'D', 'S', 'H']")

    # Agent params
    parser.add_argument('-g', '--gamma', type=float, default=0.99, help='Gamma value (γ ∈ (0, 1]) - The discounting factor')
    parser.add_argument('-eb', '--entropy_beta', type=float, default=1e-2, help='Beta value (β) for the entropy H')
    parser.add_argument('-lr', '--learning_rate', type=float, default=5e-5, help='Learning rate for any algorithm')
    parser.add_argument('-cr', '--critic_lr', type=float, default=1e-3, help='Learning rate for the Critic branch')
    parser.add_argument('-bs', '--batch_size', type=int, default=1, help='Size of the batch of videos for training the agent (default is 1)')
    parser.add_argument('-lb', '--lambda', dest='lambda_param', type=str, default='F*', help="Define the value for λ (which controls the relative importance of the overall speed-up rate). [F* (desired_num_frames) | F (num_frames) | 0 (Ignore Speed-up Reward)]")
    parser.add_argument('-sg', '--sigma', dest='sigma_param', type=float, default=0.5, help="Define the value for σ (which controls how thin the bell curve w.r.t. overall speed-up rate will be - standard deviation of a gauss function). Default: 0.5")

    # Ablation params
    parser.add_argument('--use_vdan', dest='use_vdan', action='store_true', help="Define the usage of VDAN feature extractor instead of VDAN+")
    parser.add_argument('--no_positional_encoding', dest='no_positional_encoding', action='store_true', help="Disable the usage of NRPE")
    parser.add_argument('--no_skip_info', dest='no_skip_info', action='store_true', help="Disable the usage of SA")

    # Video rendering and output params
    parser.add_argument('--create_video', dest='create_video', action='store_true', help="Create the output video based on the test environment")
    parser.add_argument('--print_details', dest='print_details', action='store_true', help="Print the speed-up and the groundtruth locations in the created video")

    parser.set_defaults(cvpr2020_subset=False, is_test=False, include_test=False, use_vdan=False, no_positional_encoding=False, no_skip_info=False, create_video=False, print_details=False)
    return parser.parse_args(args)

def test(args, test_envs, annotations):

    env = test_envs[list(test_envs.keys())[0]]

    agent = Agent(state_size=env.state_size, action_size=env.action_size, lr=args.learning_rate, critic_lr=args.critic_lr, gamma=args.gamma, entropy_beta=args.entropy_beta, annotations=annotations)
    agent.load_model(args.reinforce_model_filename)

    hostname = socket.gethostname()

    if args.experiment:
        json_sf = {'info': {'version': 'v1.1_{}'.format(dt.now().strftime('%Y%m%d_%H%M%S')), 'dataset': env.experiment.dataset}, 'data': {}}

        with torch.no_grad():
            agent.test(env, args.dataset, args.experiment, log=True)
        sf = env.selected_frames

        agent.write_selected_frames_image_to_log(env, 0, 'Test_{}'.format(args.experiment))
        agent.write_rewards_image_to_log(env, agent.rewards, 0, 'Rewards_Test_{}'.format(args.experiment))
        agent.writer.close()

        output_filename = f'results/{dt.now().strftime("%Y%m%d_%H%M%S")}_agent{agent.creation_timestamp}_lr{agent.lr}_gamma{agent.gamma}_{hostname}_sf_{args.experiment}.npy'

        print('Saved to: {}'.format(output_filename))

        if env.experiment.dataset in ['YouCook2', 'COIN']:
            json_sf['data'][args.experiment] = {'file_name': os.path.abspath(output_filename), 'recipe_id': env.experiment.recipe_id, 'split': 'test', 'frames': list(np.array(sf, dtype=str))}

        if args.create_video:
            create_output_video(args, env, output_filename)

    elif args.input_video_filename:
        video_basename = os.path.basename(args.input_video_filename).split('.')[0]

        print(f'\nTesting: {video_basename}')
        with torch.no_grad():
            agent.test(env, video_basename, video_basename, log=True)

        sf = env.selected_frames

        agent.write_selected_frames_image_to_log(env, 0, 'Test_{}'.format(video_basename))
        agent.write_rewards_image_to_log(env, agent.rewards, 0, 'Rewards_Test_{}'.format(video_basename))
        agent.writer.close()

        output_filename = f'results/{dt.now().strftime("%Y%m%d_%H%M%S")}_agent{agent.creation_timestamp}_lr{agent.lr}_gamma{agent.gamma}_{hostname}_sf_{video_basename}.npy'

        print(f'Saved to: {output_filename}')

        if args.create_video:
            create_output_video(args, env, output_filename)
    else:
        json_sf = {'info': {'version': 'v1.1_{}'.format(dt.now().strftime('%Y%m%d_%H%M%S')), 'dataset': args.dataset}, 'data': {}}
        curr_avg_speedup = np.array([np.float('nan')]*len(test_envs), dtype=np.float32)
        pbar = tqdm(test_envs.items(), desc=f'Testing Envs | Curr. Avg. Speedup -> {np.nanmean(curr_avg_speedup)}')
        for exp_idx, (exp_key, env) in enumerate(pbar):

            with torch.no_grad():
                agent.test(env, args.dataset, exp_key)

            sf = env.selected_frames
            curr_avg_speedup[exp_idx] = float(env.num_frames)/len(env.selected_frames)
            pbar.set_description(f'Testing Envs | Curr. Avg. Speedup -> {np.nanmean(curr_avg_speedup)}')

            agent.write_selected_frames_image_to_log(env, 0, 'Test_{}'.format(args.dataset), suffix=exp_key)
            agent.write_rewards_image_to_log(env, agent.rewards, 0, 'Rewards_Test_{}'.format(args.dataset), suffix=exp_key)
            agent.writer.close()

            output_filename = f'results/{args.dataset}/{dt.now().strftime("%Y%m%d_%H%M%S")}_agent{agent.creation_timestamp}_lr{agent.lr}_gamma{agent.gamma}_{hostname}_sf_{exp_key}.npy'

            if args.dataset in ['YouCook2', 'COIN']:
                json_sf['data'][exp_key] = {'file_name': os.path.abspath(output_filename), 'recipe_id': env.experiment.recipe_id, 'split': 'test', 'frames': list(np.array(sf, dtype=str))}

            if args.create_video:
                create_output_video(args, env, output_filename)

    if args.dataset in ['YouCook2', 'COIN']:
        output_json_filename = f'results/{agent.creation_timestamp}_{hostname}_{args.dataset.lower()}_ours_selected_frames{f"_{args.domain}" if args.domain else ""}_{args.speedup}x.json'

        with open(output_json_filename, 'w') as f:
            json.dump(json_sf, f, sort_keys=True)
            print(f'\nJSON results file saved at: {output_json_filename}')

if __name__ == "__main__":
    # Parse arguments
    args = parse_args(sys.argv[1:])

    print(f'[{dt.now().strftime("%Y-%m-%d %H:%M:%S")}] Loading saved model weights: {args.semantic_encoder_model_filename}...')

    _, semantic_encoder_model, _, word_map, model_params, train_params = load_checkpoint(args.semantic_encoder_model_filename, is_vdan=args.use_vdan)
    semantic_encoder_model.to(device)
    semantic_encoder_model.eval()

    semantic_encoder_data = {
        'model_name': os.path.basename(os.path.splitext(args.semantic_encoder_model_filename)[0]),
        'semantic_encoder_model': semantic_encoder_model,
        'word_map': word_map,
        'train_params': train_params,
        'model_params': model_params,
        'input_frames_length': 32
    }
    print(f'[{dt.now().strftime("%Y-%m-%d %H:%M:%S")}] Done!\n')

    annotations = None
    if args.experiment:
        if args.experiment.startswith('\\'):
            args.experiment = args.experiment[1:]

        exp_map = Experiment2VideoMapping(args.experiment)

        annotations = json.load(open(config.annotations_filenames[exp_map.dataset]))

        env = VideoEnvironment(semantic_encoder_data, document_filename=args.user_document_filename, dataset_name=exp_map.dataset, experiment_name=args.experiment, batch_size=args.feature_extraction_batch_size, speedup=args.speedup, use_vdan=args.use_vdan, no_positional_encoding=args.no_positional_encoding, no_skip_info=args.no_skip_info, lambda_param=args.lambda_param, sigma_param=args.sigma_param)

        test_envs = {args.experiment: env}

        args.dataset = exp_map.dataset

    elif args.input_video_filename:
        if not args.user_document_filename:
            print('\nPlease provide a text document using the option -u\n')
            exit(1)

        video_basename = os.path.basename(args.input_video_filename).split('.')[0]

        env = VideoEnvironment(semantic_encoder_data, document_filename=args.user_document_filename, input_video_filename=args.input_video_filename, batch_size=args.feature_extraction_batch_size, speedup=args.speedup, use_vdan=args.use_vdan, no_positional_encoding=args.no_positional_encoding, no_skip_info=args.no_skip_info, lambda_param=args.lambda_param, sigma_param=args.sigma_param)

        test_envs = {video_basename: env}

        args.dataset = video_basename

    elif args.dataset:

        experiments = np.array(Experiment2VideoMapping.get_dataset_experiments(args.dataset, cvpr2020_subset=args.cvpr2020_subset))
        random.shuffle(experiments)

        annotations = json.load(open(config.annotations_filenames[args.dataset]))

        test_set = []
        if args.dataset == 'YouCook2':
            for exp_name in tqdm(experiments, desc='Loading training and test set'):
                if annotations['database'][exp_name]['subset'] != 'training':
                    test_set.append(exp_name)

        elif args.dataset == 'COIN':
            if not args.domain:
                print('\nPlease provide a domain using the option -dm\n')
                exit(1)

            taxonomy = pd.read_csv(config.coin_taxonomy_filename, dtype=str)
            coin_domains_map = {'Nursing and Care': 'NC', 'Vehicle': 'V', 'Leisure and Performance': 'LP', 'Gadgets': 'G', 'Electrical Appliance': 'EA', 'Furniture and Decoration': 'FD', 'Science and Craft': 'SC', 'Pets and Fruit': 'PF', 'Drink and Snack': 'DS', 'Dish': 'D', 'Sport': 'S', 'Housework': 'H'}
            taxonomy_dict = {j: coin_domains_map[i] for i, j in zip(taxonomy['Domains'], taxonomy['Targets'])}

            for exp_name in tqdm(experiments, desc='Loading test set'):
                if annotations['database'][exp_name]['subset'] == 'testing' and taxonomy_dict[annotations['database'][exp_name]['class']] == args.domain:
                    test_set.append(exp_name)

        test_envs = {
            exp_key: VideoEnvironment(semantic_encoder_data, document_filename=args.user_document_filename, dataset_name=args.dataset, experiment_name=exp_key, batch_size=args.feature_extraction_batch_size, speedup=args.speedup, use_vdan=args.use_vdan, no_positional_encoding=args.no_positional_encoding, no_skip_info=args.no_skip_info, lambda_param=args.lambda_param, sigma_param=args.sigma_param)
            for exp_key in tqdm(test_set, desc='Loading test set envs')
        }

        print(f'\nTest set ({len(test_set)} videos):\n{", ".join(test_envs.keys())}\n')

    test(args, test_envs, annotations)


from tensorflow.keras.models import load_model
import numpy as np
import cv2
import os
import imutils
from PreProcessing import Preprocessor
from DigitAugment import DigitAugmenter

args = imutils.get_args(single_image=True)
img = cv2.imread(args["image"])
if img is None:
    raise FileNotFoundError("Please a valid path to the image.")

debug = False
method = 1

preprocessor = Preprocessor(640, 480, debug, method)
img, gray, canny, binary_img = preprocessor.preprocess(img)
img_ = img.copy()

augmenter = DigitAugmenter(transforms={"rotation": [-15, 15], "horizontal_shift": [-0.15, 0.15], "vertical_shift": [-0.15, 0.15]}, rescale=True)

minArea = 350
cnts, boundingBoxes = imutils.getExternalContours(img=binary_img, applySort=True, minArea=minArea, leverage=2, original=False)
number = 0
leverage = 10

models = [load_model(f"models\\digitnet_mnist_augment_decay_{i}.h5") for i in range(1, 6)]

for i, c in enumerate(cnts):
    x, y, w, h = boundingBoxes[i]
    aspect = w * 1.0 / h
    if w * h < minArea or aspect > 2.5 or aspect < 0.05:
        continue
    if method == 0:
        extract = gray[max(0, y - leverage):y + h + leverage, max(0, x - leverage):x + w + leverage]
        extract = cv2.threshold(extract, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
    else:
        extract = binary_img[max(0, y - leverage):y + h + leverage, max(0, x - leverage):x + w + leverage]
    extracts = augmenter.generate_batch(extract, 16, process=True)
    pred = models[0].predict(extracts)
    for j in range(1, 5):
        pred += models[j].predict(extracts)
    pred = pred.sum(axis=0)
    pred = np.argmax(pred)
    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
    cv2.putText(img, str(pred), (x + w // 2, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 0, 0), 1)

imutils.showImage(img_, img, "Final Output", together=True)
save_name = args['image'].split("\\")[-1]
cv2.imwrite(f"outputs\\result_{save_name}", np.hstack((img_, img)))


array1 = [1, 2, 3, 4, 5]
array2 = [4, 6, 2, 5, 9, 8]

def merge(left_array, right_array):
    """ Merges left and right arrays after sorting
    Args:
        left_array (list): array with elements
        right_array (list): array with elements
    Returns:
        list: merged sorted array
    """
    merged_array = []
    left_index = 0
    right_index = 0

    while len(left_array) > left_index and len(right_array) > right_index:
        if left_array[left_index] < right_array[right_index]:
            merged_array.append(right_array[right_index])
            right_index += 1
        else:
            merged_array.append(left_array[left_index])
            left_index += 1

    merged_array += left_array[left_index:]
    merged_array += right_array[right_index:]
    return merged_array

def mergeSort(array):
    """ recursively sorts array
    Args:
        array (list): array elements
    Return:
        list: sorted array
    """

    if len(array) <= 1:
        return array

    middle = len(array)//2
    left_array = array[:middle]
    right_array = array[middle:]
    left_array = mergeSort(left_array)
    right_array = mergeSort(right_array)
    return merge(left_array, right_array)

def rearrange_digits(array):
    """
    Rearrange Array Elements so as to form two number such that their sum is maximum.

    Args:
       input_list(list): Input List
    Returns:
       (int),(int): Two maximum sums
    """
    if array is None or array == []:
        return None

    if type(array) == str and type(array) != list:
        return -1

    sorted_array = mergeSort(array)
    left = ""
    right = ""
    for i in range(len(sorted_array)):
        if (i % 2) == 0:
            left += "{}".format(sorted_array[i])
        else:
            right += "{}".format(sorted_array[i])
    return [int(left), int(right)]

def test_function(test_case):
    output = rearrange_digits(test_case[0])
    solution = test_case[1]
    if sum(output) == sum(solution):
        print("Pass")
    else:
        print("Fail")

# Test cases
test_function([[1, 2, 3, 4, 5], [542, 31]])
test_function([[4, 6, 2, 5, 9, 8], [964, 852]])

# Edge cases

print(rearrange_digits(None))
print(rearrange_digits([]))
print(rearrange_digits(""))


from .. import config

class Anode():
    def __init__(self):
        self.name=None
        self.filename=None
        self.R=1.0
        self.lambda1=0.0
        self.lambda2=0.0
        self.isRead=False
    def Read(self):
        if self.isRead:
            return

        if self.filename is None:
            if self.name is None:
                raise Exception("Anode: Name is not set")
            ll=config.GetAnodeDict()
            if not self.name in ll.keys():
                raise Exception("Anode: File not found for "+self.name)
            self.filename=ll[self.name]

        lines=[]
        try:
            f=open(self.filename,"r")
            lines=f.readlines()
            f.close()
        except:
            raise Exception("Anode: Can not open/read file "+self.filename)

        msg="Anode: file "+self.filename+" is in a bad format"
        if (len(lines)<2):
            raise Exception(msg)
        data=lines[1].split()
        if (len(data)<3) :
            raise Exception(msg)

        try:
            self.lambda1=float(data[0])
            self.lambda2=float(data[1])
            self.R=float(data[2])
        except ValueError:
            raise Exception(msg)

        self.isRead=True

    def getLambda(self):
        self.Read()
        return (self.lambda1+self.R*self.lambda2)/(1.0+self.R)


import numpy as np
import sys
from sklearn.metrics import f1_score
from sklearn.kernel_approximation import RBFSampler
import code

if len(sys.argv) not in [4]:
    print("Usage: python compute_acc.py test_file text_embeddings category_embeddings ")
    exit(-1)

test_file = sys.argv[1]
text_file = sys.argv[2]
cat_file = sys.argv[3]

with open(test_file) as fin:
    labels = []
    for line in fin:
        label, _ = line.split(",", 1)
        if label.startswith("'") or label.startswith('"'):
            label = label[1:-1]
        labels.append(int(label) - 1)

    labels = np.array(labels)

text_embeddings = np.loadtxt(text_file)
cat_embeddings = np.loadtxt(cat_file)
num_cats = cat_embeddings.shape[0]

def euclidean(a, b):
    return np.sum((a - b) * (a-b), -1)

centroids = cat_embeddings
all_accs = []
all_scores = []

for k in range(100):
    centroids = np.expand_dims(centroids, 0)
    text_embeddings_unsqueezed = np.expand_dims(text_embeddings, 1)
    scores = euclidean(text_embeddings_unsqueezed, centroids)
    avg_score = np.mean(scores.min(1))
    all_scores.append(avg_score)

    new_preds = scores.argmin(1)
    if k > 0:
        change_of_preds = np.sum(preds != new_preds)
        print("change of preds: ", change_of_preds)
        print("average score: ", avg_score)

    # code.interact(local=locals())

    preds = new_preds
    acc = np.sum(preds == labels) / len(labels)
    all_accs.append(acc)

    print("after {} iterations of k means accuracy: {}".format(k, acc))

    centroids = []
    for i in range(num_cats):
        centroid = text_embeddings[preds == i]
        if centroid.shape[0] > 0:
            centroids.append(centroid.mean(0, keepdims=True))
        else:
            centroids.append(text_embeddings.mean(0, keepdims=True))

    centroids = np.concatenate(centroids, 0)
    centroids = (centroids + cat_embeddings) / 2

    if k > 0 and change_of_preds == 0:
        break

min_index = np.argmin(all_scores)
print("min avg score: ", all_scores[min_index], ", the corresponding accuracy: ", all_accs[min_index], ", max accuracy: ", max(all_accs))


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

import argparse
import itertools
import random
import shutil
import os
import sys
import time
import gc

import torch
import torch.nn as nn
from torch.autograd import Variable

import numpy as np

from hparams import Iwslt16EnDeBpe32SharedParams

class DataLoader(object):
  def __init__(self, hparams, decode=False):
    """Encloses both train and valid data.

    Args:
      hparams: must be ['tiny' 'bpe16' 'bpe32']
    """

    self.hparams = hparams
    self.decode = decode

    print("-" * 80)
    print("Building data for '{0}' from '{1}'".format(
      self.hparams.dataset, self.hparams.data_path))

    # vocab
    (self.source_word_to_index,
     self.source_index_to_word) = self._build_vocab(self.hparams.source_vocab)
    self.source_vocab_size = len(self.source_word_to_index)

    (self.target_word_to_index,
     self.target_index_to_word) = self._build_vocab(self.hparams.target_vocab)
    self.target_vocab_size = len(self.target_word_to_index)

    assert (self.source_word_to_index[self.hparams.pad] ==
            self.target_word_to_index[self.hparams.pad])
    assert (self.source_word_to_index[self.hparams.unk] ==
            self.target_word_to_index[self.hparams.unk])
    assert (self.source_word_to_index[self.hparams.bos] ==
            self.target_word_to_index[self.hparams.bos])
    assert (self.source_word_to_index[self.hparams.eos] ==
            self.target_word_to_index[self.hparams.eos])

    if (self.hparams.raml_source or (hasattr(self.hparams, "raml_target")
                                     and self.hparams.raml_target)):
      self.softmax = torch.nn.Softmax(dim=-1)

    if self.hparams.dist_corrupt:
      assert self.hparams.glove_emb_file is not None
      print("Reading GloVe from '{0}'".format(self.hparams.glove_emb_file))
      num_lines = 0
      vocab_size = 0
      #glove = {UNK: np.zeros(300, dtype=np.float32)}
      self.glove = torch.zeros(self.source_vocab_size, self.hparams.glove_emb_dim)
      with open(self.hparams.glove_emb_file, "r") as finp:
        for line in finp:
          # print(line)
          line = line.strip()
          if not line:
            continue

          tokens = line.split(" ")
          word = tokens[0]
          num_lines += 1
          if word not in self.source_word_to_index:
            continue
          vec = [float(v.strip()) for v in tokens[1:] if v.strip()]
          wid = self.source_word_to_index[word]
          self.glove[wid] = torch.FloatTensor(vec)
          #print(wid, word)
          #print(self.glove[wid])
          vocab_size += 1

          if num_lines % 1000 == 0:
            print("Read {0:>8d} lines, vocab_size={1}".format(num_lines,
                                                              vocab_size))
            gc.collect()
          if self.hparams.max_glove_vocab_size is not None and num_lines >= self.hparams.max_glove_vocab_size:
            break
        print("Read {0:>8d} lines, vocab_size={1}".format(num_lines,
                                                          vocab_size))
      if self.hparams.cuda:
        self.glove = self.glove.cuda()
    if self.decode:
      self.x_test, self.y_test = self._build_parallel(
        self.hparams.source_test, self.hparams.target_test, is_training=False)
      self.test_size = len(self.x_test)
      self.reset_test()
      return
    else:
      # train data
      self.x_train, self.y_train = self._build_parallel(
        self.hparams.source_train, self.hparams.target_train, is_training=True,
        sort=True)

      # signifies that x_train, y_train are not ready for batching
      self.train_size = len(self.x_train)
      self.n_train_batches = None
      self.reset_train()

      # valid data
      self.x_valid, self.y_valid = self._build_parallel(
        self.hparams.source_valid, self.hparams.target_valid, is_training=False)
      self.valid_size = len(self.x_valid)
      self.reset_valid()

  def reset_train(self):
    """Shuffle training data. Prepare the batching scheme if necessary."""

    if self.hparams.batcher == "word":
      if self.n_train_batches is None:
        start_indices, end_indices = [], []
        start_index = 0
        while start_index < self.train_size:
          end_index = start_index
          word_count = 0
          while (end_index + 1 < self.train_size and
                 (word_count +
                  len(self.x_train[end_index + 1]) +
                  len(self.y_train[end_index + 1])) <= self.hparams.batch_size):
            end_index += 1
            word_count += (len(self.x_train[end_index]) +
                           len(self.y_train[end_index]))
          start_indices.append(start_index)
          end_indices.append(end_index + 1)
          start_index = end_index + 1
        assert len(start_indices) == len(end_indices)
        self.n_train_batches = len(start_indices)
        self.start_indices = start_indices
        self.end_indices = end_indices
    elif self.hparams.batcher == "sent":
      if self.n_train_batches is None:
        self.n_train_batches = ((self.train_size + self.hparams.batch_size - 1)
                                // self.hparams.batch_size)
    else:
      raise ValueError("Unknown batcher scheme '{0}'".format(self.batcher))
    self.train_queue = np.random.permutation(self.n_train_batches)
    self.train_index = 0

  def reset_valid(self):
    self.valid_index = 0

  def reset_test(self):
    self.test_index = 0

  def next_test(self, test_batch_size=1, raml=False):
    end_of_epoch = False
    start_index = self.test_index
    end_index = min(start_index + test_batch_size, self.test_size)
    batch_size = end_index - start_index

    # pad data
    x_test = self.x_test[start_index: end_index]
    y_test = self.y_test[start_index: end_index]
    if raml:
      x_test = [sent for sent in x_test for _ in range(self.hparams.n_corrupts)]
      no_corrupt_mask = [0] * (self.hparams.n_corrupts-self.hparams.n_cleans) + [1] * self.hparams.n_cleans
      no_corrupt_mask = no_corrupt_mask * batch_size
      no_corrupt_mask = torch.ByteTensor(no_corrupt_mask).unsqueeze(1).byte()
      if self.hparams.cuda:
        no_corrupt_mask = no_corrupt_mask.cuda()
      x_test_raml, x_test, x_mask, x_pos_emb_indices, x_count = self._pad(
        sentences=x_test, pad_id=self.pad_id, raml=True,
        vocab_size=self.hparams.source_vocab_size, volatile=True,
        pad_corrupt=self.hparams.src_pad_corrupt,
        dist_corrupt=self.hparams.dist_corrupt,
        no_corrupt_mask=no_corrupt_mask, raml_tau=self.hparams.raml_src_tau)
    else:
      x_test, x_mask, x_pos_emb_indices, x_count = self._pad(
        sentences=x_test, pad_id=self.pad_id, volatile=True)

    y_test, y_mask, y_pos_emb_indices, y_count = self._pad(
      sentences=y_test, pad_id=self.pad_id, volatile=True)

    if end_index >= self.test_size:
      end_of_epoch = True
      self.test_index = 0
    else:
      self.test_index += batch_size

    if raml:
      return ((x_test_raml, x_test, x_mask, x_pos_emb_indices, x_count),
              (y_test, y_mask, y_pos_emb_indices, y_count),
              batch_size, end_of_epoch)
    else:
      return ((x_test, x_mask, x_pos_emb_indices, x_count),
              (y_test, y_mask, y_pos_emb_indices, y_count),
              batch_size, end_of_epoch)

  def next_valid(self, valid_batch_size=20):
    """Retrieves a sentence of testing examples.

    Returns:
      (x_valid, x_len): a pair of torch Tensors of size [batch, source_length]
        and [batch_size].
      (y_valid, y_len): a pair of torch Tensors of size [batch, target_length]
        and [batch_size].
      end_of_epoch: whether we reach the end of training examples.
    """

    end_of_epoch = False
    start_index = self.valid_index
    end_index = min(start_index + valid_batch_size, self.valid_size)
    batch_size = end_index - start_index

    # pad data
    x_valid = self.x_valid[start_index : end_index]
    y_valid = self.y_valid[start_index : end_index]
    x_valid, x_mask, x_pos_emb_indices, x_count = self._pad(
      sentences=x_valid, pad_id=self.pad_id, volatile=True)
    y_valid, y_mask, y_pos_emb_indices, y_count = self._pad(
      sentences=y_valid, pad_id=self.pad_id, volatile=True)

    # shuffle if reaches the end of data
    if end_index >= self.valid_size:
      end_of_epoch = True
      self.valid_index = 0
    else:
      self.valid_index += batch_size

    return ((x_valid, x_mask, x_pos_emb_indices, x_count),
            (y_valid, y_mask, y_pos_emb_indices, y_count),
            batch_size, end_of_epoch)

  def next_train(self):
    """Retrieves a batch of training examples.

    Returns:
      (x_train, x_len): a pair of torch Tensors of size [batch, source_length]
        and [batch_size].
      (y_train, y_len): a pair of torch Tensors of size [batch, target_length]
        and [batch_size].
      end_of_epoch: whether we reach the end of training examples.
    """
    if self.hparams.batcher == "word":
      start_index = self.start_indices[self.train_queue[self.train_index]]
      end_index = self.end_indices[self.train_queue[self.train_index]]
    elif self.hparams.batcher == "sent":
      start_index = (self.train_queue[self.train_index] *
                     self.hparams.batch_size)
      end_index = min(start_index + self.hparams.batch_size, self.train_size)
    else:
      raise ValueError("Unknown batcher '{0}'".format(self.hparams.batcher))

    x_train = self.x_train[start_index : end_index]
    y_train = self.y_train[start_index : end_index]
    self.train_index += 1
    batch_size = len(x_train)

    # pad data
    if self.hparams.raml_source:
      x_train_raml, x_train, x_mask, x_pos_emb_indices, x_count = self._pad(
        sentences=x_train, pad_id=self.pad_id, raml=True,
        raml_tau=self.hparams.raml_src_tau,
        vocab_size=self.hparams.source_vocab_size,
        pad_corrupt=self.hparams.src_pad_corrupt,
        dist_corrupt=self.hparams.dist_corrupt)
    else:
      x_train, x_mask, x_pos_emb_indices, x_count = self._pad(
        sentences=x_train, pad_id=self.pad_id)

    if self.hparams.raml_target:
      y_train_raml, y_train, y_mask, y_pos_emb_indices, y_count = self._pad(
        sentences=y_train, pad_id=self.pad_id, raml=True,
        raml_tau=self.hparams.raml_tau,
        vocab_size=self.hparams.target_vocab_size,
        pad_corrupt=self.hparams.trg_pad_corrupt)
    else:
      y_train, y_mask, y_pos_emb_indices, y_count = self._pad(
        sentences=y_train, pad_id=self.pad_id)

    # shuffle if reaches the end of data
    if self.train_index > self.n_train_batches - 1:
      self.reset_train()

    if self.hparams.raml_source and self.hparams.raml_target:
      return ((x_train_raml, x_train, x_mask, x_pos_emb_indices, x_count),
              (y_train_raml, y_train, y_mask, y_pos_emb_indices, y_count),
              batch_size)

    if self.hparams.raml_source:
      return ((x_train_raml, x_train, x_mask, x_pos_emb_indices, x_count),
              (y_train, y_mask, y_pos_emb_indices, y_count),
              batch_size)

    if self.hparams.raml_target:
      return ((x_train, x_mask, x_pos_emb_indices, x_count),
              (y_train_raml, y_train, y_mask, y_pos_emb_indices, y_count),
              batch_size)

    return ((x_train, x_mask, x_pos_emb_indices, x_count),
            (y_train, y_mask, y_pos_emb_indices, y_count),
            batch_size)

  def _pad(self, sentences, pad_id, volatile=False,
           raml=False, raml_tau=1., vocab_size=None, pad_corrupt=False,
           dist_corrupt=False, no_corrupt_mask=None):
    """Pad all instances in [data] to the longest length.

    Args:
      sentences: list of [batch_size] lists.

    Returns:
      padded_sentences: Variable of size [batch_size, max_len], the sentences.
      mask: Variable of size [batch_size, max_len]. 1 means to ignore.
      pos_emb_indices: Variable of size [batch_size, max_len]. indices to use
        when computing positional embedding.
      sum_len: total number of words.
      raml: if True, the sentences will be replaced by their samples according
        to the exp payoff distribution, ie. exp(-HammingDist(s, sents)).
      vocab_size: if raml is True, vocab_size has to be specified for negative
        sampling.
      dist_corrupt: if is set to True, sample corrupt words based on word
        embedding distance.
      no_corrupt_mask: [batch_size, 1] if is set, then 1 means not to corrupt
        the sentence.
    """

    batch_size = len(sentences)
    lengths = [len(sentence) for sentence in sentences]
    sum_len = sum(lengths)
    max_len = max(lengths)

    padded_sentences = [
      sentence + ([pad_id] * (max_len - len(sentence)))
      for sentence in sentences]
    mask = [
      ([0] * len(sentence)) + ([1] * (max_len - len(sentence)))
      for sentence in sentences]
    pos_emb_indices = [
      [i+1 for i in range(len(sentence))] + ([0] * (max_len - len(sentence)))
      for sentence in sentences
    ]
    if raml:
      raml_mask = [
        [1] + ([0] * (len(sentence)-2)) + ([1] * (max_len-len(sentence)+1))
        for sentence in sentences]
      raml_mask = torch.ByteTensor(raml_mask)
      if self.hparams.cuda:
        raml_mask = raml_mask.cuda()
    padded_sentences = Variable(torch.LongTensor(padded_sentences))
    mask = torch.ByteTensor(mask)
    pos_emb_indices = Variable(torch.FloatTensor(pos_emb_indices))

    if self.hparams.cuda:
      padded_sentences = padded_sentences.cuda()
      mask = mask.cuda()
      pos_emb_indices = pos_emb_indices.cuda()

    if not raml:
      return padded_sentences, mask, pos_emb_indices, sum_len

    assert vocab_size is not None
    # first, sample the number of words to corrupt for each sentence
    logits = torch.arange(max_len)
    if self.hparams.cuda:
      logits = logits.cuda()
    logits = logits.mul_(-1).unsqueeze(0).expand_as(
      padded_sentences).contiguous().masked_fill_(mask, -self.hparams.inf)
    logits = Variable(logits, volatile=True)
    if self.hparams.cuda:
      logits = logits.cuda()
    probs = self.softmax(logits.mul_(raml_tau))
    num_words = torch.distributions.Categorical(probs).sample()

    # sample the indices
    lengths = torch.FloatTensor(lengths)
    if self.hparams.cuda:
      lengths = lengths.cuda()

    # mask out bos, eos
    corrupt_pos = num_words.data.float().div_(lengths-2).unsqueeze(
      1).expand_as(padded_sentences).contiguous().masked_fill_(raml_mask, 0)
    if no_corrupt_mask is not None:
      corrupt_pos.masked_fill_(no_corrupt_mask, 0)
    corrupt_pos = torch.bernoulli(corrupt_pos, out=corrupt_pos).byte()
    total_words = int(corrupt_pos.sum())
    if total_words == 0:
      return padded_sentences, padded_sentences, mask, pos_emb_indices, sum_len
    if dist_corrupt:
      # sample words according to distance
      words_to_corrupt = padded_sentences.data.masked_select(corrupt_pos)
      # (num_words, dim)
      words_emb_to_corrupt = torch.index_select(self.glove, dim=0, index=words_to_corrupt)
      # (num_words, num_vocab)
      w12 = torch.mm(words_emb_to_corrupt, self.glove.permute(1, 0))
      # (num_words, 1)
      w1 = torch.norm(words_emb_to_corrupt, 2, dim=1, keepdim=True)
      # (num_vocab, 1)
      w2 = torch.norm(self.glove, 2, dim=1, keepdim=True)
      # (num_words, num_vocab)
      distance = w12 / ((torch.mm(w1, w2.permute(1, 0))).clamp(min=1e-8))
      distance = Variable(distance)
      if self.hparams.cuda:
        distance = distance.cuda()
      # mask out the original words
      add = torch.arange(total_words).long()*vocab_size
      if self.hparams.cuda:
        add = add.cuda()
      corrupt_mask_index = (words_to_corrupt + add)
      distance = distance.view(-1)
      distance.data.index_fill_(0, corrupt_mask_index, -self.hparams.inf)
      distance = distance.view(total_words, -1)
      probs = torch.nn.functional.softmax(distance.mul_(self.hparams.dist_corrupt_tau), dim=1)
      corrupt_val = torch.distributions.Categorical(probs).sample().view(-1)
      #_, corrupt_val = torch.topk(probs, 1)

      if self.hparams.cuda:
        corrupt_val = corrupt_val.long().cuda()
        corrupt_pos = corrupt_pos.cuda()
      sample_sentences = padded_sentences.masked_scatter(Variable(corrupt_pos), corrupt_val)
    else:
      # sample the corrupts, which will be added to padded_sentences
      corrupt_val = torch.LongTensor(total_words)
      if pad_corrupt:
        corrupt_val.fill_(self.hparams.pad_id + vocab_size)
      else:
        corrupt_val = corrupt_val.random_(1, vocab_size)
      corrupts = torch.zeros(batch_size, max_len).long()
      if self.hparams.cuda:
        corrupt_val = corrupt_val.long().cuda()
        corrupts = corrupts.cuda()
        corrupt_pos = corrupt_pos.cuda()
      corrupts = corrupts.masked_scatter_(corrupt_pos, corrupt_val)

      sample_sentences = padded_sentences.add(Variable(corrupts)).remainder_(
        vocab_size).masked_fill_(Variable(mask), pad_id)
    #if dist_corrupt:
    #  print(sample_sentences)
    #  print(corrupt_val)
    #  print(words_to_corrupt)
    #  print(padded_sentences)
    #  print(corrupt_pos)
    #  corrupt_val = corrupt_val.data.view(-1).cpu().numpy()
    #  words_to_corrupt = words_to_corrupt.cpu().numpy()

    #  for c, w in zip(corrupt_val, words_to_corrupt):
    #    print("corrupt", self.source_index_to_word[c])
    #    print("orig", self.source_index_to_word[w])
    #  exit(0)
    return sample_sentences, padded_sentences, mask, pos_emb_indices, sum_len

  def _build_parallel(self, source_file, target_file, is_training, sort=False):
    """Build pair of data."""

    print("-" * 80)
    print("Loading parallel data from '{0}' and '{1}'".format(
      source_file, target_file))

    source_file = os.path.join(self.hparams.data_path, source_file)
    with open(source_file, encoding='utf-8') as finp:
      source_lines = finp.read().split("\n")

    target_file = os.path.join(self.hparams.data_path, target_file)
    with open(target_file, encoding='utf-8') as finp:
      target_lines = finp.read().split("\n")

    source_data, target_data = [], []
    source_lens = []
    total_sents = 0
    source_unk_count, target_unk_count = 0, 0
    for i, (source_line, target_line) in enumerate(
        zip(source_lines, target_lines)):
      source_line = source_line.strip()
      target_line = target_line.strip()
      if not source_line or not target_line:
        continue

      source_indices, target_indices = [self.bos_id], [self.bos_id]
      source_tokens = source_line.split(" ")
      target_tokens = target_line.split(" ")
      if is_training and len(target_line) > self.hparams.max_len:
        continue

      total_sents += 1

      for source_token in source_tokens:
        source_token = source_token.strip()
        if source_token not in self.source_word_to_index:
          source_token = self.hparams.unk
          source_unk_count += 1
        source_index = self.source_word_to_index[source_token]
        source_indices.append(source_index)

      for target_token in target_tokens:
        target_token = target_token.strip()
        if target_token not in self.target_word_to_index:
          target_token = self.hparams.unk
          target_unk_count += 1
        target_index = self.target_word_to_index[target_token]
        target_indices.append(target_index)

      source_indices.append(self.eos_id)
      target_indices.append(self.eos_id)

      source_lens.append(len(source_indices))
      source_data.append(source_indices)
      target_data.append(target_indices)

      if (self.hparams.n_train_sents is not None and
          self.hparams.n_train_sents <= total_sents):
        break

      if total_sents % 10000 == 0:
        print("{0:>6d} pairs. src_unk={1}. tgt_unk={2}".format(
          total_sents, source_unk_count, target_unk_count))

    assert len(source_data) == len(target_data)
    print("{0:>6d} pairs. src_unk={1}. tgt_unk={2}".format(
      total_sents, source_unk_count, target_unk_count))

    if sort:
      print("Heuristic sort based on source lens")
      indices = np.argsort(source_lens)
      source_data = [source_data[index] for index in indices]
      target_data = [target_data[index] for index in indices]

    return np.array(source_data), np.array(target_data)

  def _build_vocab(self, file_name):
    """Build word_to_index and index_to word dicts."""

    print("-" * 80)
    print("Loading vocab from '{0}'".format(file_name))
    file_name = os.path.join(self.hparams.data_path, file_name)
    with open(file_name, encoding='utf-8') as finp:
      lines = finp.read().split("\n")

    word_to_index, index_to_word = {}, {}
    for line in lines:
      line = line.strip()
      if not line:
        continue
      word_index = line.split("▁")
      if len(word_index) != 2:
        print("Weird line: '{0}'. split_len={1}".format(line, len(word_index)))
        continue
      word, index = word_index
      index = int(index)
      word_to_index[word] = index
      index_to_word[index] = word
      if word == self.hparams.unk:
        self.unk_id = index
      elif word == self.hparams.bos:
        self.bos_id = index
      elif word == self.hparams.eos:
        self.eos_id = index
      elif word == self.hparams.pad:
        self.pad_id = index

    assert len(word_to_index) == len(index_to_word), (
      "|word_to_index|={0} != |index_to_word|={1}".format(len(word_to_index),
                                                        len(index_to_word)))
    print("Done. vocab_size = {0}".format(len(word_to_index)))

    return word_to_index, index_to_word


from typing import Optional

_MAP = {
    "B": "BOARD",
    "L": "LIST",
    "T": "TASK",
}

def _abbr_to_type(abbr: str) -> str:
    return _MAP[abbr]

def _create_id(abbr: str, options: dict) -> str:
    options["counter"][abbr] += 1
    return f"{abbr}-{options['counter'][abbr]}"

def _create_item(
    id: str, board_id: str, name: str, abbr: str, parent: Optional[dict] = None
):
    return {
        "id": id,
        "parent_id": f"{parent['id'] if parent else id}",
        "board_id": board_id,
        "path": parent["path"] + "#" + id if parent else board_id,
        "name": name,
        "type": _abbr_to_type(abbr=abbr),
    }

def _process_items(
    event_items: list[dict],
    response_items: list[dict],
    board_id: str,
    options: dict,
    root: Optional[dict] = None,
) -> None:
    for event_item in event_items:
        item = _create_item(
            id=_create_id(event_item["type"], options),
            board_id=board_id,
            name=event_item["name"],
            abbr=event_item["type"],
            parent=root,
        )
        response_items.append(item)

        _process_items(
            event_items=event_item.get("items", []),
            response_items=response_items,
            board_id=board_id,
            options=options,
            root=item,
        )

def create(event_root: dict, options: dict):
    items_in_hierarchy = []

    board_id = _create_id(abbr="B", options=options)
    root_item = _create_item(
        id=board_id, board_id=board_id, name=event_root["name"], abbr="B"
    )

    items_in_hierarchy.append(root_item)

    _process_items(
        event_items=event_root["items"],
        response_items=items_in_hierarchy,
        board_id=board_id,
        options=options,
        root=root_item,
    )

    return items_in_hierarchy


# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import sys, os
sys.path.insert(0,os.path.abspath(os.path.pardir))
import gvjinja

# sphinx extension module globs
extensions = [
    'sphinx.ext.autodoc',
    'sphinx.ext.viewcode',
    ]

source_suffix = ['.rst',]
master_doc = 'index'
project = 'gvjinja'
copyright = '2017, Victor Hui'
author = 'Victor Hui'
version = gvjinja.__version__
release = gvjinja.__version__
add_module_names = False
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
pygments_style = 'sphinx'
html_theme = 'alabaster'
html_static_path = ['_static']
html_sidebars = {'**':[]}


import logging
import keras
import numpy as np
import tensorflow as tf

_log = logging.getLogger('MLProject')

class NNAgent:
    def __init__(self, state_space_shape, action_space_size):
        """
        Creates a NNAgent and initializes its neural network with random weights.
        :param state_space_shape: the shape of the state space
        :param action_space_size: the number of actions in the action space
        """
        hidden_layer_size = np.prod(state_space_shape)
        self.state_space_shape = state_space_shape
        self.action_space_size = action_space_size

        # Create a unique tensorflow graph and session for this agent only
        self._tf_graph = tf.Graph()
        self._tf_sess = tf.Session(graph=self._tf_graph)

        # Set this model's graph and session as the default one, so the model is assigned to them
        with self._tf_graph.as_default(), self._tf_sess.as_default():
            self._model = tf.keras.Sequential([
                tf.keras.layers.Reshape((hidden_layer_size,), input_shape=state_space_shape),  # Flatten the state
                # tf.keras.layers.Flatten(),                       # Note: Reshape and Flatten yield different results
                tf.keras.layers.Dense(hidden_layer_size),         # First hidden layer with as many neurons as state pixels
                # tf.keras.layers.Dense(hidden_layer_size),         # Second hidden layer
                # tf.keras.layers.Dense(hidden_layer_size // 2),    # Third hidden layer
                tf.keras.layers.Dense(action_space_size),         # Output layer
                tf.keras.layers.Activation('softmax')             # Softmax activation
            ])

    def act(self, state: np.ndarray):
        """
        Acts on a state. Returns the best action to take based on the given state.
        :param state: the state, as an ndarray
        :return: an ndarray with the same number of elements as the action space size
        """
        with self._tf_graph.as_default(), self._tf_sess.as_default():
            # We don't use batching, so we wrap the state into a batch array which we
            # feed into model.predict(). Then we un-wrap the prediction from its batch array
            state_batch = np.reshape(state, (1, *state.shape))
            action = self._model.predict(state_batch, batch_size=1)[0]
        return action

    def save_model(self, filename):
        with self._tf_graph.as_default(), self._tf_sess.as_default():
            self._model.save(filename)

    def load_model(self, filename):
        with self._tf_graph.as_default(), self._tf_sess.as_default():
            self._model = keras.models.load_model(filename)

    def get_weights(self):
        """
        Returns the weights of the NN for this agent.
        :return:
        """
        with self._tf_graph.as_default(), self._tf_sess.as_default():
            weights = self._model.get_weights()
        return weights

    def set_weights(self, new_weights):
        """
        Sets new weights for the NN of this agent.
        :param new_weights:
        :return:
        """
        with self._tf_graph.as_default(), self._tf_sess.as_default():
            self._model.set_weights(new_weights)

if __name__ == '__main__':
    def vectofixedstr(vec, presicion=8):
        ret = []
        for el in vec:
            ret.append('{:.{}f}'.format(el, presicion))
        return '[' + ' '.join(ret) + ']'

    agent = NNAgent(state_space_shape=(10,), action_space_size=5)
    action = agent.act(np.array([1, 3, 5, 7, 2, 4, 6, 8, 9, 9]))
    print(vectofixedstr(action))
    print(np.argmax(action))


from ast import And
try:
    from robot.libraries.BuiltIn import BuiltIn
    from robot.libraries.BuiltIn import _Misc
    import robot.api.logger as logger
    from robot.api.deco import keyword
    ROBOT = False
except Exception:
    ROBOT = False

def eat_ghost(power_pellet_active, touching_ghost):
    """

    :param power_pellet_active: bool - does the player have an active power pellet?
    :param touching_ghost:  bool - is the player touching a ghost?
    :return: bool
    """
    eat = False
    if ((power_pellet_active == True) and (touching_ghost == True)):
        eat = True
    BuiltIn().log_to_console(f"Input {power_pellet_active} and {touching_ghost}, Output {eat}")
    return eat

def score(touching_power_pellet, touching_dot):
    """

    :param touching_power_pellet: bool - does the player have an active power pellet?
    :param touching_dot:  bool - is the player touching a dot?
    :return: bool
    """
    score = False
    if ((touching_power_pellet == True) or (touching_dot == True)):
        score = True
    BuiltIn().log_to_console(f"Input {touching_power_pellet} and {touching_dot}, Output {score}")
    return score

def lose(power_pellet_active, touching_ghost):
    """

    :param power_pellet_active: bool - does the player have an active power pellet?
    :param touching_ghost: bool - is the player touching a ghost?
    :return: bool
    """
    eat = False
    if ((power_pellet_active == False) and (touching_ghost == True)):
        eat = True
    BuiltIn().log_to_console(f" lose Function: Input {power_pellet_active} and {touching_ghost}, Output {eat}")
    return eat

def win(has_eaten_all_dots, power_pellet_active, touching_ghost):
    """

    :param has_eaten_all_dots: bool - has the player "eaten" all the dots?
    :param power_pellet_active: bool - does the player have an active power pellet?
    :param touching_ghost:  bool - is the player touching a ghost?
    :return: bool
    """
    win = False
    if ((has_eaten_all_dots == True) and (lose(power_pellet_active,touching_ghost) == False)):
        win = True
    BuiltIn().log_to_console(f"Input {power_pellet_active} and {touching_ghost} and {has_eaten_all_dots}, Output {win}")
    return win


import tkinter as tk

root= tk.Tk()

canvas1 = tk.Canvas(root, width = 400, height = 300,  relief = 'raised')
canvas1.pack()

label1 = tk.Label(root, text='Compilador')
label1.config(font=('Impact', 20))
canvas1.create_window(200, 25, window=label1)

label2 = tk.Label(root, text='Digite sua frase:')
label2.config(font=('helvetica', 10))
canvas1.create_window(200, 100, window=label2)

entry1 = tk.Entry (root)
canvas1.create_window(200, 140, window=entry1)

def Analisador ():
    frase = entry1.get()
    espaços = 0
    caractere = 0
    frasesemespaco = ""

    for letra in range(0,len(frase)):

        if frase[letra] == " ":
            espaços += 1
        else:
            frasesemespaco += frase[letra]
            caractere += 1

    #print(frase)

    label3 = tk.Label(root, text= 'A frase que você digitou é: ' + frase,font=('helvetica', 10))
    canvas1.create_window(200, 210, window=label3)

    #label4 = tk.Label(root, text= frase,font=('helvetica', 10, 'bold'))
    #canvas1.create_window(240, 230, window=label4)

    label5 = tk.Label(text= 'Total de caracteres encontrados: ' + str(caractere),font=('helvetica', 10))
    canvas1.create_window(200, 240, window=label5)

    label6 = tk.Label(text= 'Total de espaços em branco encontrados: ' + str(espaços),font=('helvetica', 10))
    canvas1.create_window(200, 260, window=label6)

    label7 = tk.Label(text= 'Frase sem nenhum espaço (concatenado): ' + str(frasesemespaco),font=('helvetica', 10))
    canvas1.create_window(200, 280, window=label7)

button1 = tk.Button(text='Analisar', command=Analisador, bg='brown', fg='white', font=('helvetica', 9, 'bold'))
canvas1.create_window(325, 138, window=button1)

root.mainloop()


import re

PUZZLE_INPUT = '1113222113'

def solution(repeat: int) -> int:
	new_sequence = [PUZZLE_INPUT]
	for i in range(repeat):
		digit_counts = re.finditer(r'(\d)\1*', ''.join(new_sequence))
		new_sequence.clear()
		for occurance in digit_counts:
			#For each digit the new sequence is [occurances of digit][digit]
			new_sequence.extend([str(len(occurance.group())), occurance.group()[0]])
	return len(new_sequence)

print(f'The length of the result is {solution(repeat=40)} after 40 runs (Part One)')
print(f'The length of the result is {solution(repeat=50)} after 50 runs (Part Two)')


#!/usr/bin/env python

import numpy as np
try:
    import cPickle
except ImportError:
      import pickle
from scipy.optimize import fmin_bfgs, fmin_l_bfgs_b
import sys
import os
from builtins import range

def calc_wfk(gi,ni,wki):
    """processing of data to perform binlessWHAM calculations

    Parameters
    ----------
    gi : 1D numpy array
        vector of relative free energies, with lenght N-1
    ni : 1D numpy array
        vector with lenght equal to the number of biases (weighted by the inefficiency factor), containing their lenghts as elements
    wki: 2D numpy array
        matrix (5) in binlessWHAM.pdf containing the potential energy of structure k and bias i

    Returns
    -------
    gi : 1D numpy array
        vector of relative free energies, with lenght N
    wfk : 1D numpy array
        inverse weight from the product of matrix multiplication of w and f
    wfki : 2D numpy array
        components product of w and f

    """
    nfix = 2
    gj = np.append(gi,0.) # Here we assume that g_N is the fixed free energy
    #gj = np.append(gi[:nfix],0.)
    #gj = np.append(gj,gi[nfix:])
    fi = ni*np.exp(gj)
    wfki = fi*wki
    wfk = np.sum(wfki,axis=1) # sum over i, len(wfk) should be M
    return gj, wfk, wfki

def F(gi,ni,wki,Ii,Ii_kini):
    """formula (7) in binlessWHAM.pdf

    In the nomenclature i is an index for the bias and k is an index for the structure.

    Parameters
    ----------
    gi : 1D numpy array
        vector of relative free energies, with length N-1
    ni : 1D numpy array
        vector with lenght equal to the number of biases, containing their lenghts as elements
    wki: 2D numpy array
        matrix (5) in binlessWHAM.pdf containing the potential energy of structure k and bias i
    Ii : 1D numpy array
        vector with length equal to the number of biases, containing their inefficiency factors
        efficiency factor Ii = 1/(1+2*tau_i) with tau_i the correlation time in biased run i
    Ii_kini : 1D numpy array
        vector with length equal to the number of structures, containing the inefficiency of their respective run

    Returns
    -------
    np.sum(Ii_kini*np.log(wfk/Ii_kini),axis=0) - np.sum(Ii*gi*ni,axis=0) : 1D numpy array
        value of the funtion F

    """
    gi, wfk, wfki = calc_wfk(gi,ni,wki)
    return np.sum(Ii_kini*np.log(wfk/Ii_kini),axis=0) - np.sum(gi*ni,axis=0)

def grad_F(gi,ni,wki,Ii,Ii_kini):
    """gradient of F, formula (8) in binlessWHAM.pdf

    In the nomenclature i is an index for the bias and k is an index for the structure.

    Parameters
    ----------
    gi : 1D numpy array
        vector of relative free energies, with lenght N-1
    ni : 1D numpy array
        vector with lenght equal to the number of biases, containing their lenghts as elements
    wki: 2D numpy array
        matrix (5) in binlessWHAM.pdf containing the potential energy of structure k and bias i
    Ii : 1D numpy array
        vector with length equal to the number of biases, containing their inefficiency factors
        efficiency factor Ii = 1/(1+2*tau_i) with tau_i the correlation time in biased run i
    Ii_kini : 1D numpy array
        vector with length equal to the number of structures, containing the inefficiency of their respective run

    Returns
    -------
    grad[:-1] : 1D numpy array
        F gradient as vector for components 1 ... N-1

    """
    gi, wfk, wfki = calc_wfk(gi,ni,wki)
    wfkiT = wfki.transpose()
    grad = np.sum(Ii_kini * wfkiT/wfk,axis=1)-ni # sum over k, len should be N
    return grad[:-1] # Here we assume that g_N is the fixed free energy

def hessian_F(gi, ni, wki, Ii, Ii_kini):
    """Hessian matrix of F

    In the nomenclature i is an index for the bias and k is an index for the structure.

    Parameters
    ----------
    gi : 1D numpy array
        vector of relative free energies, with lenght N-1
    ni : 1D numpy array
        vector with lenght equal to the number of biases, containing their lenghts as elements
    wki: 2D numpy array
        matrix (5) in binlessWHAM.pdf containing the potential energy of structure k and bias i
    Ii : 1D numpy array
        vector with length equal to the number of biases, containing their inefficiency factors
        efficiency factor Ii = 1/(1+2*tau_i) with tau_i the correlation time in biased run i
    Ii_kini : 1D numpy array
        vector with length equal to the number of structures, containing the inefficiency of their respective run

    Returns
    -------
    hessian : 2D numpy array
        Hessian of F for components 1 ... N (later only components 1 ... N-1 will be used for covariance)

    """

    gi, wfk, wfki = calc_wfk(gi,ni,wki)
    wfkiT = wfki.transpose()

    # General form of the Hessian
    hessian = np.diag(np.sum(Ii_kini*wfkiT/wfk,axis=1)) - np.dot(Ii_kini*wfkiT/wfk, np.transpose(wfkiT/wfk))

    # Simpler form of the Hessian at the optimum (not tested yet!)
    # hessian = np.diag(Ii*ni) - np.dot(Ii_kini*wfkiT/wfk, np.transpose(wfkiT/wfk))

    return hessian

def covariance_windows_free_energy(gi, ni, wki, Ii, Ii_kini, verbose=False):
    """Uncertainty of relative free energies of the windows (i.e., runs with different bias)

    Parameters
    ----------
    gi : 1D numpy array
        vector of relative free energies, with lenght N-1
    ni : 1D numpy array
        vector with lenght equal to the number of biases, containing their lenghts as elements
    wki: 2D numpy array
        matrix (5) in binlessWHAM.pdf containing the potential energy of structure k and bias i
    Ii : 1D numpy array
        vector with length equal to the number of biases, containing their inefficiency factors
        efficiency factor Ii = 1/(1+2*tau_i) with tau_i the correlation time in biased run i
    Ii_kini : 1D numpy array
        vector with length equal to the number of structures, containing the inefficiency of their respective run
    verbose:

    Returns
    -------
    c : 2D numpy array
        covariance of uncertainties of various windows
        c_ij = < delta g_i delta g_j >
    sigma : 2D numpy array
        uncertainties for free-energy differences between the relative weights gi and gj

    """

    # Inverse of the restricted Hessian
    #h = hessian_F(gi,ni,wki)[:-1,:-1]
    h = hessian_F(gi, ni, wki, Ii, Ii_kini)[:-1,:-1] # Here we assume that g_N is the fixed free energy
    if verbose:
        print("Hessian")
        print(h)
    c = np.linalg.inv(h)

    # Uncertainties for differences between different weights
    sigma = np.zeros(c.shape)
    for i in range(sigma.shape[0]):
        for j in range(sigma.shape[1]):
            sigma[i,j] = np.sqrt( c[i,i]-2*c[i,j]+c[j,j] )

    return c, sigma

def grad_p(gi,ni,wki,Ii,Ii_kini):
    """Gradient in free energies gi of probability p

    Parameters
    ----------
    gi : 1D numpy array
        vector of relative free energies, with lenght N-1
    ni : 1D numpy array
        vector with lenght equal to the number of biases, containing their lenghts as elements
    wki: 2D numpy array
        matrix (5) in binlessWHAM.pdf containing the potential energy of structure k and bias i
    Ii : 1D numpy array
        vector with length equal to the number of biases, containing their inefficiency factors
        efficiency factor Ii = 1/(1+2*tau_i) with tau_i the correlation time in biased run i
    Ii_kini : 1D numpy array
        vector with length equal to the number of structures, containing the inefficiency of their respective run

    Returns
    -------
    gp : 1D numpy array
        array containing the gradient in free energies gi of probability p

    """
    gi, wfk, wfki = calc_wfk(gi,ni,wki)
    #gp = -Ii_kini**2 *(wfki/Ii).T/wfk**2
    gp = - np.outer(Ii_kini, Ii).T*(wfki/Ii).T/wfk**2
    return gp

def grad_lnp(gi,ni,wki,Ii):
    """gradient in free energies gi of logarithmic probability p

    Parameters
    ----------
    gi : 1D numpy array
        vector of relative free energies, with lenght N-1
    ni : 1D numpy array
        vector with lenght equal to the number of biases, containing their lenghts as elements
    wki: 2D numpy array
        matrix (5) in binlessWHAM.pdf containing the potential energy of structure k and bias i
    Ii : 1D numpy array
        vector with length equal to the number of biases, containing their inefficiency factors
        efficiency factor Ii = 1/(1+2*tau_i) with tau_i the correlation time in biased run i

    Returns
    -------
    glnp : 1D numpy array
        array containing the gradient in free energies gi of logarithmic probability p

    """

    gi, wfk, wfki = calc_wfk(gi,ni,wki)
    glnp = -wfki.T/wfk

    return glnp

def calc_delta_p(gi,ni,wki,Ii,Ii_kini, calc_lnp=False, verbose=False):
    """Calculates the error in logaritmic probabilities

    Parameters
    ----------
    gi : 1D numpy array
        vector of relative free energies, with lenght N-1
    ni : 1D numpy array
        vector with lenght equal to the number of biases, containing their lenghts as elements
    wki: 2D numpy array
        matrix (5) in binlessWHAM.pdf containing the potential energy of structure k and bias i
    Ii : 1D numpy array
        vector with length equal to the number of biases, containing their inefficiency factors
        efficiency factor Ii = 1/(1+2*tau_i) with tau_i the correlation time in biased run i
    Ii_kini : 1D numpy array
        vector with length equal to the number of structures, containing the inefficiency of their respective run

    Returns
    -------
    delta_lnp : 1D numpy array
        array containing the error of the (logarithmic) probability p

    """
    if calc_lnp:
        # Gradient in free energies gi of logarithmic probability p
        gradient = grad_lnp(gi,ni,wki,Ii)
    else:
        # Default: gradient in free energies gi of probability p
        gradient = grad_p(gi, ni, wki, Ii, Ii_kini)

    # Uncertainty of relative free energies of the windows (i.e., runs with different bias)
    c, sigma = covariance_windows_free_energy(gi, ni, wki, Ii, Ii_kini, verbose=verbose)

    # Variance
    variance = np.zeros(gradient.shape[1])
    for a in range(c.shape[0]):
        for b in range(c.shape[1]):
            variance += (gradient[a]*gradient[b])*c[a,b]

    # End result
    delta_lnp = np.sqrt(variance)

    return delta_lnp

def read_input_from_file(input_NM):
    """Processes information in the input file

    Parameters
    ----------
    input_Nm : string
        path to input file with name of input file

    Returns
    -------
    M : 2D numpy list
        list containing number of bias, windows, bias energy for every structure in every bias and optionally correlation time

    """

    # reads in the input file and saves complete data in array M
    with open(input_NM) as file_NM:
        M = [i.strip().split() for i in file_NM]

    return M

def process_counts_windows(bias_def, tau=None):
    """
    Setup nj, number of points/structures sampled in every window. The counts nj
    can be corrected using estimates for the correlation time in the windows.

    Parameters
    ----------
    n_wins: int
         number of biased simulations to analyze
    ukj: array
         matrix (5) in binlessWHAM.pdf containing the potential energy of structure k and bias j (=i)

    Returns
    -------
    nj : 1D numpy array
        vector with lenght equal to the number of biases, containing their lengths as elements
    Ii : 1D numpy array
        vector with length equal to the number of biases, containing their inefficiency factors
        efficiency factor Ii = 1/(1+2*tau_i) with tau_i the correlation time in biased run i
    Ii_kini : 1D numpy array
        vector with length equal to the number of structures, containing the inefficiency of their respective run

    """

    # bias = first line in input file stating the number of bias used
    #bias = int(M[0][0])
    # correlation time
    #if len(M[0]) == bias + 1:
    #    t = np.array(M[0][1:],dtype=float)
    #else:
    #    t = np.zeros(bias)
    # creates an array nj having containing the number of biased energies

    # !!! OLD CODE !!! CAUTION: The way this is written it only works if every bias hase same number of energies
    #nj = np.array([len(M[1:])/float(M[0][0]) for i in range(bias)])
    #nj = np.array([len(u_kj[:,0])/float(n_wins)]*n_wins)
    # !!! NEW CODE !!! untested, should work with any number of structures per bias

    n_wins, nj = np.unique(bias_def, return_counts=True)
    if np.all(tau) is None:
        t = np.zeros(len(n_wins))
    else:
        t = tau

    # correlation time correction factor
    Ij = 1./(1.+2*t)
    # vector containing the correlation time correction factor of the bias in which target structure is produced.
    Ij_kinj = []
    for j,n in enumerate(nj):
        for nn in range(int(nj[j])):
            Ij_kinj.append(Ij[j])
    Ij_kinj = np.array(Ij_kinj)

    return nj, Ij, Ij_kinj

def run_wham_bfgs_structure_weights(nj, ukj, beta, Ij, Ij_kinj, verbose=False, norm_weights=True,
                                    lbfgs=False, subtract_min_bias=True):
    """
    Run numerical optimization to determine optimal weights of structures using WHAM.

    Parameters:
    -----------
    nj: array
        vector with lenght equal to the number of biases, containing their lengths as elements
    wkj: array
         matrix (5) in binlessWHAM.pdf containing the potential energy of structure k and bias j (=i)
    verbose: Boolean
         print the weights of the biased runs
    norm_weights: Boolean
         normalize the weights of the structures
    Ii : 1D numpy array
        vector with length equal to the number of biases, containing their inefficiency factors
        efficiency factor Ii = 1/(1+2*tau_i) with tau_i the correlation time in biased run i
    Ii_kini : 1D numpy array
        vector with length equal to the number of structures, containing the inefficiency of their respective run

    Returns:
    --------
    struc_weights: array
        weight of each structure
    """

    # Subtract the minimum bias energies to reduce the risk of over-/underflow
    if subtract_min_bias:
        ukjmin = np.amin(ukj, axis=0)
        ukj   -= ukjmin

    # Calculate the exponent of the bias energy
    wkj = np.exp(-beta*ukj)

    # Number of biased simulation runs (e.g. umbrella windows)
    n_wins = len(nj)

    # Initialize weights of biased simulation runs
    gj0 = np.ones(n_wins-1)

    # Weight number of structures per run by inefficiency factor
    nj = nj.astype('float') * Ij

    # Optimize the relative free energies of the windows
    if lbfgs:
        r = fmin_l_bfgs_b(F, gj0, grad_F, args=(nj, wkj, Ij, Ij_kinj), iprint=2)
        g = r[0]
        print(r[1:])
    else:
        g = fmin_bfgs(F, gj0, grad_F, args=(nj, wkj, Ij, Ij_kinj))

    # Non-normalized weights of all structures
    gj, wfk, wfki = calc_wfk(g,nj,wkj)
    struc_weights = Ij_kinj/wfk

    # Uncertainty of the structure weights
    sigma_struc_weights = calc_delta_p(g, nj, wkj, Ij, Ij_kinj, calc_lnp=False, verbose=verbose)

    # Normalization of weights and uncertainties
    if norm_weights:
        z = struc_weights.sum()
        struc_weights /= z
        sigma_struc_weights /= z

    # correct the free energies for the initial subtraction of the minimum bias energies
    if subtract_min_bias:
        gj += + ukjmin - ukjmin[-1]

    if verbose:
        print(gj)

    return struc_weights, sigma_struc_weights, gj

def calculate_pmf_from_structure_weights(p, sigma_p, state_assignment, Ij_kinj):
    """
    Calculate the potential of mean force for the states according to structure weights.

    Parameters:
    -----------
    p: array
         vector with the weights of all structures
    sigma_p: array
         vector with the uncertainties of the weights of all structures
    state_assignment: array
         array that contains the state indices of all structures
    Ii_kini : 1D numpy array
        vector with length equal to the number of structures, containing the inefficiency of their respective run

    Returns:
    --------
    pmf: array
        PMF (potential of mean force) for each state
    sigma_pmf: array
        uncertainty of the PMF for each state
    """

    # Initialize the histogram counter and the uncertainty
    counter  = np.zeros(np.max(state_assignment)+1) # assumes indices going from 0 to N
    sigma_px = np.zeros(np.max(state_assignment)+1)

    # Loop over all structures and add count and uncertainty to their states
    for k,s in enumerate(state_assignment):
        state = s
        counter[state]  += p[k] #* Ij_kinj[k]
        sigma_px[state] += sigma_p[k]

    # Calculate the PMF and its uncertainty from the histogram
    pmf = -np.log(counter)
    pmf -= np.min(pmf)
    sigma_pmf = sigma_px/counter

    return pmf, sigma_pmf

def run_wham_pmf(bias_name_k, ukj, state_assignment, tauj=None, beta=1., verbose=False, return_g=False,
                lbfgs=False):
    """
    Run WHAM with numerical optimization to calculate the potential of mean force for given states

    Parameters:
    -----------
    bias_name_k: array
         index of the bias simulations from structe k orginates
    ukj: array
         matrix (5) in binlessWHAM.pdf containing the potential energy of structure k and bias j (=i)
    state_assignment: array
         array that contains the microstate indices of all structures
    tauj : 1D numpy array
        vector with length equal to the number of biases, with tau_i the correlation time in biased run i
    beta: float
        inverse temperature
    verbose: Boolean
        Set verbosity of output

    Returns:
    --------
    pmf: array
        PMF (potential of mean force) for each state
    sigma_pmf: array
        uncertainty of the PMF for each state
    """

    # Calculate the independent counts/structures observed in each window
    nj, Ij, Ij_kinj = process_counts_windows(bias_name_k, tau=tauj)

    # Calculate the weights of each structure
    p, sigma_p, gj = run_wham_bfgs_structure_weights(nj, ukj, beta, Ij, Ij_kinj, norm_weights=True,
                                                    verbose=verbose, lbfgs=lbfgs)

    # Calculate the PMF from the structure weights
    pmf, sigma_pmf = calculate_pmf_from_structure_weights(p, sigma_p, state_assignment,
                                                          Ij_kinj)

    if return_g:
        return pmf, sigma_pmf, gj
    else:
        return pmf, sigma_pmf

def parse_first_line(fname):
    with open(fname, "r") as f:
        first_line = f.readline()
    first_line = first_line.rstrip('\n').split()
    n_wins = int(first_line[0])
    if len(first_line) > 1:
        tau = first_line[1:]
    else:
        tau = None
    return n_wins, tau

def main():

    input_NM = sys.argv[1]
    beta = 1.

    # First row: number of windows (optionally followed by correlation times of the windows)
    n_wins, tau = parse_first_line(input_NM)

    # Load bias energies (first column gives the bias to which the structure belongs)
    input_all = np.genfromtxt(input_NM, skip_header=1)
    bias_def  = input_all[:,0]
    u_kj      = input_all[:,1:]

    # Process window counts
    nj, Ij, Ij_kinj = process_counts_windows(bias_def, tau=tau)

    # Run WHAM
    p, p_sigma, gj = run_wham_bfgs_structure_weights(nj, u_kj, beta, Ij, Ij_kinj,
                                                          verbose=True, norm_weights=True)

    #final_struc_weights = 1./calc_wfk(gj_final[:-1],nj,wkj,Ij)[1]
    #print final_struc_weights

    np.savetxt(input_NM+"_FreeEnergies.out", gj)
    np.savetxt(input_NM+"_StatisticalWeights.out", p)

if __name__ == "__main__":
   main()


from selenium import webdriver
import requests
from pyquery import PyQuery as pq

#browser = webdriver.Chrome(r'C:\Program Files\chromedriver\chromedriver.exe')
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}
url = 'http://www.data5u.com/free/index.html'

res = requests.get(url=url,headers=headers)
html = res.text
doc = pq(html)
li_list = doc('.wlist li .l2').items()
for li in li_list:
    # print(li)
    # print('============')
    doc1 = pq(li)
    text = doc1('li').text()
    list = text.split(' ')
    ip = list[0]
    port = list[1]
    ip_port = ip + ':' + port
    print(ip_port)


def run_formula(dv,ds, param = None):
    defult_param = {'t1':50}
    if not param:
        param = defult_param

    alpha6 = dv.add_formula('alpha6','roe+%s/pe_ttm'%(param['t1']),
        is_quarterly = True ,add_data = True)

    return alpha6


import re

# import time

from .ninja_to_json import (
    NinjaClientModel,
    NinjaProductModel,
    NinjaInvoicesModel,
    NinjaInvoiceItem as NinjaInvoiceItemModel,
)
from .read_json import read_json
from app.ninja import api as ninja
from app.ninja import NinjaInvoice
from app.ninja.invoice import NinjaInvoiceItem
from app.ninja.client import NinjaClient
from app.models import Reseller, Phone, ResellerProduct, Product
from sqlalchemy import and_

from app.logger import log
from app import db

PHONE_PREFIX = "Phone-"
PATTERN = re.compile(r"^(?P<prod_name>[\w\s-]*)\s(?P<months>[\d]+)\sMonths$")

def get_ninja_clients():
    for json_client in read_json("ninja_clients"):
        client: NinjaClientModel = NinjaClientModel.parse_obj(json_client)
        assert client
        if not client.name:
            continue
        ninja_client = ninja.add_client(client.name)
        ninja_client.is_deleted = client.is_deleted
        reseller: Reseller = Reseller.query.filter(Reseller.name == client.name).first()
        if reseller:
            reseller.ninja_client_id = ninja_client.id
            reseller.save(False)
        else:
            log(
                log.WARNING,
                "[get_ninja_clients] cannot found resseller by name: [%s]",
                client.name,
            )

        if client.contacts:
            if ninja_client.contacts:
                contact_origin = client.contacts[0]
                contact = ninja_client.contacts[0]
                contact.contact_key = contact_origin.contact_key
                contact.email = contact_origin.email
                contact.is_primary = contact_origin.is_primary
                contact.send_email = contact_origin.send_invoice
            else:
                log(log.WARNING, "[get_ninja_clients] not found create contact info")
        else:
            log(log.WARNING, "[get_ninja_clients] cannot create contact info")
        ninja_client.save()

    db.session.commit()

def get_ninja_products():
    for json_prod in read_json("ninja_products"):
        prod: NinjaProductModel = NinjaProductModel.parse_obj(json_prod)
        assert prod.product_key
        ninja_prod = ninja.add_product(
            notes=prod.notes, product_key=prod.product_key, cost=prod.cost
        )
        if prod.is_deleted:
            ninja.delete_product(ninja_prod.id)
        is_phone = prod.product_key.startswith(PHONE_PREFIX)
        if is_phone:
            prefix_len = len(PHONE_PREFIX)
            name = prod.product_key[prefix_len:]
            phone: Phone = Phone.query.filter(Phone.name == name).first()
            if phone:
                phone.ninja_product_id = ninja_prod.id
                phone.save(False)
            else:
                log(log.WARNING, "[get_ninja_products] cannot found phone [%s]", name)
        else:
            reseller_name = prod.notes
            match = PATTERN.match(prod.product_key)
            if not match:
                log(
                    log.WARNING,
                    "[get_ninja_products] wrong product_key [%s]",
                    prod.product_key,
                )
                continue
            prod_name = match.group("prod_name")
            months = int(match.group("months"))

            reseller = Reseller.query.filter(Reseller.name == reseller_name).first()
            if not reseller:
                continue
            db_prod = Product.query.filter(Product.name == prod_name).first()
            if not db_prod:
                continue
            reseller_product: ResellerProduct = ResellerProduct.query.filter(
                and_(
                    ResellerProduct.product_id == db_prod.id,
                    ResellerProduct.reseller_id == reseller.id,
                    ResellerProduct.months == months,
                )
            ).first()
            if not reseller_product:
                continue
            reseller_product.ninja_product_id = ninja_prod.id
            reseller_product.save(False)
    db.session.commit()

def get_ninja_invoices():
    clients: list[NinjaClientModel] = [
        NinjaClientModel.parse_obj(c) for c in read_json("ninja_clients")
    ]

    ninja_clients = ninja.clients

    def find_client_by_id(id: int) -> NinjaClient:
        for c in clients:
            if c.id == id:
                for n_c in ninja_clients:
                    if n_c.name == c.name:
                        return n_c

    for json_invoice in read_json("ninja_invoices"):
        invoice: NinjaInvoicesModel = NinjaInvoicesModel.parse_obj(json_invoice)
        assert invoice
        client = find_client_by_id(invoice.client_id)
        assert client
        ninja_invoice: NinjaInvoice = NinjaInvoice.add(
            client_id=client.id,
            invoice_date=invoice.invoice_date,
            due_date=invoice.due_date,
        )
        ninja_invoice.status_id = invoice.invoice_status_id
        ninja_invoice.amount = invoice.amount
        ninja_invoice.balance = invoice.balance
        ninja_invoice.has_tasks = invoice.has_tasks
        ninja_invoice.has_expenses = invoice.has_expenses
        for item in invoice.invoice_items:
            item: NinjaInvoiceItemModel = item
            assert item
            ninja_invoice.line_items += [
                NinjaInvoiceItem(
                    product_key=item.product_key,
                    notes=item.notes,
                    cost=item.cost,
                    quantity=1,
                    product_cost=item.cost,
                )
            ]
        ninja_invoice.save()


from django import template
from django.utils.html import format_html
from menu.models import Menu

register = template.Library()

@register.simple_tag
def draw_menu(name='head', return_to_main=True, test=False):
    html = ''
    if return_to_main: html = f'
{"" if name == "Главное_меню" else "
Вернуться в главное меню

"}'
    menu_items = Menu.objects.filter(name=name).order_by('parent')
    for item in menu_items:
        if item.children.exists():
            html += f'

{item.name}
'
            html += f'
'
            for i in item.children.all():
                html += draw_menu(name=i.name, return_to_main=False)
        else:
            html += f'
{item.name}
'

        if item.children.exists():
            html += '

'
    if return_to_main: html += '
'
    return format_html(html)


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

import copy
import time
import threading
from pysc2.agents import base_agent
from pysc2.env import sc2_env
from pysc2.lib import actions, features, units
from absl import app
import random

#import scripted_actr_agent as scripted

import logging
import sys

from absl import flags

from pysc2.agents import base_agent
from pysc2.lib import actions

#game setup
FLAGS = flags.FLAGS #for passing arguments
steps = 400 # = 4 Episodes
step_mul = 1 #no frame skipping = realtime

import numpy
import ccm
log = ccm.log()

from pysc2.agents import base_agent
from pysc2.lib import actions
from pysc2.lib import features

from pysc2.env import run_loop
from pysc2.env import sc2_env

_PLAYER_SELF = features.PlayerRelative.SELF
_PLAYER_NEUTRAL = features.PlayerRelative.NEUTRAL  # beacon/minerals
_PLAYER_ENEMY = features.PlayerRelative.ENEMY

FUNCTIONS = actions.FUNCTIONS

from ccm import model
from ccm.lib.actr import *

############### Globals ######################

def _xy_locs(mask):
  """Mask should be a set of bools from comparison with a feature layer."""
  y, x = mask.nonzero()
  return list(zip(x, y))

#********************* ACT-R_CMU Stuff **********************
class GameEnvModel(ccm.Model):
    next_action=ccm.Model(isa='action',press='no_op')
    screen=ccm.Model(isa='screen',event='beacon')

class MotorModule(ccm.Model):
    beacons = 0
    next_action = ''

    def do_action(self,action):
        print(f"do the action: {action}")
        self.parent.parent.next_action = action
        self.parent.parent.screen.event='none'
        time.sleep(0.1)

class ActrAgent(ACTR):
    focus = Buffer()
    motor = MotorModule()
    visual = Buffer()
    vision_module=SOSVision(visual,delay=0)

    retrieve = Buffer()
    memory = Memory(retrieve)

    def init(self):
        print('actr init')
        self.focus.set('find_beacon')

    #def noOp(screen="event:none"):
    def seeBeacon(screen='event:?beacon'):
        print('found the beacon!')
        motor.do_action(beacon)
        self.focus.clear()

    def moveToBeacon(screen='event:?event'):
        motor.do_action(event)
        #print(f'production:{moving}')
        self.focus.clear()

#--------------------------- StarCraft Stuff ---------------------
class BeaconAgent(base_agent.BaseAgent):
  """An agent specifically for solving the MoveToBeacon map."""
  #actr_env =
  def __init__(self):
      super(BeaconAgent, self).__init__()

      self.status = 'none'
      self.target = numpy.zeros(2)
  #def nextAction(actions.FUNCTIONS func):

  def step(self, obs):

    super(BeaconAgent, self).step(obs)

    #self.response = [_NO_OP, []] #default response is to do nothing

    if FUNCTIONS.Move_screen.id in obs.observation.available_actions:

      player_relative = obs.observation.feature_screen.player_relative

      beacon = _xy_locs(player_relative == _PLAYER_NEUTRAL)

      if not beacon:
        actrGameEnv.screen.event = 'beacon'
        return FUNCTIONS.no_op()

      beacon_center = numpy.mean(beacon, axis=0).round()

      if numpy.array_equal(beacon_center,self.target):
          return FUNCTIONS.no_op()
      else:
        self.target = beacon_center
        actrGameEnv.screen.event = 'beacon'
        self.status = 'moving'
        return FUNCTIONS.Move_screen("now", beacon_center)

    else:
      actrGameEnv.screen.event = 'moving'
      return FUNCTIONS.select_army("select")

def sc2_thread(*args):

    FLAGS(args)

    sc2env = sc2_env.SC2Env(
        map_name="MoveToBeacon",
        # players=[sc2_env.Agent(sc2_env.Race.terran),
        #         sc2_env.Bot(sc2_env.Race.random,
        #                     sc2_env.Difficulty.very_easy)],
        players=[sc2_env.Agent(sc2_env.Race.terran)],

        agent_interface_format=features.AgentInterfaceFormat(
            feature_dimensions=features.Dimensions(screen=84, minimap=64),
            use_feature_units=True),
        step_mul=1,
        game_steps_per_episode=0,
        #screen_size_px=(128, 128),
        visualize=True)
        #visualize=False)

    sc2agent.setup(sc2env.observation_spec(), sc2env.action_spec())

    timesteps = sc2env.reset()

    sc2agent.reset()

    #    actrAgent.run()

    while True:
        step_actions = [sc2agent.step(timesteps[0])]
        if timesteps[0].last():
            break
        timesteps = sc2env.step(step_actions)

def actr_thread2(*args): #not currently used

    FLAGS(args)

    env = MatchEnvironment()
    env.model = actr_model
    env.model.goal.set('attend')

    ccm.display(env)

    #actr_agent = ActrAgent()
    #actrEnv = StarCraftEnvironment()
    #actrEnv.agent = actr_agent

    #ccm.log_everything(env)

    env.run()

def actr_thread(*args): #not currently used

    FLAGS(args)

    env = StarCraftEnvironment()
    env.model = actr_agent
    env.model.focus.set('no_op')

    ccm.log(env)

    env.run()

#common_model = SimpleModel()
actrGameEnv = GameEnvModel()

if __name__ == "__main__":
    #app.run(main)

    sc2agent = BeaconAgent()

    actrGameEnv.agent = ActrAgent()

    #actr_agent.focus.set('no_op')
    #sc2agent.actr_setup(deepcopy(actr_agent))

    ccm.log_everything(actrGameEnv)
    #ccm.log(actrGameEnv)

    game_thread = threading.Thread(target=sc2_thread, args=sys.argv)
    game_thread.start()

    #model_thread = Process(target=actr_thread, args=sys.argv)
    model_thread = threading.Thread(target=actrGameEnv.run(), args=sys.argv)
    model_thread.start()

    #time.sleep(25)

    # game_thread = Process(target=sc2_thread, args=sys.argv)


import sys
import os
import wget
import zipfile
import json

feature_encoding = {"C": 0, "C#": 1, "D": 2, "D#": 3, "E": 4, "F": 5, "F#": 6, "G": 7, "G#": 8, "A": 9, "A#": 10, "B": 11, "major": 0, "minor": 1}

def main():
	fdir = "mard"
	fn = fdir + ".zip"
	if not os.path.isfile(fn) and not os.path.isdir(fdir):
		print("Downloading MARD.")
		wget.download("http://mtg.upf.edu/system/files/projectsweb/mard.zip", bar=None)

		with zipfile.ZipFile("mard.zip", "r") as zip_ref:
			zip_ref.extractall("mard")

	metadata = get_imdict("mard/mard/mard_metadata.json")

	features = ["rhythm.bpm", "rhythm.danceability", "lowlevel.average_loudness", "tonal.key_key", "tonal.key_scale"]
	output = build_images_features_dict(metadata, "mard/mard/acousticbrainz_descriptors/", features)

	with open("images_output.json", "w") as output_file:
		json.dump(output, output_file, indent=4)

def get_imdict(filepath):
	with open(filepath, "r") as input_file:
		return {d["amazon-id"]: d["imUrl"] for d in list(filter(lambda x : "imUrl" in x, map(json.loads, input_file.readlines())))}

def build_images_features_dict(metadata, features_path, features):
	output = dict()
	f_files = list(filter(lambda x : x.endswith(".json"), os.listdir(features_path)))
	for f in f_files:
		with open(check_dirpath(features_path) + f, "r") as input_file:
			d = json.load(input_file)
			fv = [get_featurevalue(d[c][f]) for c, f in (feature.split(".") for feature in features)]

			amazon_id, mbid = os.path.splitext(f)[0].split("_")
			if amazon_id in metadata:
				output[amazon_id] = {"image": metadata[amazon_id], "features": fv}
			else:
				continue

	return output

def check_dirpath(dirpath):
	return dirpath if dirpath.endswith("/") else dirpath + "/"

def get_featurevalue(f):
	if type(f) is str:
		return feature_encoding[f]
	else:
		return f

if __name__ == "__main__":
	main()


#CREATED MAINpy FILE
#import files

from logo import logo,vs
import random
import os
from g_data import data
import time
from g_data import data
#print logo

print("WELCOME\n",logo)
time.sleep(3)
incorrect = "you are incorrect\nscore: "
correct = "you are correct\nscore:"
result = ''

def show(result):
    score=0
    second_acc = random.choice(data)
    while result != incorrect:

        first_acc = second_acc
        second_acc = random.choice(data)

        print('A: ', first_acc['name'], ', country: ', first_acc['country'], ', Description: ',
              first_acc['description'])
        print(vs)
        print('B:', second_acc['name'], ', country: ', second_acc['country'], ', Description: ',
              second_acc['description'])
        answer = input("Who has more Follower??? A or B:::   ")

        os.system('cls')
        print("\n",logo)
        if answer == 'A' or answer == 'a':
            if first_acc['follower_count'] > second_acc['follower_count']:
                score+=1
                result=correct
                print(result,score)

                continue
            else:
                result=incorrect
                print(result,score)
        elif answer=='B' or answer=='b':
            if first_acc['follower_count'] < second_acc['follower_count']:
                score += 1
                result=correct
                print(result,score)

                continue
            else:
                result=incorrect
                print(result,score)
        else:
            print("invalid input")
            answer=input("Who has more Follower??? A or B:::   ")
        print(f"game over \n score= (score)")

show(result)


import dash
from dash import html, dcc
from pip import main
import plotly.express as px
from dash.dependencies import Input, Output, State
import pandas as pd

#Dash app com multiplos inputs
css_externo = ['https://codepen.io/chriddyp/pen/bWLwP.css']

app = dash.Dash(__name__, external_stylesheets=css_externo)

df = pd.read_csv('https://plotly.github.io/datasets/country_indicators.csv')

indicators = df['Indicator Name'].unique()

app.layout = html.Div([
    html.Div([
        html.Div([
            dcc.Dropdown(
                id='xaxes-column',
                options=[{'label': i, 'value': i} for i in indicators],
                value='Fertility rate, total (births per woman)'
            ),
            dcc.RadioItems(
                id='xaxes-type',
                options=[{'label': i, 'value': i} for i in ['Linear', 'Log']],
                value='Linear',
                labelStyle={'display': 'inline-block'}
            )
        ],
        style={'widht': '40%', 'display': 'inline-block'}),

        html.Div([
            dcc.Dropdown(
                id='yaxes-column',
                options=[{'label': i, 'value': i} for i in indicators],
                value='Life expectancy at birth, total (years)'
            ),
            dcc.RadioItems(
                id='yaxes-type',
                options=[{'label': i, 'value': i} for i in ['Linear', 'Log']],
                value='Linear',
                labelStyle={'display': 'inline-block'}
            )
        ],
        style={'widht': '40%', 'float':'right', 'display': 'inline-block'})
        ]),

        dcc. Graph(id='indicator-graphic'),

        dcc.Slider(
            id='year--slider',
            min=df['Year'].min(),
            max=df['Year'].max(),
            value=df['Year'].max(),
            marks={str(year): str(year) for year in df['Year'].unique()},
            step=None
        )
])

@app.callback(
    Output('indicator-graphic', 'figure'),
    [Input('xaxes-column', 'value'),
     Input('yaxes-column', 'value'),
     Input('xaxes-type', 'value'),
     Input('yaxes-type', 'value'),
     Input('year--slider', 'value')])
def update_graph(xaxes_column_name, yaxes_column_name, xaxes_type, yaxes_type, year_value):
    nova_df=df[df['Year']==year_value]

    fig = px.scatter(x=nova_df[nova_df['Indicator Name'] == xaxes_column_name]['Value'],
                     y=nova_df[nova_df['Indicator Name'] == yaxes_column_name]['Value'],
                     hover_name=nova_df[nova_df['Indicator Name'] == yaxes_column_name]['Country Name'])

    fig.update_layout(margin={'l':40, 'b': 40, 't':10, 'r':0}, hovermode='closest')

    fig.update_xaxes(title=xaxes_column_name,
                     type='linear' if xaxes_type == 'Linear' else 'log')

    fig.update_yaxes(title=yaxes_column_name,
                     type='linear' if yaxes_type == 'Linear' else 'log')

    return fig

if __name__ == '__main__':
    app.run_server(debug=True)


from bisect import bisect, bisect_left

class Solution:
    def medianSlidingWindow(self, nums, k):
        window = sorted(nums[0:k])
        medians = []
        i = 0
        while i + k <= len(nums):
            # get median
            if k % 2 == 0:
                medians.append((window[k//2] + window[k//2+1]) / 2)
            else:
                medians.append(window[k // 2])
            # make a step
            zero_idx = bisect_left(window, nums[i])
            window.pop(zero_idx)
            i += 1
            if i + k > len(nums):
                break
            insert_idx = bisect(window, nums[i+k-1])
            window.insert(insert_idx, nums[i+k-1])

        return medians

if __name__ == "__main__":
    sol = Solution()
    nums = [1, 3, -1, -3, 5, 3, 6, 7]
    k = 3
    print(sol.medianSlidingWindow(nums, k))