import numpy as np
from torch.utils.data import Dataset
from torch.utils.data import DataLoader

class WineDataset(Dataset):
    def __init__(self, data:np.ndarray):
        self.data = data

    def __len__(self):
        return self.data.shape[0]

    def __getitem__(self, index):
        x = self.data[index][:-1]
        y = self.data[index][-1]
        return x, y

if __name__ == "__main__":
    ### Step 1. Initialize the Dataset
    csv_path = "/data/home/liuhanyu/hyliu/code/Deep_Learning_Notes/1.Basic/code/wine_quality/winequality-red.csv"
    data_array = np.loadtxt(
                        fname=csv_path,
                        delimiter=";",
                        skiprows=1,
                        )
    wine_dataset = WineDataset(data=data_array)
    x, y = wine_dataset[0]

    ### Step 2. Initialize the DataLoader
    dataloader = DataLoader(
                    dataset=wine_dataset,
                    batch_size=16,
                    shuffle=True,
                    )
    for idx_batch, (x, y) in enumerate(dataloader, 1):
        print("Batch {0:<10}, Batch Size {1:<10}".format(
                                                idx_batch,
                                                x.size()[0])
              )


with open('triangles', 'rt') as f:
    lines = [line.strip().split() for line in f]
    data = [[int(x) for x in line] for line in lines if line]

count = 0

for i in range(0, len(data), 3):
    triangles = data[i:i + 3]
    for j in range(3):
        x, y, z = tuple(sorted([t[j] for t in triangles]))
        if x + y > z:
            count += 1

print(count)


from collections import OrderedDict
import glob
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
plt.style.use('apj')
import h5py

from scipy.interpolate import interp1d
import pandas as pd

dirs_p1 = ["erf_AE_cut/erf_step_3D_Re4e2_P1e0_zeta1e-3_S1e3_Lz2_Lcz1_Pr0.5_a2_Titer0_64x64x256_schwarzschild/",
           "erf_AE_cut/erf_step_3D_Re4e2_P1e0_zeta1e-3_S1e3_Lz2_Lcz1_Pr0.5_a2_Titer0_64x64x256_schwarzschild_restart/"]

dirs_p1_down = ['noslip_erf_P_cut/erf_step_3D_Re4e2_P1e0_zeta1e-3_S1e3_Lz2_Lcz1_Pr0.5_a2_Titer100_64x64x256_predictive0/']
dirs_p1_up   = ['erf_AE_cut/erf_step_3D_Re4e2_P1e0_zeta1e-3_S1e3_Lz2_Lcz1_Pr0.5_a2_Titer100_64x64x256_predictive0.3']

dirs_p2 = ["erf_AE_cut/erf_step_3D_Re4e2_P2e0_zeta1e-3_S1e3_Lz2_Lcz1_Pr0.5_a2_Titer0_64x64x256_schwarzschild/",
           "erf_AE_cut/erf_step_3D_Re4e2_P2e0_zeta1e-3_S1e3_Lz2_Lcz1_Pr0.5_a2_Titer0_64x64x256_schwarzschild_restart/",
           "erf_AE_cut/erf_step_3D_Re4e2_P2e0_zeta1e-3_S1e3_Lz2_Lcz1_Pr0.5_a2_Titer0_64x64x256_schwarzschild_restart2/",
           "erf_AE_cut/erf_step_3D_Re4e2_P2e0_zeta1e-3_S1e3_Lz2_Lcz1_Pr0.5_a2_Titer0_64x64x256_schwarzschild_restart3/"]

dirs_p2_down = ['noslip_erf_P_cut/not_in_use/erf_step_3D_Re4e2_P2e0_zeta1e-3_S1e3_Lz2_Lcz1_Pr0.5_a2_Titer100_64x64x256_predictive0.1/']
dirs_p2_up   = ['erf_AE_cut/erf_step_3D_Re4e2_P2e0_zeta1e-3_S1e3_Lz2_Lcz1_Pr0.5_a2_Titer100_64x64x256_predictive0.45']

dirs_p4 = ["erf_AE_cut/erf_step_3D_Re4e2_P4e0_zeta1e-3_S1e3_Lz2_Lcz1_Pr0.5_a2_Titer0_64x64x256_schwarzschild/",
        "erf_AE_cut/erf_step_3D_Re4e2_P4e0_zeta1e-3_S1e3_Lz2_Lcz1_Pr0.5_a2_Titer0_64x64x256_schwarzschild_restart/",
        "erf_AE_cut/erf_step_3D_Re4e2_P4e0_zeta1e-3_S1e3_Lz2_Lcz1_Pr0.5_a2_Titer0_64x64x256_schwarzschild_restart2/",
        "erf_AE_cut/erf_step_3D_Re4e2_P4e0_zeta1e-3_S1e3_Lz2_Lcz1_Pr0.5_a2_Titer0_64x64x256_schwarzschild_restart3/",
        "erf_AE_cut/erf_step_3D_Re4e2_P4e0_zeta1e-3_S1e3_Lz2_Lcz1_Pr0.5_a2_Titer0_64x64x256_schwarzschild_restart4/",
        "erf_AE_cut/erf_step_3D_Re4e2_P4e0_zeta1e-3_S1e3_Lz2_Lcz1_Pr0.5_a2_Titer0_64x64x256_schwarzschild_restart5/",
        "erf_AE_cut/erf_step_3D_Re4e2_P4e0_zeta1e-3_S1e3_Lz2_Lcz1_Pr0.5_a2_Titer0_64x64x256_schwarzschild_restart6/"]

dirs_p4_down = ['noslip_erf_P_cut/not_in_use/erf_step_3D_Re4e2_P4e0_zeta1e-3_S1e3_Lz2_Lcz1_Pr0.5_a2_Titer100_64x64x256_predictive0.4/']
dirs_p4_up   = ['erf_AE_cut/erf_step_3D_Re4e2_P4e0_zeta1e-3_S1e3_Lz2_Lcz1_Pr0.5_a2_Titer100_64x64x256_predictive0.7']

name_dirs_p1      = 'erf_re4e2_p1e0_s1e3_longevolution'
name_dirs_p1_down = 'erf_re4e2_p1e0_s1e3_pertDown'
name_dirs_p1_up   = 'erf_re4e2_p1e0_s1e3_pertUp'
name_dirs_p2      = 'erf_re4e2_p2e0_s1e3_longevolution'
name_dirs_p2_down = 'erf_re4e2_p2e0_s1e3_pertDown'
name_dirs_p2_up   = 'erf_re4e2_p2e0_s1e3_pertUp'
name_dirs_p4      = 'erf_re4e2_p4e0_s1e3_longevolution'
name_dirs_p4_down = 'erf_re4e2_p4e0_s1e3_pertDown'
name_dirs_p4_up   = 'erf_re4e2_p4e0_s1e3_pertUp'

dir_lists = [   dirs_p1,
                dirs_p1_down,
                dirs_p1_up,
                dirs_p2,
                dirs_p2_down,
                dirs_p2_up,
                dirs_p4,
                dirs_p4_down,
                dirs_p4_up ]

name_lists = [  name_dirs_p1,
                name_dirs_p1_down,
                name_dirs_p1_up,
                name_dirs_p2,
                name_dirs_p2_down,
                name_dirs_p2_up,
                name_dirs_p4,
                name_dirs_p4_down,
                name_dirs_p4_up ]

for dirs, this_trace_name in zip(dir_lists, name_lists):
    #Parse input parmeters
    data = OrderedDict()
    S = float(dirs[0].split('_S')[-1].split('_')[0])
    P = float(dirs[0].split('_Pr')[0].split('_P')[-1].split('_')[0])
    Re = float(dirs[0].split('_Re')[-1].split('_')[0])
    Lz = float(dirs[0].split('_Lz')[-1].split('_')[0])
    threeD = True
    erf = True

    k_rz = 0.2 / (S * P)
    t_diff = 1/k_rz

    #Read in scalar and profile data
    times = []
    L_d01s = []
    L_d05s = []
    L_d09s = []
    theory_f = []
    theory_xi = []
    grad = []
    prof_times = []
    for i, d in enumerate(dirs):
        if i == 0 and 'longevolution' in d:
            skip_points = 100
        else:
            skip_points = 0
        with h5py.File('{:s}/data_top_cz.h5'.format(d), 'r') as f:
            dictionary = dict()
            for k in ['times', 'L_d01s', 'L_d05s', 'L_d09s']:
                dictionary[k] = f[k][()]
                if k != 'times':
                    dictionary[k] = dictionary[k][np.unique(dictionary['times'], return_index=True)[1]]
            try:
                for k in ['modern_f', 'modern_xi']:
                    dictionary[k] = f[k][()]
                    dictionary[k] = dictionary[k][np.unique(dictionary['times'], return_index=True)[1]]

            except:
                #some older files don't have modern_f/modern_xi
                Ls = f['Ls'][()]
                L_d09s_tmp = f['L_d09s'][()]
                enstrophy_Ls = f['enstrophy_Ls'][()]
                enstrophy_cz = f['enstrophy_cz'][()]
                fconv_Ls = f['fconv_Ls'][()]

                L_pz = L_d09s_tmp - Ls
                dissipation_cz   = enstrophy_cz/Re
                dissipation_Ls   = enstrophy_Ls/Re
                dissipation_pz   = (dissipation_cz * L_d09s_tmp - dissipation_Ls * Ls) / L_pz

                modern_f         = dissipation_Ls/fconv_Ls
                modern_xi        = ( (dissipation_pz*L_pz) / (fconv_Ls*Ls) ) / (modern_f * (L_pz/Ls))
                dictionary['modern_f'] = modern_f
                dictionary['modern_xi'] = modern_xi
                for k in ['modern_f', 'modern_xi']:
                    dictionary[k] = dictionary[k][np.unique(dictionary['times'], return_index=True)[1]]

            dictionary['times'] = np.unique(dictionary['times'])
            if i > 0:
                #clean out some time artifacts from restarting simulations
                skip_points = int(np.sum(dictionary['times'] <= times[-1][-1]))

            times.append(dictionary['times'][skip_points:])
            L_d01s.append(dictionary['L_d01s'][skip_points:])
            L_d05s.append(dictionary['L_d05s'][skip_points:])
            L_d09s.append(dictionary['L_d09s'][skip_points:])
            theory_f.append(dictionary['modern_f'][skip_points:])
            theory_xi.append(dictionary['modern_xi'][skip_points:])
            Ls = f['Ls'][()]
        with h5py.File('{:s}/avg_profs/averaged_avg_profs.h5'.format(d), 'r') as f:
            z = f['z'][()]
            grad_ad = -f['T_ad_z'][()][0,:].squeeze()
            grad_rad = -f['T_rad_z'][()][0,:].squeeze()

            grad.append(-f['T_z'][()])
            prof_times.append(f['T_z_times'][()])

    times          = np.array(np.concatenate(times))
    L_d01s         = np.array(np.concatenate(L_d01s))
    L_d05s         = np.array(np.concatenate(L_d05s))
    L_d09s         = np.array(np.concatenate(L_d09s))
    theory_f       = np.array(np.concatenate(theory_f))
    theory_xi      = np.array(np.concatenate(theory_xi))

    grad           = np.array(np.concatenate(grad, axis=0))
    prof_times     = np.array(np.concatenate(prof_times))

    with h5py.File('temporal_data/{}.h5'.format(this_trace_name), 'w') as f:
        f['scalars/Ls']  = Ls
        f['scalars/d01'] = L_d01s - Ls
        f['scalars/d05'] = L_d05s - Ls
        f['scalars/d09'] = L_d09s - Ls
        f['scalars/times'] = times
        f['scalars/f']     = theory_f
        f['scalars/xi']    = theory_xi
        f['profiles/z']     = z
        f['profiles/grad']  = grad
        f['profiles/times'] = prof_times
        f['profiles/grad_ad'] = grad_ad
        f['profiles/grad_rad'] = grad_rad


from turtle import Turtle
import pandas

FONT = ('Arial', 18, 'normal')
MOVE = False
ALIGNMENT = "center"

class StateWriter(Turtle):
  def __init__(self, state_name):
    super().__init__()
    self.speed("fastest")
    self.hideturtle()
    self.color("black")
    self.penup()
    self.csv_data = pandas.read_csv("50_states.csv")
    self.state_row = self.csv_data[self.csv_data.state == state_name]
    self.state_name = state_name
    self.x_cor = int(self.state_row.x)
    self.y_cor = int(self.state_row.y)
    self.goto(self.x_cor, self.y_cor)
    self.pendown()
    self.write_state()

  def write_state(self):
    self.write(self.state_name, move=MOVE, align=ALIGNMENT, font=FONT)


# -*- coding: utf-8 -*-
"""
Created on Fri Jan  7 14:22:09 2023

@author: fedig
"""
'''
import pandas as pd
pd.options.mode.chained_assignment = None  # default='warn'

#members = pd.read_excel("excelFileName.xlsx")
members = pd.read_excel("Volunteer List by OU .xlsx")

all_positions = ["Chair", "Counselor", "Secretary", "Treasurer", "Vice Chair", "Webmaster"]

grouped = members.groupby("OU Name")["Position"].agg(list).reset_index()

def find_missing_positions(positions):
    return [pos for pos in all_positions if pos not in positions]

grouped["Missing Positions"] = grouped["Position"].apply(find_missing_positions)

grouped.to_excel("SBs Missing Volunteers.xlsx")
'''
import pandas as pd
pd.options.mode.chained_assignment = None  # default='warn'

# Read the Excel file
members = pd.read_excel("Volunteer List by OU.xlsx")

all_positions = ["Chair", "Advisor", "Secretary", "Treasurer", "Vice Chair", "Webmaster"]

# Group by OU Name and aggregate email addresses into a comma-separated string
grouped = members.groupby("OU Name").agg({
    "Position": list,
    "Email Address  ": lambda x: ','.join(x) if not x.empty else ''
}).reset_index()

# Define a function to find missing positions
def find_missing_positions(positions):
    return [pos for pos in all_positions if pos not in positions]

# Apply the function to create a new column for missing positions
grouped["Missing Positions"] = grouped["Position"].apply(find_missing_positions)

# Save the result to an Excel file
grouped.to_excel("SBCs Missing Volunteers.xlsx", index=False)


import os
import glob
import argparse

from PIL import Image
from skimage import io
import numpy as np
from tqdm import tqdm

WORK_DIR = './workspace/U-2-Net'

def parse_args():
    parser = argparse.ArgumentParser(
        description='Postprocess for U-2-Net'
    )
    parser.add_argument('--image_dir', type=str, default='./datasets/ECSSD/images',
                        help='input dataset image dir')
    parser.add_argument('--save_dir', type=str, default='./test_vis_ECSSD')
    parser.add_argument('--out_dir', type=str, default='./result/dumpOutput_device0')
    global_args = parser.parse_args()
    return global_args

def save_output(image_name, predict_np, d_dir):
    im = Image.fromarray(predict_np * 255).convert('RGB')
    img_name = image_name.split(os.sep)[-1]
    image = io.imread(image_name)
    imo = im.resize((image.shape[1], image.shape[0]), resample=Image.BILINEAR)

    aaa = img_name.split(".")
    bbb = aaa[0:-1]
    imidx = bbb[0]
    for i in range(1, len(bbb)):
        imidx = imidx + "." + bbb[i]

    save_output_result = os.path.join(d_dir, imidx + '.png')
    imo.save(save_output_result)

def normPRED(d):
    ma = np.max(d)
    mi = np.min(d)
    dn = (d - mi) / (ma - mi)
    return dn

def postprocess(ori_image_list, bin_dir, num, save_dir):
    for idx in tqdm(range(num)):
        bin_path = os.path.join(bin_dir, '{}_0.bin'.format(idx))
        bin_data = np.fromfile(bin_path, dtype=np.float32).reshape([320, 320])
        bin_data = normPRED(bin_data)
        image_path = ori_image_list[idx]
        save_output(image_path, bin_data, save_dir)

if __name__ == '__main__':
    args = parse_args()
    out_dir = args.out_dir
    save_dir_path = args.save_dir
    image_dir = args.image_dir
    bin_files = os.listdir(out_dir)
    os.makedirs(save_dir_path, exist_ok=True)
    img_name_list = glob.glob(image_dir + os.sep + '*')
    img_name_list.sort()
    postprocess(img_name_list, out_dir, len(bin_files), save_dir_path)


import operator
import re

from ..lib.misc import file_scan, hash_files, random_string
from functools import reduce
from itertools import chain

from pyramid.view import view_config
from pyramid.renderers import render_to_response

import logging
log = logging.getLogger(__name__)

random_revision = random_string()

@view_config(route_name='cache_manifest')
def cache_manifest(request):
    log.debug('cache.manifest')
    request.response.cache_expires(request.registry.settings.get('template.offline.cache_expires'))
    if request.registry.settings['template.offline.enabled']:
        mounts = request.registry.settings['mounts']
        files = sorted(chain(request.root.paths,*map(operator.attrgetter('mounted'), mounts)))
        files.remove('/offline')
        cache = dict(
            revision = "".join(map(operator.attrgetter('hash'), mounts)),
            cache = files,
        )
    else:
        cache = dict(
            revision = random_revision,
            network = '*',
        )
    return render_to_response('_cache.manifest.mako', dict(cache=cache), request=request)


import pandas as pd
import re #清楚数字标点的标准库
from textblob import TextBlob
import  emotion
from nltk.corpus import stopwords  # 下载之后 载入字典
from nltk.stem.porter import PorterStemmer  # stem：词根 PorterStemmer： 词根函数库

positive, negative = emotion.get_emotion()
positive = tuple(positive)
negative = tuple(negative)

table = "microwave"

# dataset = pd.read_csv('data/hair_dryer.tsv', delimiter = '\t', quoting = 3, encoding='utf-8')
# dataset = pd.read_csv('data/pacifier.tsv', delimiter = '\t', quoting = 3, encoding='utf-8')

dataset = pd.read_csv('data/microwave.tsv', delimiter = '\t', quoting = 3, encoding='utf-8')

def get_scores():

    corpus = []  # 空list
    lens = len(dataset)

    listc = []
    mp = dict()
    k = 0
    sum = 0
    scorce = []
    sum_count = 0
    for i in range(0, lens):
        try:
            # if dataset['star_rating'][i] != 5:
            #     continue
            review = re.sub('[^a-zA-Z]', ' ', dataset['review_headline'][i] + dataset['review_body'][i])  # 去除标点，数字，去除之后用空格代替，只留下大小写字母
            review = review.lower()  # 全部转换成小写
            review = review.split()  # 将句子字符串，转换成含有不同单词的list
            ps = PorterStemmer()  # 取词根化的方程
            review = [ps.stem(word) for word in review if not word in set(stopwords.words('english'))]  # 用词根化后的结果进行循环
            # set让速度变得更快。 最后查看是否在英文的虚词字典里 ‘english’
            # 代码运行到这里 举栗子： 原来第一行review便转化成了 ['wow','love','place']

            for item in review:
                if item not in positive and item not in negative:
                    continue
                if item not in mp:
                    mp[item] = 1
                else:
                    mp[item] += 1
            review = ' '.join(review)  # 在每两个单词之间加上空格，并重现转化成字符串

            # 情感分析
            blob = TextBlob(review)
            # ans = -1
            temp_sum = 0
            temp_c = 0
            lens2 = len(blob.sentences)
            if(len != 0):
                for item in blob.sentences:
                    # print(item.sentiment)
                    # print(item.sentiment.polarity)
                    temp_sum += item.sentiment.polarity
                    temp_c += item.sentiment.subjectivity
            if temp_sum != 0:
                temp_list = []
                temp_list.append(temp_sum / lens2)
                temp_list.append(temp_c / lens2)
                scorce.append(temp_list)
            else:
                scorce.append([-2, 0.75])
            # print(temp_sum)
            if lens2 != 0:
                sum += temp_sum / lens2

            corpus.append(review)  # 每处理一行，变加入list
            listc.append(dataset.iloc[i, 7])
        except Exception as e:
            k += 1
            scorce.append([-2, 0.75])
            print(e)
            continue
        else:
            sum_count += 1
            if (i % 500 == 0):
                print(i)

    ave = sum / lens
    print(ave, len(scorce), lens)

    with open("data/评论得分%s.csv" % table, "w+") as f:
        for item in scorce:
            # print(item)
            if item[0] != -2:
                f.write(str(item[0]) + ',' + str(item[1]) + '\n')
            else:
                f.write(str(ave) + ',0.75\n')
                item[0] = ave
                item[1] = 0.75

    with open("data/词频统计%s.csv" % table, "w+") as f:
    # 输出频率最高的情感单词
        mp = sorted(mp.items(), key=lambda d: d[1], reverse=True)
        for item in mp:
            print(item, end='\n')
            # print(mp[item])
            f.write(str(item)+',' +'\n')
    return scorce, dataset, table


import logging
import functools

import torch
import torch.nn.functional as F
from torch.nn.modules.loss import _Loss

import network.utils as utils
import network.models as models

logger = logging.getLogger()

def get_loss_act(activation):
    if activation == 'tanh':
        act = utils.nn_tanh_phi_fn_dir
        k_min, k_max = -1., 1.
    elif activation == 'sigmoid':
        act = utils.nn_sigmoid_phi_fn_dir
        k_min, k_max = 0., 1.
    elif activation == 'relu':
        act = utils.nn_relu_phi_fn_dir
        k_min, k_max = 0., 1.
    else:
        raise NotImplementedError()
    return act, k_min, k_max

def get_k_mtrx(input1, input2, activation):
    act, _, _ = get_loss_act(activation)
    if (len(input1.shape) > 2 or len(input2.shape) > 2):
        input1 = F.avg_pool2d(input1, 4)
        input1 = input1.view(input1.size(0), -1)
        input2 = F.avg_pool2d(input2, 4)
        input2 = input2.view(input2.size(0), -1)
    return act(input1).mm(act(input2).t())

def get_ideal_k_mtrx(target1, target2, activation, n_classes):
    """
    Returns the "ideal" kernel matrix G* defined as
        (G*)_{ij} = k_min if y_i == y_j;
        (G*)_{ij} = k_max if y_i != y_j.

    Args:
        target1 (tensor): Categorical labels with values in
        {0, 1, ..., n_classes-1}.
        target2 (tensor): Categorical labels with values in
        {0, 1, ..., n_classes-1}.
        n_classes (int)

    Shape:
        - Input:
        target1: (n_examples1, 1) or (1,) (singleton set)
        target2: (n_examples2, 1) or (1,) (singleton set)
        - Output: (n_examples1, n_examples2)
    """
    _, k_min, k_max = get_loss_act(activation)

    if n_classes < 2:
        raise ValueError('You need at least 2 classes')

    if len(target1.size()) == 1:
        target1.unsqueeze_(1)
    elif len(target1.size()) > 2:
        raise ValueError('target1 has too many dimensions')
    if len(target2.size()) == 1:
        target2.unsqueeze_(1)
    elif len(target2.size()) > 2:
        raise ValueError('target2 has too many dimensions')

    if torch.max(target1) + 1 > n_classes:
        raise ValueError('target1 has at least one invalid entry')
    if torch.max(target2) + 1 > n_classes:
        raise ValueError('target2 has at least one invalid entry')

    target1_onehot, target2_onehot = \
        utils.one_hot_encode(target1, n_classes).to(torch.float), \
        utils.one_hot_encode(target2, n_classes).to(torch.float)

    ideal = target1_onehot.mm(target2_onehot.t())

    if k_min != 0:
        min_mask = torch.full_like(ideal, k_min)
        ideal = torch.where(ideal == 0, min_mask, ideal)
    if k_max != 1:
        max_mask = torch.full_like(ideal, k_max)
        ideal = torch.where(ideal == 1, max_mask, ideal)

    return ideal

class SRSLoss(_Loss):
    """
    The Supervised Representation Similarity (SRS) loss defined as
      (input, target)
        -> loss(map_target(target), map_input(input)).
    """

    def __init__(self, map_input, map_target, loss):
        """
        Args:
          map_input: A function (executable) that evaluates on every pair of examples
          in input.

          map_target: A function (executable) that evaluates on target.

          loss: A bivariate loss function (executable) for the outputs from map_input and
            map_target. Specify 'reduction' when instantiating this object and passing the instance to
            SRSLoss will make SRSLoss inherit the specified reduction behavior.
        """
        super(SRSLoss, self).__init__()
        self.map_input = map_input
        self.map_target = map_target
        self.loss = loss

    def forward(self, input, target):
        """
        Args:
          input (tensor): The batch of representations to compare. Shape: (N, d1, d2, ...).
          target (tensor): The target of the batch. Shape: (N, p1, p2, ...).
        """
        res_input = self.map_input(input)
        res_target = self.map_target(target)
        return self.loss(
            res_input.view([-1] + list(res_input.size())[2:]),
            res_target.view([-1] + list(res_target.size())[2:])
        )

# some reference SRS instantiations are given below, all of which are to be maximized
# in all instantiations, pairs of the form (x, x) are not considered

def _make_fn(map_input, map_target, loss):
    """
    A helper method that abstracts some boilerplate code
    """
    return SRSLoss(
        map_input=map_input,
        map_target=map_target,
        loss=loss
    )

def _srs_raw(activation, n_classes, neo):
    """
    In the regular version, the returned loss function computes sum of all kernel
    values from positive pairs minus that of all kernel values from negative pairs
    divided by the total number of pairs.

    In the negative only version, the returned loss function computes -1 times
    the sum of all kernel values from negative pairs divided by the total number
    of negative pairs.

    Args:
      phi: A Phi object.
      n_classes (int): The number of classes in the dataset.
      neo (bool): Whether to use the NEgative Only version, in which only
        the negative pairs are considered.

    Returns an SRS loss function.
    """

    def map_input(x): return torch.where(
        torch.eye(len(x)).to(x.device) == 1,
        torch.tensor(0.).to(x.device),
        get_k_mtrx(x, x, activation=activation)
    )  # removes the main diagonal
    def map_target(x): return get_ideal_k_mtrx(x, x, activation=activation, n_classes=n_classes)

    def loss_fn(input, target):
        _, k_min, k_max = get_loss_act(activation)
        if neo:
            mask = torch.where(
                target == k_min,
                torch.tensor(-1., device=input.device),
                torch.tensor(0., device=input.device)
            )
            return torch.sum(input * mask) / (torch.sum(torch.abs(mask)))
        else:
            mask = torch.where(
                target == k_max,
                torch.tensor(1., device=input.device),
                torch.tensor(-1., device=input.device)
            )
            # removes the main diagonal
            return torch.sum(input * mask) / (torch.sum(torch.abs(mask)) - len(input)**.5)

    return _make_fn(
        map_input=map_input,
        map_target=map_target,
        loss=loss_fn,
    )

def _srs_nmse(activation, n_classes, neo):
    """
    Negative MSE between the actual kernel mtrx and the perfect one.
    """

    def map_input(x): return get_k_mtrx(x, x, activation=activation)
    def map_target(x): return get_ideal_k_mtrx(x, x, activation=activation, n_classes=n_classes)
    _loss_fn = torch.nn.MSELoss(reduction='mean')

    if neo:
        _, k_min, _ = get_loss_act(activation)
        @utils.mask_loss_fn(k_min)
        def loss_fn(input, target):
            return -_loss_fn(input, target)
    else:
        def loss_fn(input, target):
            return -_loss_fn(input, target)

    return _make_fn(
        map_input=map_input,
        map_target=map_target,
        loss=loss_fn,
    )

def _srs_alignment(activation, n_classes, neo):
    """
    Cosine similarity between the actual kernel mtrx and the perfect one.
    """

    def map_input(x): return get_k_mtrx(x, x, activation=activation)
    def map_target(x): return get_ideal_k_mtrx(x, x, activation=activation, n_classes=n_classes)
    _loss_fn = torch.nn.CosineSimilarity(dim=0)

    if neo:
        _, k_min, _ = get_loss_act(activation)
        if k_min == 0:
            raise ValueError(
                'srs_alignment_neo is not defined for the given phi.')

        @utils.mask_loss_fn(k_min)
        def loss_fn(input, target):
            return _loss_fn(input, target)
    else:
        loss_fn = _loss_fn

    return _make_fn(
        map_input=map_input,
        map_target=map_target,
        loss=loss_fn,
    )

def _srs_upper_tri_alignment(activation, n_classes, neo):
    """
    Cosine similarity between the actual kernel mtrx and the
    perfect one but only considering the upper triangle minus
    the main diagonal.
    """
    def map_input(x): return utils.upper_tri(get_k_mtrx(x, x, activation=activation))
    def map_target(x): return utils.upper_tri(
        get_ideal_k_mtrx(x, x, activation=activation, n_classes=n_classes))

    _loss_fn = torch.nn.CosineSimilarity(dim=0)

    if neo:
        _, k_min, _ = get_loss_act(activation)
        if k_min == 0:
            raise ValueError(
                'srs_upper_tri_alignment_neo is not defined for the given phi.')

        @utils.mask_loss_fn(k_min)
        def loss_fn(input, target):
            return _loss_fn(input, target)
    else:
        loss_fn = _loss_fn

    return _make_fn(
        map_input=map_input,
        map_target=map_target,
        loss=loss_fn,
    )

def _srs_contrastive(activation, n_classes, neo):
    """
    A contrastive-loss-like instantiation.
    """

    def map_input(x): return torch.where(
        torch.eye(len(x)).to(x.device) == 1,
        torch.tensor(-utils.INF).to(x.device),
        get_k_mtrx(x, x, activation=activation)
    )  # removes the main diagonal
    def map_target(y): return get_ideal_k_mtrx(y, y, activation=activation, n_classes=n_classes)
    _, k_min, k_max = get_loss_act(activation)
    if neo:
        def loss_fn(x, y): return -torch.mean(torch.exp(x[y == k_min]))
    else:
        def loss_fn(x, y): return torch.sum(torch.exp(x[y == k_max])) / \
            torch.sum(torch.exp(x))

    return _make_fn(
        map_input=map_input,
        map_target=map_target,
        loss=loss_fn,
    )

def _srs_log_contrastive(activation, n_classes, neo):
    """
    A contrastive-loss-like instantiation.
    """
    _, k_min, k_max = get_loss_act(activation)
    if neo:
        def loss_fn(x, y): return - \
            torch.log(torch.mean(torch.exp(x[y == k_min])))
    else:
        def loss_fn(x, y):
            dims = list(range(len(x.size())))
            return torch.logsumexp(x[y == k_max], dim=0) - torch.logsumexp(x, dim=dims)

    def map_input(x): return torch.where(
        torch.eye(len(x)).to(x.device) == 1,
        torch.tensor(-utils.INF).to(x.device),
        get_k_mtrx(x, x, activation=activation)
    )  # removes the main diagonal
    def map_target(y): return get_ideal_k_mtrx(y, y, activation=activation, n_classes=n_classes)

    return _make_fn(
        map_input=map_input,
        map_target=map_target,
        loss=loss_fn,
    )

srs_raw_neo = functools.partial(_srs_raw, neo=True)
srs_raw = functools.partial(_srs_raw, neo=False)
srs_nmse_neo = functools.partial(_srs_nmse, neo=True)
srs_nmse = functools.partial(_srs_nmse, neo=False)
srs_upper_tri_alignment_neo = functools.partial(_srs_upper_tri_alignment, neo=True)
srs_upper_tri_alignment = functools.partial(_srs_upper_tri_alignment, neo=False)
srs_alignment_neo = functools.partial(_srs_alignment, neo=True)
srs_alignment = functools.partial(_srs_alignment, neo=False)
srs_contrastive_neo = functools.partial(_srs_contrastive, neo=True)
srs_contrastive = functools.partial(_srs_contrastive, neo=False)
srs_log_contrastive_neo = functools.partial(_srs_log_contrastive, neo=True)
srs_log_contrastive = functools.partial(_srs_log_contrastive, neo=False)


from unityagents import UnityEnvironment
import numpy as np
from ddpg_agent import Agent
import torch
from collections import deque
import matplotlib.pyplot as plt

env = UnityEnvironment(file_name='Tennis_Windows_x86_64/Tennis.exe',no_graphics=True)

# get the default brain
brain_name = env.brain_names[0]
brain = env.brains[brain_name]

# reset the environment
env_info = env.reset(train_mode=True)[brain_name]

# number of agents
num_agents = len(env_info.agents)

# size of each action
action_size = brain.vector_action_space_size

# size state space
states = env_info.vector_observations
state_size = states.shape[1]

# init agent
agent = Agent(state_size, action_size, random_seed=2)

def ddpg(n_episodes=3000, target_score=0.5, print_every=10, window_len=100, updateAfterEvery=1, numUpdateCycles=1):
    scoreOverEpisodes = []
    averageScore = []
    scoreDeque = deque(maxlen=window_len)
    actions = np.zeros([num_agents, action_size])

    for i_episode in range(1, n_episodes+1):
        env_info = env.reset(train_mode=True)[brain_name]      # reset the environment
        states = env_info.vector_observations                  # get the current state (for each agent)
        agent.reset()                                          # reset noise
        scores = np.zeros(num_agents)                          # initialize the score (for each agent)
        t = 0

        while True:
            t += 1
            actions = agent.act(states)                        # select an action (for each agent)
            env_info = env.step(actions)[brain_name]           # send all actions to tne environment
            next_states = env_info.vector_observations         # get next state (for each agent)
            rewards = env_info.rewards                         # get reward (for each agent)
            dones = env_info.local_done                        # see if episode finished

            for state, action, reward, next_state, done in zip(states, actions, rewards, next_states, dones):
                agent.store(state, action, reward, next_state, done)

            if t % updateAfterEvery == 0:
                for i in range(numUpdateCycles):
                    agent.learnFromBufferSamples()

            scores += rewards                                  # update the score (for each agent)
            states = next_states                               # roll over states to next time step
            if np.any(dones):                                  # exit loop if episode finished
                break

        if i_episode % print_every == 0:
            print('Score of episode {:04d}: {:1.4f} \t Window mean: {:1.4f}'.format(i_episode, np.max(scores), np.mean(scoreDeque)))

        scoreOverEpisodes.append(np.max(scores))
        scoreDeque.append(np.max(scores))
        averageScore.append(np.mean(scoreDeque))

        if np.mean(scoreDeque) >= target_score:
            # solved
            break

    torch.save(agent.actor_local.state_dict(), 'checkpoint_actor.pth')      # save final actor
    torch.save(agent.critic_local.state_dict(), 'checkpoint_critic.pth')    # save final critic

    print('Windowed mean score at episode {:04d}: \t Window mean: {:1.4f}'.format(i_episode, np.max(scores), np.mean(scoreDeque)))

    return scoreOverEpisodes, averageScore

scores, average = ddpg()
env.close()

# plot results
fig = plt.figure()
ax = fig.add_subplot(111)
plt.plot(np.arange(1, len(scores)+1), scores, label='instant')
plt.plot(np.arange(1, len(average)+1), average, label='average')
plt.ylabel('Score')
plt.xlabel('Episode #')
ax.legend(fontsize='large', loc='upper left')
plt.show()
fig.savefig('scores.png')


from pymongo import MongoClient
import config

client = MongoClient()
db = client[config.db_name]
posts = db.posts

def get_coord(t_id):
    loc_log = {}
    loc_lat = {}
    for id in t_id:
        count2 = 0
        for post in posts.find({'id':id}):
            log = 0.0
            lat = 0.0
            count = 0.0
            # pprint.pprint(post)
            # print(post['id'])
            if post['place'] and (post['id'] not in loc_log.keys()):
                for i in post['place']['bounding_box']['coordinates'][0]:
                    log += i[0]
                    lat += i[1]
                    count += 1
                log = log / count
                lat = lat / count
                loc_log[post['id']] = log
                loc_lat[post['id']] = lat
    return loc_log, loc_lat

def get_time(t_id):
    time = []
    for i in t_id:
        count2 = 0
        for post in posts.find({'id': i}):
            time.append(post['created_at'])

    return time


# -*- coding: utf-8 -*-
####
# 01/2011 Bernd Schlapsi <brot@gmx.info>
#
# This script is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# gPodder is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Dependencies:
# * python-mutagen (Mutagen is a Python module to handle audio metadata)
#
# This extension script adds episode title and podcast title to the audio file
# The episode title is written into the title tag
# The podcast title is written into the album tag

import base64
import datetime
import logging
import mimetypes

from mutagen import File
from mutagen.easyid3 import EasyID3
from mutagen.easymp4 import EasyMP4Tags
from mutagen.flac import Picture
from mutagen.id3 import APIC, ID3
from mutagen.mp3 import MP3, EasyMP3
from mutagen.mp4 import MP4Cover, MP4Tags

import gpodder
from gpodder import coverart

logger = logging.getLogger(__name__)

# workaround for https://github.com/quodlibet/mutagen/issues/334
# can't add_tags to MP4 when file has no tag
MP4Tags._padding = 0

_ = gpodder.gettext

__title__ = _('Tag downloaded files using Mutagen')
__description__ = _('Add episode and podcast titles to MP3/OGG tags')
__authors__ = 'Bernd Schlapsi <brot@gmx.info>'
__doc__ = 'https://gpodder.github.io/docs/extensions/tagging.html'
__payment__ = 'https://flattr.com/submit/auto?user_id=BerndSch&url=http://wiki.gpodder.org/wiki/Extensions/Tagging'
__category__ = 'post-download'

DefaultConfig = {
    'strip_album_from_title': True,
    'genre_tag': 'Podcast',
    'always_remove_tags': False,
    'auto_embed_coverart': False,
    'set_artist_to_album': False,
    'set_version': 4,
    'modify_tags': True,
    'remove_before_modify': False
}

class AudioFile(object):
    def __init__(self, filename, album, title, subtitle, genre, pubDate, cover):
        self.filename = filename
        self.album = album
        self.title = title
        self.subtitle = subtitle
        self.genre = genre
        self.pubDate = pubDate
        self.cover = cover

    def remove_tags(self):
        audio = File(self.filename, easy=True)
        if audio.tags is not None:
            audio.delete()
        audio.save()

    def write_basic_tags(self, remove_before_modify, modify_tags, set_artist_to_album, set_version):
        audio = File(self.filename, easy=True)

        if audio is None:
            logger.warning("Unable to add tags to file '%s'", self.filename)
            return

        if audio.tags is None:
            audio.add_tags()

        if modify_tags:
            if remove_before_modify:
                audio.delete()

            if self.album is not None:
                audio.tags['album'] = self.album

            if self.title is not None:
                audio.tags['title'] = self.title

            if self.subtitle is not None:
                audio.tags['subtitle'] = self.subtitle

            if self.subtitle is not None:
                audio.tags['comments'] = self.subtitle

            if self.genre is not None:
                audio.tags['genre'] = self.genre

            if self.pubDate is not None:
                audio.tags['date'] = self.pubDate

            if set_artist_to_album:
                audio.tags['artist'] = self.album

        if type(audio) is EasyMP3:
            audio.save(v2_version=set_version)
        else:
            # Not actually audio
            audio.save()

    def insert_coverart(self):
        """ implement the cover art logic in the subclass
        """
        None

    def get_cover_picture(self, cover):
        """ Returns mutagen Picture class for the cover image
        Useful for OGG and FLAC format

        Picture type = cover image
        see http://flac.sourceforge.net/documentation_tools_flac.html#encoding_options
        """
        f = file(cover)
        p = Picture()
        p.type = 3
        p.data = f.read()
        p.mime = mimetypes.guess_type(cover)[0]
        f.close()

        return p

class OggFile(AudioFile):
    def __init__(self, filename, album, title, subtitle, genre, pubDate, cover):
        super(OggFile, self).__init__(filename, album, title, subtitle, genre, pubDate, cover)

    def insert_coverart(self):
        audio = File(self.filename, easy=True)
        p = self.get_cover_picture(self.cover)
        audio['METADATA_BLOCK_PICTURE'] = base64.b64encode(p.write())
        audio.save()

class Mp4File(AudioFile):
    def __init__(self, filename, album, title, subtitle, genre, pubDate, cover):
        super(Mp4File, self).__init__(filename, album, title, subtitle, genre, pubDate, cover)

    def insert_coverart(self):
        audio = File(self.filename)

        if self.cover.endswith('png'):
            cover_format = MP4Cover.FORMAT_PNG
        else:
            cover_format = MP4Cover.FORMAT_JPEG

        data = open(self.cover, 'rb').read()
        audio.tags['covr'] = [MP4Cover(data, cover_format)]
        audio.save()

class Mp3File(AudioFile):
    def __init__(self, filename, album, title, subtitle, genre, pubDate, cover):
        super(Mp3File, self).__init__(filename, album, title, subtitle, genre, pubDate, cover)

    def insert_coverart(self):
        audio = MP3(self.filename, ID3=ID3)

        if audio.tags is None:
            audio.add_tags()

        audio.tags.add(
            APIC(
                encoding=3,  # 3 is for utf-8
                mime=mimetypes.guess_type(self.cover)[0],
                type=3,
                desc='Cover',
                data=open(self.cover, 'rb').read()
            )
        )
        audio.save()

class gPodderExtension:
    def __init__(self, container):
        self.container = container
        # fix #737 EasyID3 doesn't recognize subtitle and comment tags
        EasyID3.RegisterTextKey("comments", "COMM")
        EasyID3.RegisterTextKey("subtitle", "TIT3")
        EasyMP4Tags.RegisterTextKey("comments", "desc")
        EasyMP4Tags.RegisterFreeformKey("subtitle", "SUBTITLE")

    def on_episode_downloaded(self, episode):
        info = self.read_episode_info(episode)
        if info['filename'] is None:
            return

        self.write_info2file(info, episode)

    def get_audio(self, info, episode):
        audio = None
        cover = None
        audioClass = None

        if self.container.config.auto_embed_coverart:
            cover = self.get_cover(episode.channel)

        if info['filename'].endswith('.mp3'):
            audioClass = Mp3File
        elif info['filename'].endswith('.ogg'):
            audioClass = OggFile
        elif info['filename'].endswith('.m4a') or info['filename'].endswith('.mp4'):
            audioClass = Mp4File
        elif File(info['filename'], easy=True):
            # mutagen can work with it: at least add basic tags
            audioClass = AudioFile

        if audioClass:
            audio = audioClass(info['filename'],
                info['album'],
                info['title'],
                info['subtitle'],
                info['genre'],
                info['pubDate'],
                cover)
        return audio

    def read_episode_info(self, episode):
        info = {
            'filename': None,
            'album': None,
            'title': None,
            'subtitle': None,
            'genre': None,
            'pubDate': None
        }

        # read filename (incl. file path) from gPodder database
        info['filename'] = episode.local_filename(create=False, check_only=True)
        if info['filename'] is None:
            return

        # read title+album from gPodder database
        info['album'] = episode.channel.title
        title = episode.title
        if (self.container.config.strip_album_from_title and title and info['album'] and title.startswith(info['album'])):
            info['title'] = title[len(info['album']):].lstrip()
        else:
            info['title'] = title

        info['subtitle'] = episode._text_description

        if self.container.config.genre_tag is not None:
            info['genre'] = self.container.config.genre_tag

        # convert pubDate to string
        try:
            pubDate = datetime.datetime.fromtimestamp(episode.pubDate)
            info['pubDate'] = pubDate.strftime('%Y-%m-%d %H:%M')
        except:
            try:
                # since version 3 the published date has a new/other name
                pubDate = datetime.datetime.fromtimestamp(episode.published)
                info['pubDate'] = pubDate.strftime('%Y-%m-%d %H:%M')
            except:
                info['pubDate'] = None

        return info

    def write_info2file(self, info, episode):
        audio = self.get_audio(info, episode)

        if self.container.config.always_remove_tags:
            audio.remove_tags()
        else:
            audio.write_basic_tags(self.container.config.remove_before_modify,
                                   self.container.config.modify_tags,
                                   self.container.config.set_artist_to_album,
                                   self.container.config.set_version)

            if self.container.config.auto_embed_coverart:
                audio.insert_coverart()

        logger.info('tagging.on_episode_downloaded(%s/%s)', episode.channel.title, episode.title)

    def get_cover(self, podcast):
        downloader = coverart.CoverDownloader()
        return downloader.get_cover(podcast.cover_file, podcast.cover_url,
            podcast.url, podcast.title, None, None, True)


import pandas as pd
from pymongo import MongoClient,TEXT
from json import loads
from datetime import datetime

client = MongoClient('mongodb://localhost:27017/')
db = client["datavis"]

senate = db["senate"]
chamber = db["chamber"]

def to_mongo(dest, data, idxs=[]):
    dest.drop()

    for chunk in data:
        dest.insert_one(loads(chunk.to_json(orient='records')))

    for idx in idxs:
    	dest.create_index(idx)

indexes = [("congressperson_name",TEXT)]

deputies_dtype= {"cnpj_cpf":"np.uint64","document_number":"np.uint64","issue_date":datetime}
df_deputies = pd.read_csv('data/Chamber/reimbursements.xz',compression='xz',chunksize=10000,thousands=",")
to_mongo(chamber,df_deputies,indexes)

df_senate = pd.read_csv("data/Senate/federal-senate-reimbursements.xz",compression='xz',chunksize=10000,thousands=",")
to_mongo(senate,df_senate,indexes)


# Import the necessary libraries
from gripable.udpclient.flex.FlexUdp import FlexUdp
from gripable.udpclient.flex.FlexUdp2 import FlexUdp2
from gripable.udpclient.flex.protobuf.SensorData_pb2 import SensorData
import time
import RPi.GPIO as gpio
import statistics

# Start connections with the GripAble devices
flex_right = FlexUdp()
flex_left = FlexUdp2()
flex_right.start()
flex_left.start()
acc_min = 0.3        # Minimum acceleration which is detected by the GripAble device
goForward = True     # Variable to change between forward and reverse modes

# Previous accelerations to compute mean values
prev_acc_right = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
prev_acc_left = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

print("Initializing connection")
gpio.setmode(gpio.BOARD)
gpio.setwarnings(False)

# Variables for trigger and echo pins of ultrasonic sensors
Trigger_right = 29
Echo_right = 36
Trigger_left = 31
Echo_left = 32

# Declaration of driver pins
gpio.setup(12, gpio.OUT)
gpio.setup(16, gpio.OUT)
gpio.setup(33, gpio.OUT)
gpio.setup(37, gpio.OUT)

# Declaration of led's which notice the direction of the car
gpio.setup(24, gpio.OUT)  # Blue led for backward mode
gpio.output(24, gpio.LOW)
gpio.setup(40, gpio.OUT)  # Green led for forward mode
gpio.output(40, gpio.HIGH)

# Declaration of trigger and echo pins of ultrasonic sensors
gpio.setup(Trigger_right, gpio.OUT)
gpio.setup(Echo_right, gpio.IN)
gpio.output(Trigger_right, False)  # Setting the right trigger pin to zero as default
gpio.setup(Trigger_left, gpio.OUT)
gpio.setup(Echo_left, gpio.IN)
gpio.output(Trigger_left, False)  # Setting the left trigger pin to zero as default

# Buzzer to give sound feedback
gpio.setup(18, gpio.OUT)
beep = gpio.PWM(18, 100)
beep.start(0)

# Assignation of pins to motors
motor_right_forward = gpio.PWM(33, 100)
motor_right_reverse = gpio.PWM(37, 100)
motor_left_forward = gpio.PWM(12, 100)
motor_left_reverse = gpio.PWM(16, 100)

# Function to move forward right motor
def forward_right_motor(velocity):
    motor_right_reverse.stop()
    motor_right_forward.start(0)
    motor_right_forward.ChangeDutyCycle(velocity)

# Function to move reverse right motor
def reverse_right_motor(velocity):
    motor_right_forward.stop()
    motor_right_reverse.start(0)
    motor_right_reverse.ChangeDutyCycle(velocity)

# Function to move forward left motor
def forward_left_motor(velocity):
    motor_left_reverse.stop()
    motor_left_forward.start(0)
    motor_left_forward.ChangeDutyCycle(velocity)

# Function to move reverse left motor
def reverse_left_motor(velocity):
    motor_left_forward.stop()
    motor_left_reverse.start(0)
    motor_left_reverse.ChangeDutyCycle(velocity)

# Function to limit values between min_acc and 1
def value_limits(value):
    if value > 1.0:
        value = 1.0
    if value < acc_min:
        value = 0
    return value * 100

# Function to spin in place moving to the right
def spin_in_place_right(velocity):
    motor_right_reverse.stop()
    motor_left_forward.stop()
    motor_right_forward.start(0)
    motor_left_reverse.start(0)
    motor_right_forward.ChangeDutyCycle(velocity)
    motor_left_reverse.ChangeDutyCycle(velocity)

# Function to spin in place moving to the left
def spin_in_place_left(velocity):
    motor_right_forward.stop()
    motor_left_reverse.stop()
    motor_right_reverse.start(0)
    motor_left_forward.start(0)
    motor_right_reverse.ChangeDutyCycle(velocity)
    motor_left_forward.ChangeDutyCycle(velocity)

# Function to read distance with ultrasonic sensor
def read_distance(trigger, echo):
    global end_time, start_time
    gpio.output(trigger, True)
    time.sleep(0.00001)
    gpio.output(trigger, False)
    while gpio.input(echo) == 0:
        start_time = time.time()
    while gpio.input(echo) == 1:
        end_time = time.time()
    difference = end_time - start_time
    distance = 17150 * difference
    print("Measured distance is ", distance, " cm")

    # Use the buzzer to notice if the distance with the wall is very low or high
    if (distance < 5) or (distance > 20):
        beep.ChangeDutyCycle(100)
        time.sleep(0.01)
        beep.ChangeDutyCycle(0)

# Ask user to use the sensors of the right side, left one or no one
sensor = input("Please write 1 to use the right distance sensor, 2 to use the left one or 3 do not use them:   ")
sensor = float(sensor)

# Main loop
while True:
    try:
        time.sleep(0.05)  # Sleep time necessary to read measures of the GripAble device

        multi = 2
        if sensor == 1:  # The user chose use the right ultrasonic sensor
            read_distance(Trigger_right, Echo_right)
            multi = 1
        elif sensor == 2:  # The user chose use the left ultrasonic sensor
            read_distance(Trigger_left, Echo_left)
            multi = 1

        # Read the data of the GripAble devices
        devRdata: SensorData = flex_right.getSensorData()
        devLdata: SensorData = flex_left.getSensorData()

        # Saving acceleration and force values of both GripAble devices
        acc_right = float(devRdata.accelerometer.x)
        acc_right_abs = abs(acc_right)
        acc_left = float(devLdata.accelerometer.x)
        acc_left_abs = abs(acc_left)
        force_right = devRdata.grip.force
        force_left = devLdata.grip.force

        # Deleting first element of previous acceleration lists and save the new one
        del prev_acc_right[0]
        prev_acc_right.append(acc_right_abs)
        del prev_acc_left[0]
        prev_acc_left.append(acc_left_abs)

        # Computation of the mean values and limit both accelerations
        mean_acc_right = multi * statistics.mean(prev_acc_right)
        mean_acc_right = value_limits(mean_acc_right)
        print("Mean acc right: %f \n" % mean_acc_right, end="")
        mean_acc_left = multi * statistics.mean(prev_acc_left)
        mean_acc_left = value_limits(mean_acc_left)
        print("Mean acc left: %f \n" % mean_acc_left, end="")

        # Mode 1: forward and reverse, Mode 2: spin in place right direction, Mode 3: spin in place left direction
        mode = 1

        # If force is applied to both GripAble devices change between forward and reverse
        if (force_right > 1) and (force_left > 1):
            if goForward:
                gpio.output(40, gpio.LOW)  # Turn off the front led
                gpio.output(24, gpio.HIGH)  # Turn on the back led
                goForward = False
                print("Reverse mode \n")
            else:
                gpio.output(24, gpio.LOW)  # Turn off the back led
                gpio.output(40, gpio.HIGH)  # Turn on the front led
                goForward = True
                print("Forward mode \n")
            time.sleep(1)

        # While force is applied to the right GripAble it will spin in place to the right
        elif (force_right > 1) and (force_left < 1) and (mean_acc_right > acc_min):
            print("Spin in place mode to the right \n")
            mode = 2
            time.sleep(1)

        # While force is applied to the left GripAble it will spin in place to the left
        elif (force_right < 1) and (force_left > 1) and (mean_acc_left > acc_min):
            print("Spin in place mode to the left \n")
            mode = 3
            time.sleep(1)

        if mode == 1:  # Forward and reverse mode
            if (mean_acc_right > acc_min) or (mean_acc_left > acc_min):
                if goForward:  # Forward movement
                    # Apply same velocity to both wheels if accelerations are similar
                    if abs(mean_acc_right - mean_acc_left) < 40:
                        vel = max(mean_acc_right, mean_acc_left)
                        print("Same velocity %f \n" % vel, end="")
                        forward_right_motor(vel)
                        forward_left_motor(vel - 2)
                    else:
                        forward_right_motor(mean_acc_right)
                        forward_left_motor(mean_acc_left)

                else:  # Reverse movement
                    # Apply same velocity to both wheels if accelerations are similar
                    if abs(mean_acc_right - mean_acc_left) < 40:
                        vel = max(mean_acc_right, mean_acc_left)
                        reverse_right_motor(vel)
                        reverse_left_motor(vel - 2)
                    else:
                        reverse_right_motor(mean_acc_right)
                        reverse_left_motor(mean_acc_left)

            if mean_acc_right < acc_min:  # If right GripAble is not moving stop right motor
                motor_right_forward.stop()
                motor_right_reverse.stop()

            if mean_acc_left < acc_min:  # If left GripAble is not moving stop left motor
                motor_left_forward.stop()
                motor_left_reverse.stop()

        elif mode == 2:  # Spin in place to the right mode
            spin_in_place_right(mean_acc_right)

        elif mode == 3:  # Spin in place to the left mode
            spin_in_place_left(mean_acc_left)

    except KeyboardInterrupt:
        break

# Stop connections with the GripAble devices and clean the gpio configuration
print("MOVit movement program stopped")
gpio.cleanup()
flex_right.stop()
flex_right.join()
flex_left.stop()
flex_left.join()


class Solution(object):
    def hammingDistance(self, x, y):
        """
        :type x: int
        :type y: int
        :rtype: int
        """
        x=bin(x)[2:]
        y=bin(y)[2:]
        #print(x,y)
        #print([0]*0)
        x1,y1=[],[]
        if(len(x)<len(y)):
            x1=['0']*(len(y)-len(x))
            x1.append(x)
            y1.append(y)
        #elif(len(x)len(y)):
        else:
            y1=['0']*(len(x)-len(y))
            y1.append(y)
            x1.append(x)
        #print(''.join(x1),''.join(y1))
        x1=''.join(x1)
        y1=''.join(y1)
        cnt=0
        for i in range(0,len(x1)):
            if(x1[i]!=y1[i]):
                cnt+=1
        return(cnt)


import json
from enum import Enum
from typing import List, Optional

from pydantic import BaseModel, Field, validator  # pylint: disable=no-name-in-module

class ContentSignature(BaseModel):
    """
    Defines the data used to generate the signature, as well as the signer's identifier.
    """
    event_content_hash: str = Field(
        description="Hash of the event content. It's also the request id")
    signer: str = Field(description="Identifier of the signer")
    timestamp: int = Field(description="Timestamp of the event")

class Signature(BaseModel):
    """
    The format, in addition to the signature, includes additional information,
    namely the signer's identifier, the signature timestamp and the hash of the signed contents.
    """
    content: ContentSignature = Field(description="The signed content")
    signature: str = Field(description="The signature value")

class Metadata(BaseModel):
    """
    Metadata of a TAPLE Event
    """
    governance_id: str = Field(description="Identifier of the governance")
    governance_version: int = Field(
        description="Version of the governance")
    namespace: str = Field(description="Namespace")
    owner: str = Field(description="Owner identifier")
    schema_id: str = Field(description="Identifier of the schema")

class ApprovalType(str, Enum):
    """
    Approval type
    """
    Accept = "Accept"
    Reject = "Reject"

class ContentApproval(BaseModel):
    """
    Defines the data used to generate the signature,
    as well as the signer's identifier.
    """
    approval_type: ApprovalType = Field(description="Type of approval")
    event_request_hash: str = Field(
        description="Hash of the event request")
    expected_sn: int = Field(description="Expected sequence number")
    signer: str = Field(description="Identifier of the signer")
    timestamp: int = Field(description="Timestamp of the approval")

class Approval(BaseModel):
    """
    Approval of a TAPLE Event
    """
    content: ContentApproval = Field(
        description="Content approval")
    signature: str = Field(description="The signature value")

class Payload(BaseModel):
    """
    Payload of a TAPLE Event type json
    """
    json_: Optional[dict] = Field(
        description="Payload", alias="Json", default=None)
    json_patch: Optional[dict] = Field(
        description="Payload", alias="JsonPatch", default=None)

    @validator("json_", pre=True)
    @classmethod
    def coerce_dict(cls, value):
        """
        Coerce dict
        """
        if isinstance(value, dict):
            return value
        return json.loads(value)

    @validator("json_patch", pre=True)
    @classmethod
    def coerce_dict_patch(cls, value):
        """
        Coerce dict
        """
        if isinstance(value, dict):
            return value
        return json.loads(value)

    class Config:  # pylint: disable=missing-class-docstring
        allow_population_by_field_name = True

class Create(BaseModel):
    """
    Create event
    """
    governance_id: str = Field(description="Governance identifier")
    namespace: str = Field(description="Namespace")
    payload: Payload = Field(description="Payload object")
    schema_id: str = Field(
        description="Identifier of the schema used by the object")

class State(BaseModel):
    """
    Change State event
    """
    payload: Payload = Field(description="Payload object")
    subject_id: str = Field(description="Subject identifier")

class RequestType(str, Enum):
    """
    Approval type
    """
    CREATE = "Create"
    STATE = "State"

class Request(BaseModel):
    """
    Request of an event
    """
    create: Optional[Create] = Field(
        description="Create event", alias="Create", default=None)
    state: Optional[State] = Field(
        description="State event", alias="State", default=None)

    @property
    def get_type(self) -> RequestType:
        """
        Get type of event
        """
        return RequestType.CREATE if self.create else RequestType.STATE

    @property
    def payload(self) -> Payload:
        """
        Get payload of event
        """
        return self.create.payload if self.create else self.state.payload

    @property
    def subject_id(self) -> str:
        """
        Get subject id of event
        """
        return self.state.subject_id if self.state else None

    @property
    def schema_id(self) -> str:
        """
        Get schema id of event
        """
        return self.create.schema_id if self.create else None

    class Config:  # pylint: disable=missing-class-docstring
        allow_population_by_field_name = True

class EventRequest(BaseModel):
    """
    Request that originated the event. It contains basically the proposed change and the votes obtained related to it.
    """
    approvals: List[Approval] = Field(description="List of approvals")
    request: Request = Field(description="Request object")
    signature: Signature = Field(description="Signature object")
    timestamp: int = Field(description="Timestamp")

    @property
    def request_id(self) -> str:
        """
        Get request id
        """
        return self.signature.content.event_content_hash

class EventContent(BaseModel):
    """
    Content of a TAPLE Event
    """
    approved: bool = Field(
        description="Indicates if the event is approved")
    event_request: EventRequest = Field(
        description="Request that originated the event")
    metadata: Metadata = Field(description="Metadata of the event")
    previous_hash: str = Field(description="Hash of the previous event")
    sn: int = Field(description="Sequence number of the event")
    state_hash: str = Field(description="Hash of the state")
    subject_id: str = Field(description="Subject identifier")

class Event(BaseModel):
    """
    TAPLE Event
    """
    event_content: EventContent = Field(
        description="Content of the event")
    signature: Signature = Field(description="Signature of the event")


_DEFAULT_INDENTATION = 4

class _node:

    def __init__(self, fd, doc, name, attrs, indent, level):
        """ Base class for xml elements
        Keyword arguments:
            fd     - output file-like writable object
            doc    - document object
            name   - element name
            attrs  - element attributes {name1:value1, name2:value2 ... }
            indent - if true all children will be output after a CR+level
            level  - current indentation level
        """
        self.fd = fd
        self.doc = doc
        self.name = name
        self.attrs = attrs
        self.indent = indent
        self.level = level
        self.hascontent = False

    def element(self, name, attrs={}):
        """ Element with indentation
            indentation is ignored if doc.pretty==False
        """
        return self._element(name, attrs, True)

    def helement(self, name, attrs={}):
        """ Element with no indentation
            content is never indented even if doc.pretty==True
        """
        return self._element(name, attrs, False)

    def _element(self, name, attrs, indentation):
        if not self.hascontent:
            self.fd.write(">")
        self.hascontent = True
        childlevel = self.level
        if self.doc.pretty and self.indent:
            self.fd.write("\n" + (" " * self.level))
            childlevel += self.doc.indentation
        return _node(self.fd, self.doc, name, attrs, indentation, childlevel)

    def text(self, text):
        """ Element text """
        if not self.hascontent:
            self.fd.write(">")
        self.hascontent = True
        self.fd.write(str(text))

    def __enter__(self):
        self.fd.write(f"<{self.name}")
        for k, v in self.attrs.items():
            self.fd.write(f" {k}=\"{v}\"")
        return self

    def __exit__(self, type, value, traceback):
        if not self.doc.compactempty and not self.hascontent:
            self.fd.write(">")
        if not self.doc.compactempty or self.hascontent:
            if self.doc.pretty and self.indent:
                nspaces = self.level-self.doc.indentation
                self.fd.write("\n" + (" " * nspaces))
            self.fd.write(f"</{self.name}>")
        else:
            self.fd.write("/>")

class _document(_node):
    """ XML document """
    global _DEFAULT_INDENTATION

    def __init__(self, fd, encoding, pretty, compactempty, indentation):
        super().__init__(fd, self, "document", {}, True, 0)
        self.encoding = encoding
        self.pretty = pretty
        self.indentation = indentation
        self.compactempty = compactempty

    def __enter__(self):
        prolog = "<?xml version=\"1.0\" encoding=\"%s\"?>"
        self.fd.write(prolog % self.encoding)
        self.hascontent = True
        return self

    def __exit__(self, type, value, traceback):
        if self.pretty:
            self.fd.write("\n")

def XMLWriter(
    fd,
    encoding="utf-8",
    pretty=True,
    compactempty=True,
    indentation=_DEFAULT_INDENTATION
):
    """ Create a document for output on given file-like fd object
    Keyword arguments:
        fd           - file-like object, only write(text) method is required
        encoding     - xml file encoding, this is the caller responsabily to
                            respect this when creating elements
        pretty       - True for pretty-print output
        compactempty - if True empty elements will be in compact form <name/>
        indentation  - indentation level, default 4
    """
    return _document(fd, encoding, pretty, compactempty, indentation)


import sys

class ParserInput(object) :
    def __init__(self, data, position=0) :
        self._data = data
        self._position = position
        self._max_position = position

    def data(self) :
        return self._data

    def position(self) :
        return self._position

    def remaining(self) :
        return len(self._data) - self._position

    def read(self, n=1) :
        i = self._position
        return self._data[i:i+n]

    def inc_position(self, n=1) :
        self._position += n
        self._max_position = max(self._max_position, self._position)

    def set_position(self, position) :
        self._position = position
        self._max_position = max(self._max_position, self._position)

    def max_position(self) :
        return self._max_position

#
# Match, NoMatch
#
# A parser object returns either a Match or NoMatch object.
# The Match object contains a 'value' property that holds
# the result of parsing.
#

class Match(object) :
    def __init__(self, value) :
        self.value = value

    def __repr__(self) :
        return "Match(%s)" % (self.value,)

class NoMatch(object) :
    def __repr__(self) :
        return "NoMatch()"

def is_match(result) :
    return isinstance(result, Match)

#
# Parser
#
# This is the base-class representing parser objects.
# The 'parse' method is the method that does the parsing.
# It accepts a ParserInput object and returns either a Match
# or NoMatch object.
#
# In the case of a match, the parsed result is returned
# in the 'value' property of the Match object and the
# parser input position is advanced by the length of the input
# that was parsed.
#
# In the case of no-match, the parser input position must
# remain unchanged from what it was when the 'parse' method
# was called. If the input position was advanced during
# intermediate stages, then it should be restored back to
# what it was when the 'parse' method was called.
#
# Note on the 'match' method and 'modifier' attribute:
#
# The 'modifier' attribute can be set to a function that
# modifies the 'value' property of the Match object in the event
# of a successful match. The 'match' method is a helper method
# that applies the 'modifier' if it is present.
#

class Parser(object) :
    def match(self, value) :
        modifier = getattr(self, "modifier", None)
        if modifier is not None :
            value = self.modifier(value)
        return Match(value)

    def parse(self, parser_input) :
        raise NotImplementedError

#
# Char
#
# The Char parser parses a single character matching the character
# provided in the constructor if it is found at the current position
# and fails if it's not found or if there are no more characters left.
#

class Char(Parser) :
    def __init__(self, char) :
        self._char = char

    def parse(self, parser_input) :
        if parser_input.remaining() == 0 :
            return NoMatch()
        c = parser_input.read()
        if c != self._char :
            return NoMatch()
        parser_input.inc_position()
        return self.match(c)

#
# CharSet
#
# The CharSet parser parses a single character matching any one
# of the characters passed in the constructor. The input to the
# constructor can be a string, a list of characters, or a set of
# characters.
#

class CharSet(Parser) :
    def __init__(self, chars) :
        self._chars = chars

    def parse(self, parser_input) :
        if parser_input.remaining() == 0 :
            return NoMatch()
        c = parser_input.read()
        if c not in self._chars :
            return NoMatch()
        parser_input.inc_position()
        return self.match(c)

#
# ZeroOrMore
#
# ZeroOrMore takes another parser as input and applies it repeatedly
# until it doesn't match. All the results of the repeated application
# are collected in a list and returned as the result of parsing.
#
# This parser never fails to match because it simply returns an
# empty list as a match if the input parser doesn't match even once.
#

class ZeroOrMore(Parser) :
    def __init__(self, parser) :
        self._parser = parser

    def parse(self, parser_input) :
        values = []
        while True :
            result = self._parser.parse(parser_input)
            if not is_match(result) :
                break
            values.append(result.value)
        return self.match(values)

#
# OneOrMore
#
# OneOrMore takes another parser as input and applies it repeatedly
# until it doesn't match. All the results of the repeated application
# are collected in a list and returned as the result of parsing.
#
# This parser matches only if the input parser matches atleast once.
#

class OneOrMore(Parser) :
    def __init__(self, parser) :
        self._parser = parser

    def parse(self, parser_input) :
        values = []
        while True :
            result = self._parser.parse(parser_input)
            if not is_match(result) :
                break
            values.append(result.value)
        if len(values) == 0 :
            return NoMatch()
        return self.match(values)

#
# Sequence
#
# The Sequence parser takes N parsers as input and applies them
# one after another. Sequence succeeds in matching if all the input
# parsers succeed and doesn't match even if one of input parsers don't
# match. In the event of a successful match, the results of the input
# parsers are collected in a list and returned as the result of parsing.
#

class Sequence(Parser) :
    def __init__(self, *parsers) :
        self._parsers = parsers

    def parse(self, parser_input) :
        values = []
        saved = parser_input.position()
        for parser in self._parsers :
            result = parser.parse(parser_input)
            if not is_match(result) :
                parser_input.set_position(saved)
                return NoMatch()
            values.append(result.value)
        return self.match(values)

#
# Choice
#
# The Choice parser takes N parsers as input. It applies the first one
# and if it succeeds then the result is returned as a successful match.
# If the first parser doesn't match, then the second parser is attempted.
# This continues until one of the parsers matches. The result of the
# first matching parser is returned as the match result of
# the Choice parser. The Choice parser doesn't match if all the
# input parsers fail to match.
#

class Choice(Parser) :
    def __init__(self, *parsers) :
        self._parsers = parsers

    def parse(self, parser_input) :
        for parser in self._parsers :
            result = parser.parse(parser_input)
            if is_match(result) :
                return self.match(result.value)
        return NoMatch()

#
# Optional
#
# The Optional parser takes a parser as input and always succeeds
# in matching. If the input parser succeeds in matching, then its
# result is returned as the result of a successful match. If the
# input parser doesn't match, then None is returned as a successful
# match.
#

class Optional(Parser) :
    def __init__(self, parser) :
        self._parser = parser

    def parse(self, parser_input) :
        result = self._parser.parse(parser_input)
        if not is_match(result) :
            return self.match(None)
        return self.match(result.value)

#
# Wrapper
#
# Wrapper is a simple direct wrapper around another parser.
# The input parser is available in the 'parser' property.
# It can be leftout during construction and can be set directly
# set later. This allows for forward declaring a parser that needs
# to call itself recursively.
#

class Wrapper(Parser) :
    def __init__(self, parser=None) :
        self.parser = parser

    def parse(self, parser_input) :
        result = self.parser.parse(parser_input)
        if not is_match(result) :
            return result
        return self.match(result.value)

#
# EOF
#
# The EOF parser succeeds in matching if the input posiition
# is at the end. It fails to match otherwise.
#

class EOF(Parser) :
    def parse(self, parser_input) :
        if parser_input.remaining() == 0 :
            return self.match(None)
        else :
            return NoMatch()

#
# Example 1
#
# Parse one or more digits
#

def example1() :
    digit = CharSet("0123456789")
    digits = OneOrMore(digit)
    return digits

#
# Example 2
#
# Parse one or more digits and convert to integer
#

def example2() :

    # convert single digit to integer
    def char_to_digit(c) :
        return ord(c) - ord("0")

    # convert list of digit values to integer
    def digits_to_number(a) :
        result = 0
        for x in a :
            result = result*10 + x
        return result

    digit = CharSet("0123456789")
    digit.modifier = char_to_digit
    digits = OneOrMore(digit)
    digits.modifier = digits_to_number
    return digits

#
# Example 3
#
# An expression parser.
#

def example3() :

    # Helpers

    def char_to_digit(c) :
        return ord(c) - ord("0")

    def digits_to_number(a) :
        result = 0
        for x in a :
            result = result*10 + x
        return result

    def bracket_inner(a) :
        return a[1]

    def apply_sign(a) :
        sign = a[0]
        if sign is not None :
            return [sign, a[1]]
        else :
            return a[1]

    def make_operation_tree(a) :
        value = a[0]
        for operator, value2 in a[1] :
            value = [operator, value, value2]
        return value

    # parsers

    whitespace = ZeroOrMore(Char(" "))

    def eat_space(parser) :
        parser2 = Sequence(whitespace, parser)
        parser2.modifier = lambda a : a[1]
        return Wrapper(parser2)

    digit = CharSet("0123456789")
    digit.modifier = char_to_digit

    number = eat_space(OneOrMore(digit))
    number.modifier = digits_to_number

    expr = Wrapper()

    left_parenthesis = eat_space(Char("("))
    right_parenthesis = eat_space(Char(")"))
    bracketed = Sequence(left_parenthesis, expr, right_parenthesis)
    bracketed.modifier = bracket_inner

    sign = eat_space(CharSet("+-"))
    atomic = Sequence(Optional(sign), Choice(number, bracketed))
    atomic.modifier = apply_sign

    term_operator = eat_space(CharSet("*/"))
    term_operation = Sequence(term_operator, atomic)
    term = Sequence(atomic, ZeroOrMore(term_operation))
    term.modifier = make_operation_tree

    expr_operator = eat_space(CharSet("+-"))
    expr_operation = Sequence(expr_operator, term)

    expr.parser = Sequence(term, ZeroOrMore(expr_operation))
    expr.modifier = make_operation_tree

    return expr

#
# main
#

main_parser = None

#
# Uncomment one of the following lines.
#
# main_parser = example1()
# main_parser = example2()
# main_parser = example3()

def main() :
    if main_parser is None :
        print("Please uncomment one of the example initializer lines")
        return

    if len(sys.argv) != 2 :
        print("%s <input>" % (sys.argv[0],))
        return
    s = sys.argv[1]
    parser_input = ParserInput(s, 0)
    result = main_parser.parse(parser_input)
    if not is_match(result) :
        print("ERROR: %s" % (s,))
        i = len("ERROR: ") + parser_input.max_position()
        print("%s^" % ("-"*i,))
    else :
        print("RESULT: %s" % result.value)
        i = parser_input.position()
        data = parser_input.data()
        if i < len(data) :
            print("UNPARSED LEFTOVER: %s" % data[i:])

if __name__ == "__main__" :
    main()


import asyncio
import random
import time, logging

format = '[%(asctime)s] %(levelname)s: %(message)s'
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.DEBUG, format=format)

async def heavy_work(n: int):
    i = 2 # random.randint(0, 2)
    logger.info(f"sleep for {i}")
    await asyncio.sleep(i)
    return f"finished {n}"

async def main(*args):
    results = await asyncio.gather(*(heavy_work(n) for n in args))
    logger.info(results)

if __name__ == "__main__":
    args = [1, 2, 3]

    start = time.perf_counter()
    asyncio.run(main(*args))

    end = time.perf_counter() - start
    logger.debug(f"Program finished in {end:0.2f} seconds.")


import numpy as np
import scipy.io
from numpy.linalg import inv as inv
from keras.models import Sequential
from keras.layers import Dense, LSTM, Dropout, Activation
from sklearn.preprocessing import MinMaxScaler
import time
def kr_prod(a, b):
    return np.einsum('ir, jr -> ijr', a, b).reshape(a.shape[0] * b.shape[0], -1)
def cp_combine(U, V, X):
    return np.einsum('is, js, ts -> ijt', U, V, X)
def ten2mat(tensor, mode):
    return np.reshape(np.moveaxis(tensor, mode, 0), (tensor.shape[mode], -1), order = 'F')
def graph_weight_cal(dist, epsilon = 0.5):
    dim = dist.shape[0]
    distances = dist[np.nonzero(dist)].flatten()
    std = distances.std()
    print(std)
    std_square = 5 * std ** 2
    A = np.zeros((dim, dim))
    for i in range(dim):
        for j in range(dim):
            if dist[i][j] > 0:
                weight = np.exp(- dist[i][j] ** 2 / std_square)
                if i != j and weight >= epsilon:
                    A[i][j] = weight
    return A
def create_lstm_samples(dataset, time_lags, rate):
    dataX, dataY = [], []
    data_len = dataset.shape[0] - np.max(time_lags)
    t_sample = np.random.choice(data_len, int(rate * data_len), replace=False)

    for t in t_sample:
        a = dataset[t + np.max(time_lags) - time_lags, :][::-1]
        dataX.append(a)
        dataY.append(dataset[t + np.max(time_lags), :])
    return np.array(dataX), np.array(dataY)
def lstmmodel(rank, lag_len):
    # create the LSTM network
    model = Sequential()
#     model.add(LSTM(rank, input_shape = (lag_len, rank), return_sequences = True)) # If you need multi-layer LSTM
    model.add(LSTM(rank, input_shape = (lag_len, rank)))
    model.add(Dense(rank))
    model.compile(loss='mean_squared_error', optimizer='adam')
    return model
def mean_absolute_percentage_error(y_true, y_pred, pos):
#     y_true, y_pred = np.array(y_true), np.array(y_pred)
    return np.mean(np.abs((y_true[pos] - y_pred[pos]) / y_true[pos])) * 100
def root_mean_squared_error(y_true, y_pred, pos):
#     y_true, y_pred = np.array(y_true), np.array(y_pred)
    return np.sqrt(np.mean(np.square(y_true[pos] - y_pred[pos])))
def LSTM_GL_ReTF(sparse_tensor, invD, init, time_lags, lambda_w, lambda_g, lambda_v, lambda_x, eta, sampling_rate,
                 maxiter, track, dense_tensor=0):
    W = init["W"]
    V = init["V"]
    X = init["X"]
    dim1, dim2, dim3 = sparse_tensor.shape
    binary_tensor = np.zeros((dim1, dim2, dim3))
    position = np.where((sparse_tensor != 0))
    binary_tensor[position] = 1
    d = len(time_lags)
    max_lags = np.max(time_lags)
    r = X.shape[1]
    if track:
        pos = np.where((sparse_tensor == 0) & (dense_tensor != 0))
    model = lstmmodel(r, d)
    model_reverse = lstmmodel(r, d)
    start_time = time.time()

    for iters in range(maxiter):
        var1 = kr_prod(X, V).T  # (r, n*t)
        var2 = kr_prod(var1, var1)  # (r*r, n*t)
        mat1 = ten2mat(binary_tensor, 0).T  # (n*t, m)
        mat2 = ten2mat(sparse_tensor, 0).T  # (n*t, m)
        for i in range(dim1):
            vec1 = np.matmul(W.T, invD[i, :])
            var_Lambda1 = np.matmul(var2, mat1[:, i]).reshape([rank, rank]) + lambda_w * np.eye(
                rank) + lambda_g * np.eye(rank) * np.sum(invD[i, :])
            inv_var_Lambda1 = np.linalg.inv((var_Lambda1 + var_Lambda1.T) / 2)
            W[i, :] = np.matmul(inv_var_Lambda1, np.matmul(var1, mat2[:, i]) + lambda_g * vec1)

        var1 = kr_prod(X, W).T
        var2 = kr_prod(var1, var1)
        mat1 = ten2mat(binary_tensor, 1).T  # (m*t, n)
        mat2 = ten2mat(sparse_tensor, 1).T  # (m*t, n)
        for j in range(dim2):
            var_Lambda1 = np.matmul(var2, mat1[:, j]).reshape([rank, rank]) + lambda_v * eta * np.eye(rank)
            inv_var_Lambda1 = np.linalg.inv((var_Lambda1 + var_Lambda1.T) / 2)
            V[j, :] = np.matmul(inv_var_Lambda1, np.matmul(var1, mat2[:, j]))

        var1 = kr_prod(V, W).T  # (r, m*n)
        var2 = kr_prod(var1, var1)  # (r*r, m*n)
        mat1 = ten2mat(binary_tensor, 2).T  # (m*n, n)
        mat2 = ten2mat(sparse_tensor, 2).T  # (m*n, n)
        for t in range(dim3):
            if iters == 0 or t < max_lags:
                var_Lambda1 = np.matmul(var2, mat1[:, t]).reshape([rank, rank]) + lambda_x * eta * np.eye(rank)
                X[t, :] = np.matmul(inv((var_Lambda1 + var_Lambda1.T) / 2), np.matmul(var1, mat2[:, t]))
            else:
                var_Lambda1 = np.matmul(var2, mat1[:, t]).reshape([rank, rank]) + lambda_x * np.eye(
                    rank) + lambda_x * eta * np.eye(rank)
                X_hat = X[t - time_lags, :][::-1]
                X_hat_feed = X_hat[np.newaxis, :, :]
                Qt = model.predict(X_hat_feed,verbose=0)[0]
                X[t, :] = np.matmul(inv((var_Lambda1 + var_Lambda1.T) / 2),
                                    (np.matmul(var1, mat2[:, t]) + lambda_x * Qt))

        if iters == 0:
            lstmX, lstmY = create_lstm_samples(X, time_lags, 1)
            model.fit(lstmX, lstmY, epochs=20, batch_size=50, verbose=0)
        else:
            lstmX, lstmY = create_lstm_samples(X, time_lags, sampling_rate)
            model.fit(lstmX, lstmY, epochs=2, batch_size=10, verbose=0)
        if (iters + 1) % 1 == 0:
            print('Iterations: %d, time cost: %ds' % ((iters + 1), (time.time() - start_time)))
            start_time = time.time()
            if track:
                tensor_hat = cp_combine(W, V, X)
                tensor_hat[position] = sparse_tensor[position]
                tensor_hat[tensor_hat < 0] = 0
                rmse = root_mean_squared_error(dense_tensor, tensor_hat, pos)
                mape = mean_absolute_percentage_error(dense_tensor, tensor_hat, pos)
                print(np.mean(W))
                print(np.mean(V))
                print(np.mean(X))
                print('Imputation RMSE = %.2f' % rmse)
                print('Imputation MAPE = %.2f' % mape)
            print()
    #     model.save('model_save\lstm_trained1.h5')
    tensor_hat = cp_combine(W, V, X)
    tensor_hat[position] = sparse_tensor[position]
    tensor_hat[tensor_hat < 0] = 0
    return tensor_hat, W, V, X, model
def OnlineLSTMReTF(sparse_mat, init, lambda_x, time_lags):
    time_lags = time_lags[::-1]
    W = init["W"]
    V = init["V"]
    X = init["X"]
    model = init["model"]
    dim1, dim2 = sparse_mat.shape
    t, rank = X.shape
    X_hat = X[t - 1 - time_lags, :].copy()
    X_hat_feed = X_hat[np.newaxis, :, :]
    Qt = model.predict(X_hat_feed,verbose=0)[0]

    sparse_tensor = np.zeros((dim1, dim2, 1))
    sparse_tensor[:, :, 0] = sparse_mat
    position = np.where(sparse_tensor != 0)
    binary_tensor = np.zeros(sparse_tensor.shape)
    binary_tensor[position] = 1
    var1 = kr_prod(V, W).T
    var2 = kr_prod(var1, var1)
    var_mu = np.matmul(var1, ten2mat(sparse_tensor, 2).reshape([dim1 * dim2])) + lambda_x * Qt
    inv_var_Lambda = inv(
        np.matmul(var2, ten2mat(binary_tensor, 2).reshape([dim1 * dim2])).reshape([rank, rank]) + lambda_x * np.eye(
            rank))
    return np.matmul(inv_var_Lambda, var_mu)
def online_prediction(sparse_tensor, init, time_lags, lambda_x, maxiter):
    W = init["W"]
    V = init["V"]
    X = init["X"]
    model = init["model"]
    pre_step_num = X.shape[0]
    rank = X.shape[1]
    dim1, dim2, dim3 = sparse_tensor.shape
    X_hat = np.zeros((dim3 + pre_step_num, rank))
    tensor_pred = np.zeros((dim1, dim2, dim3))
    X_hat[:pre_step_num, :] = X.copy()
    start_time = time.time()
    for t in range(dim3):
        if t == 0:
            X_star = X_hat[pre_step_num + t - time_lags, :][::-1]
            X_star_feed = X_star[np.newaxis, :, :]
            Qt = model.predict(X_star_feed,verbose=0)[0]
            X_hat[pre_step_num + t, :] = Qt.copy()
        else:
            sparse_mat = sparse_tensor[:, :, t - 1]
            if np.where(sparse_mat > 0)[0].shape[0] > 0:
                init = {"W": W, "V": V, "X": X_hat[pre_step_num + t - np.max(time_lags) - 1: pre_step_num + t, :],
                        "model": model}
                X_c = OnlineLSTMReTF(sparse_mat, init, lambda_x / dim3, time_lags)
                X_hat[pre_step_num + t - 1, :] = X_c.copy()
                X_star = X_hat[pre_step_num + t - time_lags, :][::-1]
                X_star_feed = X_star[np.newaxis, :, :]
                Qt = model.predict(X_star_feed,verbose=0)[0]
                X_hat[pre_step_num + t, :] = Qt.copy()
            else:
                X_star = X_hat[pre_step_num + t - time_lags, :][::-1]
                X_star_feed = X_star[np.newaxis, :, :]
                Qt = model.predict(X_star_feed,verbose=0)[0]
                X_hat[pre_step_num + t, :] = Qt.copy()
        tensor_pred[:, :, t] = np.einsum('ir, jr, r -> ij', W, V, X_hat[pre_step_num + t, :])
        if (t + 1) % 1000 == 0:
            print('Time step: %d, time cost: %d s' % ((t + 1), (time.time() - start_time)))
            start_time = time.time()

    sparse_mat = sparse_tensor[:, :, -1]
    init = {"W": W, "V": V, "X": X_hat[dim2 + pre_step_num - np.max(time_lags) - 1:, :], "model": model}
    X_c = OnlineLSTMReTF(sparse_mat, init, lambda_x / dim2, time_lags)
    X_hat[dim2 + pre_step_num - 1, :] = X_c.copy()
    tensor_rec = cp_combine(W, V, X_hat[pre_step_num:, :])
    return tensor_rec, tensor_pred

directory = '../datasets/PEMS08/'

missing_rate = 0.1
mode = 'CM'

Dist = np.load(directory + 'Dist.npy')
A = np.load(directory + 'Adj.npy')
dense_tensor = np.load( directory + 'PeMS08.npy')

dim1, dim2, dim3 = dense_tensor.shape
# dense_mat = dense_tensor.reshape(dim1 * dim2, dim3)
# =============================================================================
### Point-wise missing (PM) scenario
### Set the PM scenario by:
if mode == 'PM':
    pm_random_mat = np.load(directory + 'pm_random_mat.npy')
    binary_mat = np.round(pm_random_mat + 0.5 - missing_rate)
    sparse_tensor = dense_tensor.copy()
    for i in range(dim2):
        sparse_tensor[:, i, :] = dense_tensor[:, i, :] * binary_mat
# =============================================================================
# =============================================================================
### Continuous-random missing (CM) scenario
### Set the CM scenario by:
if mode == 'CM':
    cm_random_mat = np.load(directory + 'cm_random_mat.npy')
    binary_mat = np.round(cm_random_mat + 0.5 - missing_rate)
    dense_tensor_reshape = dense_tensor.reshape(dim1, dim2, 62, 288)
    sparse_tensor_reshape = dense_tensor_reshape.copy()
    for i in range(dim1):
        for j in range(62):
            sparse_tensor_reshape[i, :, j, :] = dense_tensor_reshape[i, :, j, :] * binary_mat[i, j]
    sparse_tensor = sparse_tensor_reshape.reshape(dim1, dim2, dim3)
# =============================================================================
print('Missing rate = %s %.1f'%(mode, missing_rate))

sparse_tensor = np.expand_dims(sparse_tensor[:, 0, 8928:], axis=1)
dense_tensor = np.expand_dims(dense_tensor[:, 0, 8928:], axis=1)
print(sparse_tensor.shape,'shape')
dim1, dim2, dim3 = sparse_tensor.shape
#Creating training set and test set
test_len = 2880
train_len = dim3 - test_len
training_set = sparse_tensor[:, :, :train_len]
test_set = sparse_tensor[:, :, train_len:]
print('The size of training set is:')
print(training_set.shape)
print()
print('The size of test set is:')
print(test_set.shape)
#Saving ground truth(real value)
training_ground_truth = dense_tensor[:, :, :train_len]
test_ground_truth = dense_tensor[:, :, train_len:]
print('The size of training set ground truth is:')
print(training_ground_truth.shape)
print()
print('The size of test set ground truth is:')
print(test_ground_truth.shape)

np.random.seed(seed=10)
rank = 20
maxiter = 100
eta = 0.2
lambda_w = 100
lambda_g = 100
lambda_v = 100
lambda_x = 100
sampling_rate = 1.0
time_lags = np.array([1, 2, 288])#np.arange(1, 25, 1)
track = True
dim1, dim2, dim3 = training_set.shape
init = {"W": 0.1 * np.random.rand(dim1, rank), "V": 0.1 * np.random.rand(dim2, rank), "X": 0.1 * np.random.rand(dim3, rank)}
tensor_hat, W, V, X, model = LSTM_GL_ReTF(training_set, A, init, time_lags, lambda_w, lambda_g, lambda_v,
                                       lambda_x, eta, sampling_rate, maxiter, track, training_ground_truth)

start_time = time.time()
sc = 100000
init = {"W": W, "V": V, "X": X[- np.max(time_lags): , :], "model": model}
test_mat_rec, test_mat_pred = online_prediction(test_set, init, time_lags, sc * lambda_x, maxiter)
print('Shape of imputed data is:')
print(test_mat_rec.shape)
print()
print('Shape of predicted data is:')
print(test_mat_pred.shape)

print('10 first prediciton on test set:')
print(test_mat_pred[0, 0, :10])
print()
print('10 first real value on test set')
print(test_ground_truth[0, 0, :10])

# Prediction
pos = np.where(test_ground_truth != 0)
testPred_rmse = root_mean_squared_error(test_ground_truth, test_mat_pred, pos)
print('Test prediction RMSE: %.2f RMSE' % (testPred_rmse))
testPred_mape = mean_absolute_percentage_error(test_ground_truth, test_mat_pred, pos)
print('Test prediction MAPE: %.2f%% MAPE' % (testPred_mape))
print()


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

# range color
def detect_chess_board(path):
    hh = 500
    ww = 400
    image = cv2.imread(path)

    # resize image
    image = cv2.resize(image,(hh,ww))

    #1. Tách màu sáng, giữ lại màu đen
    # converting frame(image == BGR) to HSV(hue-saturation-value)
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    lower_red = np.array([0, 0, 137])
    upper_red = np.array([255, 255, 255])

    # Morphological Transformations,Opening and Closing
    thresh = cv2.inRange(hsv,lower_red, upper_red)
    kernel = np.ones((5,5),np.uint8)
    mask = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
    mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
    result = cv2.bitwise_and(image, image, mask = mask)

    #2. lấy vùng bàn cờ
    contours = cv2.findContours(255 - mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    # print(contours)
    contours = contours[0] if len(contours) == 2 else contours[1]
    mask_0 = np.zeros((ww,hh), dtype=np.uint8)
    for cntr in contours:
        cv2.drawContours(mask_0, [cntr], 0, (255,255,255), -1)
    result = cv2.bitwise_and(image, image, mask=mask_0)

    #3. Tách trắng lấy đen loại bỏ viền bàn cờ
    hsv = cv2.cvtColor(result, cv2.COLOR_BGR2HSV)
    lower_red = np.array([0, 0, 0])
    upper_red = np.array([255, 255, 162])

    # Morphological Transformations,Opening and Closing
    thresh = cv2.inRange(hsv,lower_red, upper_red)
    kernel = np.ones((15,15),np.uint8)

    #4. khử nhiễu
    mask = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
    mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
    image = np.zeros((ww,hh), dtype=np.uint8)
    image += 255
    result = cv2.bitwise_and(image, image, mask = mask)
    corners = 0
    mask_0 = mask
    #5. Lấy góc ô cờ
    found, corners = cv2.findChessboardCorners(result, (7, 7),flags=cv2.CALIB_CB_FAST_CHECK)
    # print(np.shape(corners))

    # corner_lt = (corners[0]-corners[16])

    img = cv2.imread(path)
    img = cv2.resize(img,(hh,ww))
    img2 = np.copy(img)  # Make a copy of original img as img2

    for corner in corners:
        # print(corner[0])
        coord = (int(corner[0][0]), int(corner[0][1]))
        # print(coord)
        cv2.circle(img=img2, center=coord, radius=2, color=(255, 0, 0), thickness=2)

    corner_lt = np.array([corners[0][0][0]-(corners[8][0][0]-corners[0][0][0])**2/(corners[16][0][0]-corners[8][0][0]),corners[0][0][1]-(corners[8][0][1]-corners[0][0][1])**2/(corners[16][0][1]-corners[8][0][1])])
    corner_rb = np.array([corners[48][0][0]+(corners[48][0][0]-corners[40][0][0])**2/(corners[40][0][0]-corners[32][0][0]),corners[48][0][1]+(corners[48][0][1]-corners[40][0][1])**2/(corners[40][0][1]-corners[32][0][1])])
    corner_lb = np.array([corners[42][0][0]-(corners[36][0][0]-corners[42][0][0])**2/(corners[30][0][0]-corners[36][0][0]),corners[42][0][1]+(corners[42][0][1]-corners[36][0][1])**2/(corners[36][0][1]-corners[30][0][1])])
    corner_rt = np.array([corners[6][0][0]+(corners[6][0][0]-corners[12][0][0])**2/(corners[12][0][0]-corners[18][0][0]),corners[6][0][1]-(corners[12][0][1]-corners[6][0][1])**2/(corners[18][0][1]-corners[12][0][1])])

    mask = np.zeros((ww,hh), dtype=np.uint8)
    mask = cv2.line(mask, (int(corner_lt[0]),int(corner_lt[1])), (int(corner_rt[0]),int(corner_rt[1])), (255,255,255), 2)
    mask = cv2.line(mask, (int(corner_lt[0]),int(corner_lt[1])), (int(corner_lb[0]),int(corner_lb[1])), (255,255,255), 2)
    mask = cv2.line(mask, (int(corner_rb[0]),int(corner_rb[1])), (int(corner_rt[0]),int(corner_rt[1])), (255,255,255), 2)
    mask = cv2.line(mask, (int(corner_rb[0]),int(corner_rb[1])), (int(corner_lb[0]),int(corner_lb[1])), (255,255,255), 2)

    contours = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    contours = contours[0] if len(contours) == 2 else contours[1]
    mask_0 = np.zeros((ww,hh), dtype=np.uint8)
    for cntr in contours:
        cv2.drawContours(mask_0, [cntr], 0, (255,255,255), -1)

    return mask_0, corners

def distance(p1,p2):
    return np.sqrt((p1[0]-p2[0])**2+(p1[1]-p2[1])**2)

def point_near(point, array):
    near = 10000
    near_index = np.array([0,0])
    for i in range(len(array)):
        dt= distance(point, array[i])
        if near > dt:
            near = dt

            near_index = np.array([i//7,i%7])
    print(near_index)
    arr_near = np.zeros((4,2))
    if point[0] > near_index[0] and point[1]> near_index[1]:
        arr_near[0] = np.array(near_index)
        arr_near[1] = np.array([near_index[0],near_index[1]+1])
        arr_near[2] = np.array([near_index[0]+1,near_index[1]+1])
        arr_near[3] = np.array([near_index[0]+1,near_index[1]])
    elif point[0] < near_index[0] and point[1]> near_index[1]:
        arr_near[0] = np.array([near_index[0],near_index[1]-1])
        arr_near[1] = np.array(near_index)
        arr_near[2] = np.array([near_index[0]+1,near_index[1]])
        arr_near[3] = np.array([near_index[0]+1,near_index[1]-1])
    elif point[0] < near_index[0] and point[1]< near_index[1]:
        arr_near[0] = np.array([near_index[0]-1,near_index[1]-1])
        arr_near[1] = np.array([near_index[0]-1,near_index[1]])
        arr_near[2] = np.array(near_index)
        arr_near[3] = np.array([near_index[0],near_index[1]-1])
    elif point[0] > near_index[0] and point[1]< near_index[1]:
        arr_near[0] = np.array([near_index[0]-1,near_index[1]])
        arr_near[1] = np.array([near_index[0]-1,near_index[1]+1])
        arr_near[2] = np.array([near_index[0],near_index[1]+1])
        arr_near[3] = np.array(near_index)
    print(arr_near)
    arr_point = np.array([array[convert_2d_to_1d(arr_near[0].astype(int))],array[convert_2d_to_1d(arr_near[1].astype(int))],array[convert_2d_to_1d(arr_near[2].astype(int))],array[convert_2d_to_1d(arr_near[3].astype(int))]])
    return near, near_index, arr_near, arr_point

def convert_2d_to_1d(a,n=7):
    return a[0]*n+a[1]

# print(convert_2d_to_1d([3,2]))

def get_line_2point(A,B):
    vector_AB = B - A
    a = 0-vector_AB[1]
    b = vector_AB[0]
    c = -a*A[0] - b*A[1]
    return a,b,c

def check_line(A,B,C):
    a,b,c = get_line_2point(A,B)
    if C[0]*a+C[1]*b+c ==0:
        print("True")
    else:
        print("false")

def check_phuong_vecto(a,b):
    if a[0]/b[0] == a[1]/b[1]:
        print("true")
    else:
        print("false")

def giao_diem(a1,b1,c1,a2,b2,c2):
    y = (c2-(a2*c1/a1))/((a2*b1/a1)-b2)
    x = 0-(c1+b1*y)/a1
    return x,y

# a1,b1,c1=get_line_2point(np.array([0,1]),np.array([2,3]))
# a2,b2,c2=get_line_2point(np.array([0,4]),np.array([2,3]))
# print(giao_diem(a1,b1,c1,a2,b2,c2))

def hinhchieu(C,p1,p2,p3):
    a1,b1,c1 = get_line_2point(p1,p2)
    a2,b2,c2 = get_line_2point(C,p3)

    # print(a2,b2,c2,a1,b1,c1)
    x,y = giao_diem(a1,b1,c1,a2,b2,c2)
    G = np.array([x,y])
    H = C+(p2-p3)*(G-C)/(G-p3)
    return H

def ti_le(a1,a2,a3,n=2.75):
    return distance(a1,a2)/distance(a1,a3)*n
# img2 = cv2.bitwise_and(img2, img2, mask=mask_0)

# path = "D:/Study/Xulyanh/code/data/back.jpg"
# mask, corners = detect_chess_board(path)
# image = cv2.imread(path)
# image = cv2.resize(image,(500,400))
# crop_chess_board = cv2.bitwise_and(image, image, mask=mask)
# for corner in corners:
#         # print(corner[0])
#         coord = (int(corner[0][0]), int(corner[0][1]))
#         # print(coord)
#         cv2.circle(img=crop_chess_board, center=coord, radius=2, color=(255, 0, 0), thickness=2)
# cv2.imshow('mask',crop_chess_board);
# cv2.waitKey(0)


while True:
	entrada = input().split(" ")
	B = int(entrada[0])
	N = int(entrada[1])
	if (B == 0 and N == 0):
		break
	entrada = input().split(" ")
	bolas = [0]*(B+1)
	bolasValidas = [0]*(B+1)
	for i in range(len(entrada)):
		aux = int(entrada[i])
		bolas[aux] = 1
	#print(bolas)
	for i in range(len(bolas)):
		for j in range(len(bolas)-1,i,-1):
			if (bolas[j] == 1 and bolas[i] == 1):
				pos = j - i
				bolasValidas[pos] = 1
	aux = 1
	#print(bolasValidas)
	for i in range(1,len(bolasValidas)):
		if (bolasValidas[i] == 0):
			aux = 0
			break
	if (aux == 1):
		print("Y")
	else:
		print("N")