import re
from copy import deepcopy
from tqdm import tqdm

# split sentences into lines without meta
def get_lines(sent, ans_sent):
    meta_lines = re.search('^(#.*\n)*', sent).group()
    no_meta_sent = sent[len(meta_lines):]
    lines = no_meta_sent.split('\n')
    meta_lines_ans = re.search('^(#.*\n)*', ans_sent).group()
    no_meta_ans_sent = ans_sent[len(meta_lines_ans):]
    ans_lines = no_meta_ans_sent.split('\n')
    return lines, ans_lines, meta_lines

# match predicted token indices to one gold token index
def match_pred_tokens_to_gold(lines, ans_lines):
    ind_matches = {}
    i = 0
    num_of_skipped = 0
    for j in range(len(ans_lines)):
        # если равны, добавляем индекс-сопоставление, идем дальше
        try:
            if ans_lines[j].split('\t')[1] == lines[i].split('\t')[1]:
                ind_matches[ans_lines[j].split('\t')[0]] = [lines[i].split('\t')[0]]
                i += 1
                continue
        except:
            print('\n'.join(ans_lines))
            print('\n'.join(lines))
        # если не равны, но начинается с того же символа или если это [UNK], пропускаем
        # ЧТО ЭТО И ЗАЧЕМ?
        # if not ans_lines[j].split('\t')[1].startswith(lines[i].split('\t')[1]) and lines[i].split('\t')[1] != '[UNK]':
        #     num_of_skipped += 1
        #     print(ans_lines[j], lines[i])
        #     continue
        # в остальных случаях full_token - текущий токен (ответы), откусываем от него длину текущего токена (пред)
        full_token = ans_lines[j].split('\t')[1]
        full_token = full_token[len(lines[i].split('\t')[1]):]
        indices = [lines[i].split('\t')[0]]
        for line in lines[i+1:]:  # идем дальше по (пред) линиям - пока начала совпадают - пропускаем
            # !NEW! Added full_token != ''
            if full_token.startswith(line.split('\t')[1]) or line.split('\t')[1] == '[UNK]' and full_token != '':
                if line.split('\t')[1] != '[UNK]':
                    full_token = full_token[len(line.split('\t')[1]):]
                else:
                    full_token = full_token[1:]  # assumption that [UNK] is always only 1 symbol in length
                i += 1
                indices.append(line.split('\t')[0])
            else:
                break
        ind_matches[ans_lines[j].split('\t')[0]] = indices
        i += 1
    return ind_matches, num_of_skipped

# collect all tokens matched to one original-token in one list and in groups
def get_additional_lists(ind_matches):
    all_misplaced = []
    misplaced_groups = []
    for key, value in ind_matches.items():
        if len(value) > 1:
            all_misplaced.extend(value)
            misplaced_groups.append(value)
    return all_misplaced, misplaced_groups

# create our predict with fixed tokenization (only enh deps will be used from here)
def match_ud_tokenization(lines, all_misplaced, misplaced_groups):
    group_ind = 0
    new_lines = []
    i = 0
    while i < len(lines):
        if str(i+1) in all_misplaced:
            begin = misplaced_groups[group_ind][0]
            end = misplaced_groups[group_ind][-1]
            full_token = ''
            head_candidates = []
            for line in lines[int(begin)-1:int(end)]:
                i += 1
                dep_nums = [dep.split(':')[0] for dep in line.split('\t')[8].split('|')]
                for num in dep_nums:
                    if num not in misplaced_groups[group_ind] and line.split('\t')[8] not in head_candidates:
                        head_candidates.append(line.split('\t')[8])
                full_token += line.split('\t')[1]
            format_line = lines[int(end)-1]
            parts = format_line.split('\t')
            parts[1] = full_token
            parts[2] = full_token
            if len(head_candidates) == 0:
                head_candidates.append('0:X')
                print('no head candidates')
            parts[8] = head_candidates[0]  # simply chooses first candidate - place for improvement
            new_line = '\t'.join(parts)
            new_lines.append(new_line)
            group_ind += 1
        else:
            new_lines.append(lines[i])
            i += 1
    return new_lines

def fix_indices(new_lines):
    fixed_lines = []
    for i in range(len(new_lines)):
        parts = new_lines[i].split('\t')
        parts[0] = str(i+1)
        fixed_lines.append('\t'.join(parts))
    return fixed_lines

# fix head numbers in enh deps
def fix_dep_numbers(fixed_lines, ind_matches, num_of_skipped):
    new_deps_lines = []
    for line in fixed_lines:
        parts = line.split('\t')
        deps = parts[8].split('|')
        new_deps = []
        for dep in deps:
            num = dep.split(':')[0]
            new_num = num  # !!! NEW NUM MUST BE ALWAYS DEFINED - PROBLEM!!!
            if int(num) < 0:
                new_num = '0'
            for orig_ind in ind_matches:
                if num == '0' or int(num) < 1:
                    new_num = '0'
                    break
                if num in ind_matches[orig_ind]:
                    new_num = str(int(orig_ind) - num_of_skipped)
                    break
            new_deps.append(new_num + ':' + ':'.join(dep.split(':')[1:]))
        new_full_dep = '|'.join(list(set(new_deps)))  # SET: if they start to duplicate - collapse into one
        parts[8] = new_full_dep
        new_deps_lines.append('\t'.join(parts))
    return '\n'.join(new_deps_lines)

def match_if_original_shorter(lines, ans_lines):
    new_lines = deepcopy(lines)
    count_added = 0
    ind_matches = {}
    for i in range(len(lines)):
        try:
            if lines[i].split('\t')[1] == ans_lines[i + count_added].split('\t')[1] or lines[i].split('\t')[1] == '[UNK]':
                ind_matches[ans_lines[i + count_added].split('\t')[0]] = [lines[i].split('\t')[0]]
                continue
            if not ans_lines[i + count_added].split('\t')[1].startswith(lines[i].split('\t')[1]):
                j = 0
                for ans_line in ans_lines[i + count_added + 1:]:
                    if ans_line.split('\t')[1] == lines[i].split('\t')[1]:
                        parts = ans_lines[i + count_added +j].split('\t')
                        parts[8] = '0:X'
                        new_lines.insert(i, '\t'.join(parts))
                        count_added += 1
                        ind_matches[ans_lines[i + count_added].split('\t')[0]] = [parts[0]]
                        break
                    j += 1
            else:
                # print(lines)
                print('Something is wrong!')
        except:
            print('\n'.join(lines))
            exit()
    return new_lines, ind_matches

def align_tokenization(ans_sents, sents):
    sents_fixed_tokenization = []
    for i in tqdm(range(len(sents))):
        lines, ans_lines, meta_lines = get_lines(sents[i], ans_sents[i])
        # less in original
        ind_matches, num_skipped = match_pred_tokens_to_gold(lines, ans_lines)
        all_misplaced, misplaced_groups = get_additional_lists(ind_matches)
        new_lines = match_ud_tokenization(lines, all_misplaced, misplaced_groups)
        fixed_lines = fix_indices(new_lines)
        ud_sent = fix_dep_numbers(fixed_lines, ind_matches, num_skipped)
        # more in original
        new_lines, ind_matches = match_if_original_shorter(ud_sent.split('\n'), ans_lines)
        fixed_lines = fix_indices(new_lines)
        ud_sent = fix_dep_numbers(fixed_lines, ind_matches, 0)
        sents_fixed_tokenization.append(meta_lines + ud_sent)
    return sents_fixed_tokenization

def insert_enhanced_in_original(ans_file, predict_file, output_file):
    with open(ans_file, 'r', encoding='utf-8') as f:
        ans_text = f.read()
    with open(predict_file, 'r', encoding='utf-8') as f:
        text = f.read()
    ans_sents = ans_text.split('\n\n')[:-1]
    sents = text.split('\n\n')[:-1]
    new_sents = align_tokenization(ans_sents, sents)
    print('Alignment is done!\nInserting into original...')
    ans_with_pred_deps = []
    for i in tqdm(range(len(new_sents))):
        lines, ans_lines, meta = get_lines(new_sents[i], ans_sents[i])
        if len(lines) != len(ans_lines):
            print('Tokenization align error!')
        for j in range(len(lines)):
            parts = ans_lines[j].split('\t')
            parts[8] = lines[j].split('\t')[8]
            ans_lines[j] = '\t'.join(parts)
        ans_with_pred_deps.append(meta + '\n'.join(ans_lines))
    with open(output_file, 'w', encoding='utf-8') as f:
        f.write('\n\n'.join(ans_with_pred_deps) + '\n\n')


import random

# Read the list of common English words from the "word_list.txt" file
with open('100k-word_list.txt', 'r') as file:
    common_words = [line.strip() for line in file]

# Shuffle the list of common words to ensure randomness
random.shuffle(common_words)

# Generate a number of lines
num_lines = 100000

# Create and open the output file
with open('generated-txt.txt', 'w') as file:
    for _ in range(num_lines):
        # Ensure that we don't run out of words by looping through the list
        if not common_words:
            random.shuffle(common_words)  # Shuffle the list again if we've used all the words
        # Choose a word from the list (and remove it to avoid duplicates)
        word = common_words.pop()
        # Generate a random number between 1000 and 1000000
        number = random.randint(1000, 1000000)
        # Write the word and number to the file
        file.write(f"{word}  {number}\n")


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

import math
import torch
from torch import nn
import torch.nn.functional as F
import torchvision.models as models

from .network_utils import *

class StateEncoderShallowCNN(torch.nn.Module):
    """
    state encoder (shallow CNN)
    """
    def __init__(self, output_dim, drop):
        super(StateEncoderShallowCNN, self).__init__()
        self.output_dim = output_dim

        self.conv1 = nn.Conv2d(3, 32, 8, stride=4)
        self.bn1 = nn.BatchNorm2d(32)
        self.conv2 = nn.Conv2d(32, 64, 4, stride=2)
        self.bn2 = nn.BatchNorm2d(64)
        self.conv3 = nn.Conv2d(64, 64, 3, stride=1)
        self.bn3 = nn.BatchNorm2d(64)
        self.fc = nn.Linear(64 * 7 * 7, output_dim)
        self.drop = drop
        self.apply(weights_init)

    def forward(self, state):
        x = F.relu(self.bn1(self.conv1(state)))
        x = F.relu(self.bn2(self.conv2(x)))
        x = F.relu(self.bn3(self.conv3(x)))
        x = x.view(-1, 64 * 7 * 7)
        x = F.relu(F.dropout(self.fc(x), p=self.drop))
        return x

class StateEncoderResNet(torch.nn.Module):
    def __init__(self, output_dim, drop):
        super(StateEncoderResNet, self).__init__()
        self.output_dim = output_dim
        self.backbone = models.resnet50(pretrained=True)
        for param in self.backbone.parameters():
            param.requires_grad = True
        # self.conv1 = nn.Conv2d(3, 32, 8, stride=4)
        # self.bn1 = nn.BatchNorm2d(32)
        # self.conv2 = nn.Conv2d(32, 64, 4, stride=2)
        # self.bn2 = nn.BatchNorm2d(64)
        # self.conv3 = nn.Conv2d(64, 64, 3, stride=1)
        # self.bn3 = nn.BatchNorm2d(64)
        self.fc = nn.Linear(1000, output_dim)
        self.drop = drop
        self.apply(weights_init)

    def forward(self, x):
        x = self.backbone(x)
        # x = F.relu(self.bn1(self.conv1(x)))
        # x = F.relu(self.bn2(self.conv2(x)))
        # x = F.relu(self.bn3(self.conv3(x)))
        # x = x.view(-1, 64 * 7 * 7)
        x = F.dropout(F.relu(self.fc(x)), p=self.drop)
        return x


import streamlit as st

from torchtyping import TensorType as TT
from transformer_lens.hook_points import HookPoint
from .environment import get_action_preds
from .visualizations import plot_action_preds, plot_single_residual_stream_contributions, plot_single_residual_stream_contributions_comparison
from .analysis import get_residual_decomp

def show_ablation(dt, logit_dir, original_cache):

    with st.expander("Ablation Experiment"):
        st.write("ablation experiment here")
        # list out the components of the transformer

        # make a streamlit form for choosing a component to ablate
        n_layers = dt.n_layers
        n_heads = dt.n_heads

        columns = st.columns(4)
        with columns[0]:
            layer = st.selectbox("Layer", list(range(n_layers)))
        with columns[1]:
            component = st.selectbox("Component", ["MLP", "HEAD"], index=1)
        with columns[2]:
            if component == "HEAD":
                head = st.selectbox("Head", list(range(n_heads)))
        with columns[3]:
            ablate_to_mean = st.checkbox("Ablate to mean", value=True)

        if component == "HEAD":
            ablation_func = get_ablation_function(ablate_to_mean, head)
            dt.transformer.blocks[layer].attn.hook_z.add_hook(ablation_func)
        elif component == "MLP":
            ablation_func = get_ablation_function(
                ablate_to_mean, layer, component="MLP")
            dt.transformer.blocks[layer].hook_mlp_out.add_hook(ablation_func)

        action_preds, x, cache, tokens = get_action_preds(dt)

        if st.checkbox("show action predictions"):
            plot_action_preds(action_preds)
        if st.checkbox("show counterfactual residual contributions"):
            original_residual_decomp = get_residual_decomp(
                dt, original_cache, logit_dir)
            ablation_residual_decomp = get_residual_decomp(
                dt, cache, logit_dir)
            plot_single_residual_stream_contributions_comparison(
                original_residual_decomp, ablation_residual_decomp)

    # then, render a single residual stream contribution with the ablation

def get_ablation_function(ablate_to_mean, head_to_ablate, component="HEAD"):

    def head_ablation_hook(
        value: TT["batch", "pos", "head_index", "d_head"],  # noqa: F821
        hook: HookPoint
    ) -> TT["batch", "pos", "head_index", "d_head"]:  # noqa: F821
        print(f"Shape of the value tensor: {value.shape}")

        if ablate_to_mean:
            value[:, :, head_to_ablate, :] = value[:, :,
                                                   head_to_ablate, :].mean(dim=2, keepdim=True)
        else:
            value[:, :, head_to_ablate, :] = 0.
        return value

    def mlp_ablation_hook(
        value: TT["batch", "pos", "d_model"],  # noqa: F821
        hook: HookPoint
    ) -> TT["batch", "pos", "d_model"]:  # noqa: F821
        print(f"Shape of the value tensor: {value.shape}")

        if ablate_to_mean:
            value[:, :-1, :] = value[:, :-1, :].mean(dim=2, keepdim=True)
        else:
            value[:, :-1, :] = 0  # ablate all but the last token
        return value

    if component == "HEAD":
        return head_ablation_hook
    elif component == "MLP":
        return mlp_ablation_hook


from skimage import io
import numpy as np

im1 = io.imread('1.pgm')
im2 = io.imread('2.pgm')

x = np.array(im1)
y = np.array(im2)
z = abs(x/100 - y/100)
z = z*100
SAD = np.sum(z)
SSD = np.sum(z**2)
print(SAD, SSD)


from sympy import Matrix
from sympy.solvers import solve
from fractions import Fraction
from Molecules import Molecule
import math
import re

# modos: redox(ácido y básico), ácido-base, desplazamiento, dismutación
# cuando falta algo de algún lado?
# cargas?
# si hay más de una opción? cómo elegir

class Reaction:

    def __init__(self, reacts, prods, mode=1):
        self.reacts = reacts
        self.prods = prods
        self.mode = mode
        self.neto = 0           # agregar o no e-

    def starter(self):
        atoms = []
        charges = []

        info_r = {}

        for elem in self.reacts:
            molecule = Molecule(elem)
            molecule.get_symbol()
            charges.append(molecule.charge)
            atoms += molecule.get_elements()
            info_r[elem] = dict(zip(molecule.get_elements(), molecule.get_indexes()))

        info_p = {}

        for elem in self.prods:
            molecule = Molecule(elem)
            molecule.get_symbol()
            charges.append(molecule.charge)
            atoms += molecule.get_elements()
            info_p[elem] = dict(zip(molecule.get_elements(), molecule.get_indexes()))

        return (info_r, info_p), list(set(atoms)), charges

    def fix_charges(self, charges):
        my_charges = []
        for cha in charges:
            if type(cha) is str:
                x = re.split("(?<=\d)(?=\D)|(?<=\D)(?=\d)", cha)
                if len(x) == 1:
                    x.insert(0, "1")
                if not x[0].isnumeric():
                    x[0], x[1] = x[1], x[0]
                if x[1] == "+":
                    my_charges.append(int(x[0]))
                else:
                    my_charges.append(-int(x[0]))

            else:
                my_charges.append(0)

        return my_charges

    def set_matrix(self):
        columns = []
        info, atoms, charges = self.starter()
        new_charges = self.fix_charges(charges)
        for side in info:
            for molec in side:
                v = []
                for atom in atoms:
                    v.append(int(side[molec].get(atom, 0)))
                columns.append(Matrix(v))

        return Matrix.hstack(*columns), atoms, new_charges

    def get_coeffs(self):
        mat, atoms, charges = self.set_matrix()
        zeros = Matrix.zeros(len(atoms), 1)
        first, taus = mat.gauss_jordan_solve(zeros)
        dot_p = first.dot(Matrix(charges))
        unos = dict.fromkeys(taus[:-1], 1)
        try:
            ultimo = solve(dot_p.subs(unos))[0]
        except IndexError:
            ultimo = 0

        if self.mode == 2 or ultimo <= 0:
            intento = first.subs(dict.fromkeys(taus, 1)).tolist()
            self.neto = Matrix(charges).dot(Matrix(intento))
            return [float(abs(e[0])) for e in intento]

        unos[taus[-1]] = ultimo
        s = first.subs(unos).tolist()
        s_joined = [float(abs(e[0])) for e in s]
        return s_joined

    def normalizer(self):
        coffs = self.get_coeffs()
        denoms = [Fraction(x).limit_denominator().denominator for x in coffs]

        for d in denoms:
            coffs = [d*values for values in coffs]
            self.neto = self.neto*d
        coffs = [int(f) for f in coffs]
        gcd = math.gcd(*coffs)
        if gcd == 0:
            gcd = 1
        coffs = [int(e/gcd) for e in coffs]

        self.neto = int(self.neto/gcd)

        return coffs

class Balanced(Reaction):

    def __init__(self, reacts, prods, mode=1):
        super().__init__(reacts, prods, mode)

    def reaction_printer(self):
        coefficients = self.normalizer()
        s = ""
        for i in range(len(self.reacts)):
            m = Molecule(self.reacts[i])
            s += str(coefficients.pop(0)) + " " + m.get_symbol()
            if i != len(self.reacts) - 1:
                s += " + "

        # s += str(self.neto)
        if self.neto < 0:
            s += " + " + str(abs(self.neto)) + " e-"

        s += " → "

        for j in range(len(self.prods)):
            m = Molecule(self.prods[j])
            s += str(coefficients.pop(0)) + " " + m.get_symbol()
            if j != len(self.prods) - 1:
                s += " + "

        if self.neto > 0:
            s += " + " + str(self.neto) + " e-"

        # s += self.molar_mass_printer()
        return s, self.molar_mass_printer()

    def molar_mass_printer(self):
        s = []
        # s += "

Masas molares:
"
        for molecule in set(self.reacts + self.prods):
            m = Molecule(molecule)
            s.append(m.get_symbol() + " → " + str(m.get_molar_mass()))
        return s


import os
import cv2
import tensorflow as tf
import numpy as np
from DataGenerator import ImageDataGenerator
from DHN import *

batch_size = 100
hash_K = 48
checkpoint_path = os.path.join(os.getcwd(), "tmp\\dhn")

def toBinaryString(binary_like_values):
    numOfImage, bit_length = binary_like_values.shape
    list_string_binary = []
    for i in range(numOfImage):
        str = ''
        for j in range(bit_length):
            str += '0' if binary_like_values[i][j] <= 0 else '1'
        list_string_binary.append(str)
    return list_string_binary

def toString(binary_like_values):
    numOfImage, bit_length = binary_like_values.shape
    list_string_binary = []
    for i in range(numOfImage):
        st = ''
        for j in range(bit_length):
            st += str(binary_like_values[i][j]) + ' '
        list_string_binary.append(st)
    return list_string_binary

def get_hanming(binarystr1, binarystr2):
    L = len(binarystr1)
    dis = 0
    #print(len(binarystr1))
    #print(len(binarystr2))
    for i in range(L):
        if binarystr1[i] != binarystr2[i]:
            dis += 1
    return dis

def get_manhattan(originfeature1, originfeature2):
    if (len(originfeature1) != len(originfeature2)):
        print("Differnet Dimensions!")
        return
    dis = 0
    for i in range(len(originfeature1)):
        dis += abs(originfeature1[i]-originfeature2[i])
    return dis

def file_read(path):
    file_in = open(path, 'r')
    lines = file_in.read()
    ls = lines.split('\n')
    names = []
    features = []
    origin_features = []
    for line in ls:
        tmp = line.split('\t')
        if len(line) < 3: continue
        # print(tmp)
        temp = tmp[0].split(' ')
        ori = []
        for digstr in temp:
            if len(digstr) == 0: continue
            ori.append((float)(digstr))
        origin_features.append(ori)
        # print(origin_features[-1])
        # print(len(origin_features[-1]))
        features.append(tmp[1])
        names.append(tmp[2])
    return names, features, origin_features

def getSecond(x):
    return x[1]

def test_accuracy_dhn(names, features, originfeature):
    tot = 0
    less10 = 0
    for i in range(len(features)):
        cnt = 0
        acc = 0
        index_tmp = []
        print(i)
        for j in range(len(features)):
            #if (get_manhattan(originfeature[i], originfeature[j]) < 50.):
            index_tmp.append( (j, get_manhattan(originfeature[i], originfeature[j]), get_hanming(features[i], features[j])) )

        # print(len(index))

        index_tmp.sort(key=getSecond)
        index = []
        for j in range(len(index_tmp)):
            if j >= 100: break
            index.append( (index_tmp[j][0], index_tmp[j][2]) )
        index.sort(key=getSecond)

        for j in range(len(index)):
            if j >= 10: break
            cnt += 1
            # print(names[index[j][0]])
            if (names[index[j][0]].split('_')[0] == names[i].split('_')[0]):
                acc += 1
        if (cnt < 10):
            less10 += 1
        tot += (float)(acc/cnt)
        print((float)(acc/cnt))
    print(tot/len(features))
    print(less10)

def getHash(path):
    x = tf.placeholder(tf.float32, [batch_size, 227, 227, 3], name='x')
    model = DeepHashingNet(x, 1, hash_K, [])
    fch = model.fch
    print("Reading checkpoints...")
    ckpt = tf.train.get_checkpoint_state(checkpoint_path)
    saver = tf.train.Saver(tf.all_variables())

    sess = tf.InteractiveSession()

    query_generator = ImageDataGenerator(path,
                                         horizontal_flip=False, shuffle=False)

    file_res = open('query_dhn.txt', 'w')
    # sys.stdout = file_res
    if ckpt and ckpt.model_checkpoint_path:
        ckpt_name = os.path.basename(ckpt.model_checkpoint_path)
        print(ckpt_name)
        global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]
        saver.restore(sess, os.path.join(checkpoint_path, ckpt_name))
        print('Loading success, global_step is %s' % global_step)

        k = 0
        for i in range(query_generator.dataSize // batch_size):
            print(str(i) + "th batch in " + str(query_generator.dataSize // batch_size))
            images, label = query_generator.next_batch(batch_size)
            eval_sess = sess.run(fch, feed_dict={x: images})
            # print(eval_sess)
            w_res = toBinaryString(eval_sess)
            wzy = toString(eval_sess)

            for j in range(batch_size):
                file_res.write(wzy[j] + '\t' + w_res[j] + '\t' + str(query_generator .images[k]) + '\n')
                k+=1

    file_res.close()
    sess.close()

def showimage(name, showname = 'wzy'):
    if os.path.exists(os.path.join('./data/test', name)):
        img = cv2.imread(os.path.join('./data/test', name))
    elif os.path.exists(os.path.join('./data/train', name)):
        img = cv2.imread(os.path.join('./data/train', name))
    elif os.path.exists(os.path.join('./data/query', name)):
        img = cv2.imread(os.path.join('./data/query', name))
    cv2.imshow(showname, img)
    cv2.waitKey()

def query_dhn(names_dataset, features_dataset, originfeature_dataset, names_query, features_query, originfeature_query):
    file_out = open("answer_dhn.txt", "w")
    for i in range(2):
        index_tmp = []
        print(i)
        showimage(names_query[i], str(i))
        for j in range(len(features_dataset)):
            index_tmp.append( (j, get_manhattan(originfeature_query[i], originfeature_dataset[j]), get_hanming(features_query[i], features_dataset[j])) )

        index_tmp.sort(key=getSecond)
        index = []
        for j in range(len(index_tmp)):
            if j >= 100: break
            index.append( (index_tmp[j][0], index_tmp[j][2]) )
        index.sort(key=getSecond)

        file_out.write(names_query[i] + ':')
        index.sort(key=getSecond)
        for j in range(len(features_dataset)):
            if j >= 10: continue
            showimage(names_dataset[index[j][0]], str(i)+" "+str(j))
            file_out.write(" " + names_dataset[index[j][0]])
        file_out.write("\n")
    file_out.close()

names_dhn, features_dhn, origin_features  = file_read(r"C:\Users\ycdfw\Desktop\DHN_0.1\result_dhn.txt")
#getHash("data/query")
names_query_dhn, features_query_dhn, origin_features_query = file_read(r"C:\Users\ycdfw\Desktop\DHN_0.1\query_dhn.txt")
#test_accuracy_dhn(names_dhn, features_dhn, origin_features)
query_dhn(names_dhn, features_dhn, origin_features, names_query_dhn, features_query_dhn, origin_features_query)


import json
import os

file_path = os.path.join('bananafashion/input_data/womendata.json')
with open(file_path) as f:
    women_new_arrival = json.load(f)

file_path = os.path.join('bananafashion/input_data/homedata.json')
with open(file_path) as f:
    home = json.load(f)

file_path = os.path.join('bananafashion/input_data/workwear.json')
with open(file_path) as f:
    workwear = json.load(f)
#print(women_new_arrival)

# k = data['productCategoryFacetedSearch']['productCategory']['childCategories'][0]['childProducts']
# items = []
# for item in k:
#     items.append(item['businessCatalogItemId'])
# #print(items)

# k2 =  data['productCategoryFacetedSearch']['productCategory']['childCategories'][0]['childProducts']
# items_2  = []
# for item in k2:
#     items_2.append(item['parentStyleId'])
# #print(items_2)


import os
import sys
__dirname = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.join(__dirname, '../api'))
from _init_ import _init_

class LibScootersOwners(object):
    def __init__(self):
        self.init = _init_()

    def scooters_owners_get(self, request_data_type=None, owner_ids= None, scooter_ids=None, scooter_plates=None,
                            scooter_vins=None, scooter_guids=None, scooter_vin_for_transfer=None,
                            scooter_plate_for_transfer=None, profile_id_for_transfer=None, account=None, offset=None, limit=None):
        """ get scooter's owner

        Examples:
        | ${resp} = | Scooters Owners Get | data |
        """
        self.init.authHeader(account)
        data = {
            "op_code": "get",
            "get_data":  {
                    "request_data_type": request_data_type,
                    "owner_ids": owner_ids,
                    "scooter_ids": scooter_ids,
                    "scooter_plates": scooter_plates,
                    "scooter_vins": scooter_vins,
                    "scooter_guids": scooter_guids,
                    "scooter_vin_for_transfer": scooter_vin_for_transfer,
                    "scooter_plate_for_transfer": scooter_plate_for_transfer,
                    "profile_id_for_transfer": profile_id_for_transfer,
                    "pagination_criteria": {
                        "offset": offset,
                        "limit": limit
                }
            }
        }

        resp = self.init.request('post', "/scooters/owners", json=data)
        return resp


from framework.framework_request import GetRequests, PostRequest
from quopri import decodestring
from patterns.creational_patterns import Logger

logger = Logger('main')

def not_found_404_view(request):
    return '404 WHAT', '404 Page Not Found'

class Application:
    def __init__(self, routes, fronts):
        """
        :param routes: dict whis all end-points and hendlers
        :param fronts: all middleware
        """
        print('Server run .....')
        self.routes = routes
        self.fronts = fronts

    def __call__(self, environ, start_response):
        """
        :param environ: словарь от сервера
        :param start_response: функция для ответа серверу
        """

        # получаем адрес по которому выполнен запрос
        path = environ["PATH_INFO"]

        # если нет закрывающего слеша дополняем его сами
        if not path.endswith('/'):
            path = f'{path}/'
        request = {}
        method = environ['REQUEST_METHOD']
        request['method'] = method
        if method == 'POST':
            data = PostRequest().get_request_params(environ)
            request['data'] = Application.decode_value(data)
            if request['data']:
                print(f'Нам пришёл post-запрос: {request["data"]}')
        if method == 'GET':
            request_params = GetRequests().get_request_params(environ)
            request['request_params'] = Application.decode_value(request_params)
            if request['request_params']:
                print(f'Нам пришли GET-параметры:'
                      f' {request["request_params"]}')

        if path in self.routes:
            view = self.routes[path]
        else:
            view = not_found_404_view

        # передний контроллер, он добавляет все данные по запросу из промежуточного ПО
        # наполняем его, всеми данными
        # паттерн front controller
        for front in self.fronts:
            front(request)
        code, body = view(request)
        # функция которую получаем от wsgiref при вызове нашего класса
        start_response(code, [('Content-type', 'text/html')])
        return [body.encode('utf-8')]

    @staticmethod
    def decode_value(data):
        new_data = {}
        for k, v in data.items():
            val = bytes(v.replace('%', '=').replace("+", " "), 'UTF-8')
            val_decode_str = decodestring(val).decode('UTF-8')
            new_data[k] = val_decode_str
        return new_data


"""
This file has both training and testing for the network.
"""

from perceptron import Perceptron
from mnist import MNIST
import random
import activation

num_inputs = 784

hiddenlayer1_size = 40
hiddenlayer2_size = 40

num_outputs = 10

batch_size = 100

class Network:

    def __init__(self, is_leaky_relu: bool = False, leakage_coeff: float = 0.2):
        self._relu = activation.ReLU(is_leaky=is_leaky_relu, leakage=leakage_coeff if is_leaky_relu else 0)
        self._sigmoid = activation.Sigmoid()
        self._identity = activation.Identity()

        self._network = [
                            [Perceptron(num_inputs, self._relu) for _ in range(hiddenlayer1_size)],
                            [Perceptron(hiddenlayer1_size, self._relu) for _ in range(hiddenlayer2_size)],
                            [Perceptron(hiddenlayer2_size, self._sigmoid) for _ in range(num_outputs)]
                        ]
        self._mn_data = MNIST('./images')
        self._desired_changes = None
        self._layer_inputs = None

    def feed_forward(self, inputs: [float]) -> [float]:
        """

        Parameters
        ----------
        inputs: a list of length 784 representing the activation levels of each pixel.

        Returns
        -------
        A list of length 10 with activation values corresponding to digits.

        """
        self._layer_inputs = []
        result_after_layer = inputs
        for layer in self._network:
            # print(result_after_layer)
            self._layer_inputs.append(result_after_layer)
            result_after_layer = [perceptron.evaluate(result_after_layer) for perceptron in layer]
        self._layer_inputs.append(result_after_layer)
        return result_after_layer

    def train(self, num_epochs: int):
        """
        Uses stochastic gradient descent to train this network.
        """
        learn_rate = 0.02

        images, labels = self._mn_data.load_training()
        indices = [i for i in range(len(images))]

        for epoch in range(num_epochs):
            random.shuffle(indices)  # Avoids modifying the actual lists
            epoch_cost = 0
            i = 0

            # Go through the training data in batches
            while i < len(indices):
                print(i, "---------------------------------------------------------")

                if i >= 800:
                    break

                start = i
                end = i + batch_size
                batch_indices = indices[start:end]

                dw = [[[0 for _ in range(perceptron.size_w())] for perceptron in layer] for layer in self._network]
                db = [[0 for _ in layer] for layer in self._network]

                # Take a single image from the batch
                for index in batch_indices:
                    # print("ex")
                    result = self.feed_forward(images[index])
                    epoch_cost += self.cost(result, labels[index])  # Creates self._desired_changes

                    # Backpropagate starting from the last (output) layer
                    for j in range(len(self._network)-1, -1, -1):
                        layer = self._network[j]
                        prev_act_values = self._layer_inputs[j]
                        function_name = layer[0].get_activation().name()

                        if j > 0:
                            next_desired_changes = [0.0 for _ in self._network[j-1]]
                        else:
                            next_desired_changes = None

                        if function_name == "relu":
                            leakage = self._relu.get_leakage()

                        # Look at each perceptron
                        for k in range(len(layer)):
                            perceptron = layer[k]
                            dc_da = self._desired_changes[k]

                            if function_name == "sigmoid":
                                dc_da *= self._sigmoid(perceptron.z) * (1 - self._sigmoid(perceptron.z))
                                # print(perceptron.z, sig_delta)
                                # print(dc_da)
                                db[j][k] -= dc_da * learn_rate

                                # For each weight
                                for l in range(len(perceptron.weights)):
                                    dw[j][k][l] -= dc_da * prev_act_values[l] * learn_rate

                                    if next_desired_changes:
                                        next_desired_changes[l] += dc_da * perceptron.weights[l]

                            elif function_name == "relu":
                                dc_da *= leakage if perceptron.z < 0 else 1
                                db[j][k] -= dc_da * learn_rate

                                # For each weight
                                for l in range(len(perceptron.weights)):
                                    dw[j][k][l] -= dc_da * prev_act_values[l] * learn_rate

                                    if next_desired_changes:
                                        next_desired_changes[l] += dc_da * perceptron.weights[l]

                            # print("dcda", dc_da)

                        if next_desired_changes:
                            # print("nd", next_desired_changes)
                            self._desired_changes = next_desired_changes

                    # End of sample image loop
                    # print(dw[1:])
                    # break

                # Update weights and biases
                for j in range(len(self._network)):
                    layer = self._network[j]

                    for k in range(len(layer)):
                        perceptron = layer[k]

                        perceptron.change_weights_and_bias(dw[j][k], db[j][k])

                # print(dw[1:])
                # print(db)

                i += batch_size

            print("Epoch {} completed out of {} with loss {}".format(epoch + 1, num_epochs, epoch_cost))

    def test(self, num_to_test) -> float:
        test_images, test_labels = self._mn_data.load_testing()
        total = min(num_to_test, len(test_images))
        num_correct = 0
        for i in range(min(num_to_test, len(test_images))):
            if i%100 == 0:
                print(i)
            l = self.feed_forward(test_images[i])
            if Network.one_hot_to_digit(l) == test_labels[i]:
                num_correct += 1

        return num_correct / total

    def cost(self, result: [float], label: int) -> float:
        """
        A simple cost function.
        """
        desired_outputs = Network.digit_to_one_hot(label)
        self._desired_changes = [result[i] - desired_outputs[i] for i in range(num_outputs)]
        return sum((result[i] - desired_outputs[i]) ** 2 for i in range(num_outputs))

    def show_network(self):
        if not self._relu.is_leaky():
            print("Network uses a ReLU activation function")
        else:
            print("Network uses a Leaky ReLU activation function with coefficient {}".format(self._relu.get_leakage()))
        print()
        for i in range(len(self._network)):
            print("Layer {}\n".format(i+1))
            for perceptron in self._network[i]:
                perceptron.show_values("\t")
            print()
        print("End display\n")

    @staticmethod
    def digit_to_one_hot(v: int):
        if v < 0 or v > 9:
            raise ValueError("Argument must be a single digit")
        l = [(1 if i == v else 0) for i in range(10)]

        return l

    @staticmethod
    def one_hot_to_digit(l: [float]):
        if len(l) == 0:
            raise ValueError("List is empty")
        max_index = 0
        max_value = l[0]
        for i in range(len(l)):
            if l[i] > max_value:
                max_value = l[i]
                max_index = i

        return max_index

    @staticmethod
    def normalize_input(inputs: [float]) -> [float]:
        """
        Linearly compresses the list "inputs" into the range [0, 1].

        Parameters
        ----------
        inputs: A list of data

        Returns
        -------
        The list, normalized between 0 and 1.
        """

    @staticmethod
    def MNIST_normalize_input(inputs: [int]) -> [float]:
        """
        A simplified version of the above function for the MNIST dataset.

        Parameters
        ----------
        inputs

        Returns
        -------

        """
        return [i/256 for i in inputs]  # simple for MNIST

# print(_cost([0, 500, 0, 0, 0, 0, 0, 1000, 0, 0], 6))


import numpy as np
from emclaw.utils.materials import Material3D
from emclaw.utils.sources import Source3D
from emclaw.utils import basics

x_lower = 0.0
x_upper = 10.0

y_lower = 0.0
y_upper = 5.0

z_lower = 0.0
z_upper = 5.0

sy = y_upper-y_lower
sx = x_upper-x_lower
sz = z_upper-z_lower

mid_point_y = (y_upper-y_lower)/2.0
mid_point_z = (z_upper-z_lower)/2.0

material = Material3D(shape='homogeneous',metal=False)
material.setup()
material._calculate_n()

source = Source3D(material,shape='off',wavelength=2.0)
source.offset[0] = 5.0
source.transversal_shape = 'plane'
source.heading = 'x'
source.setup()
source.transversal_offset = [sy/2.0,sz/2.0]
source.transversal_width  = [sy/2.0,sz/2.0]

def em3D(mx=64, my=64, mz=64, num_frames=10, cfl=1.0, outdir='./_output', before_step=False, debug=False, nl=False, psi=True):
    import clawpack.petclaw as pyclaw
    import petsc4py.PETSc as MPI

    if np.logical_and(debug, MPI.COMM_WORLD.rank==0):
        material.dump()
        source.dump()

    num_eqn   = 6
    num_waves = 4
    num_aux   = 12

#   grid pre calculations and domain setup
    _, _, _, dt,tf = basics.grid_basic([[x_lower,x_upper,mx], [y_lower,y_upper,my], [z_lower,z_upper,mz]], cfl = cfl, co = material.co, v = source.v)

    x = pyclaw.Dimension(x_lower,x_upper,mx, name = 'x',)
    y = pyclaw.Dimension(y_lower,y_upper,my, name = 'y',)
    z = pyclaw.Dimension(z_lower,z_upper,mz, name = 'z',)

    domain = pyclaw.Domain([x, y, z])

#   Solver settings
    solver = pyclaw.SharpClawSolver3D()
    solver.num_waves  = num_waves
    solver.num_eqn    = num_eqn
    solver.lim_type = 2

    solver.dt_variable = True
    solver.dt_initial  = dt/2.0
    solver.dt_max      = dt
    solver.max_steps   = int(2*tf/dt)

#   Import Riemann and Tfluct solvers
    from emclaw.riemann import maxwell_3d_nc_rp as maxwell_3d_rp
    from emclaw.riemann import maxwell_3d_nc_tfluct as maxwell_3d_tfluct

    solver.tfluct_solver = True
    solver.fwave = True

    solver.rp = maxwell_3d_rp
    solver.tfluct = maxwell_3d_tfluct

    solver.cfl_max = cfl+0.5
    solver.cfl_desired = cfl
    solver.reflect_index = [1,0,5]

#   boundary conditions
    solver.bc_lower[0] = pyclaw.BC.wall
    solver.bc_lower[1] = pyclaw.BC.wall
    solver.bc_lower[2] = pyclaw.BC.wall
    solver.bc_upper[0] = pyclaw.BC.wall
    solver.bc_upper[1] = pyclaw.BC.wall
    solver.bc_upper[2] = pyclaw.BC.wall

    solver.aux_bc_lower[0]= pyclaw.BC.wall
    solver.aux_bc_lower[1]= pyclaw.BC.wall
    solver.aux_bc_lower[2]= pyclaw.BC.wall
    solver.aux_bc_upper[0]= pyclaw.BC.wall
    solver.aux_bc_upper[1]= pyclaw.BC.wall
    solver.aux_bc_upper[2]= pyclaw.BC.wall

#   before step configure
    if before_step:
            solver.call_before_step_each_stage = True
            solver.before_step = material.update_aux

#   state setup
    state = pyclaw.State(domain,num_eqn,num_aux)

    state.problem_data['chi2']  = material.chi2
    state.problem_data['chi3']  = material.chi3
    state.problem_data['co'] = material.co
    state.problem_data['zo'] = material.zo
    state.problem_data['eo'] = material.eo
    state.problem_data['mo'] = material.mo
    state.problem_data['dx'] = state.grid.x.delta
    state.problem_data['dy'] = state.grid.y.delta
    state.problem_data['dz'] = state.grid.z.delta
    state.problem_data['nl']     = nl
    state.problem_data['psi']    = psi

    source._delta[0] = state.grid.x.delta
    source._delta[1] = state.grid.y.delta
    source._delta[2] = state.grid.z.delta

#   array initialization
    source.init(state)
    material.init(state)

#   controller
    claw = pyclaw.Controller()
    claw.tfinal = tf
    claw.num_output_times = num_frames
    claw.solver = solver
    claw.solution = pyclaw.Solution(state,domain)
    claw.outdir = outdir
    claw.write_aux_always = True

    return claw

if __name__=="__main__":
    from clawpack.pyclaw.util import run_app_from_main
    output = run_app_from_main(em3D)

    import os
    os.system("python ../../emclaw/utils/visualization.py /home/$USER/emclaw/examples/maxwell_vc_3d/_output")


def sto():
    while type:
        a = input('Введите число: ')
        try:
            b = int(a)
        except ValueError:
            print('"' + a + '"' + ' - не является числом')
        else:
            try:
                k=100/int(a)
            except ZeroDivisionError:
                print('На ноль делить не стоит')
            else:
                k = 100 / int(a)
                print('100/', a, "=", k)
                break

print(sto())


# Nengo Example: Inhibitory Gating of Ensembles

# ## Step 1: Create the network
#
# Our model consists of two ensembles (called A and B) that receive inputs from
# a common sine wave signal generator.
#
# Ensemble A is gated using the output of a node, while Ensemble B is gated
# using the output of a third ensemble (C). This is to demonstrate that
# ensembles can be gated using either node outputs, or decoded outputs from
# ensembles.

import nengo

model = nengo.Network()
with model:
    a = nengo.Ensemble(n_neurons=30, dimensions=1)
    b = nengo.Ensemble(n_neurons=30, dimensions=1)
    c = nengo.Ensemble(n_neurons=30, dimensions=1)

    stim = nengo.Node(0)
    inhibition = nengo.Node(0)

    nengo.Connection(stim, a)
    nengo.Connection(stim, b)
    nengo.Connection(inhibition, a.neurons, transform=[[-2.5]] * 30)
    nengo.Connection(inhibition, c)
    nengo.Connection(c, b.neurons, transform=[[-2.5]] * 30)


import os
import sys
import cv2

def images2vedio(in_dir, out_dir, out_name, fps=2):
  im_names = os.listdir(in_dir)
  im_names.sort()
  im_paths = [in_dir + im_name.strip() for im_name in im_names]

  out_path = out_dir + out_name
  # error: 'module' object has no attribute VideoWriter_fourcc
  # fourcc = cv2.VideoWriter_fourcc(*'avi')	# error
  fourcc = cv2.cv.CV_FOURCC(*'XVID')
  out = cv2.VideoWriter(out_path, fourcc, fps, (640,480))

  for im_path in im_paths:
  	im = cv2.imread(im_path)
  	out.write(im)
  	if (cv2.waitKey(1) & 0xFF) == ord('q'):
  		break
  out.release()

if __name__ == '__main__':

	in_dir = "/home/ddk/malong/dataset/person.torso/demo/vision/mude.images.pose1/"
	out_name = "demo.avi"
	out_dir = "/home/ddk/malong/dataset/person.torso/demo/vision/mude.images.pose1/"

	images2vedio(in_dir, out_dir, out_name)


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

import matplotlib.pyplot as plt
import os.path
import os
import argparse
import json

parser = argparse.ArgumentParser(description='Train report build')
parser.add_argument('-a', '--history', help='History file name',default=None)
args = parser.parse_args()

history_list = []
model_cont = 1

def search_history(*args):
    print()
    for item in args:
        for p, _, files in os.walk(os.path.abspath(item)):
            for file in files:
                if(file == 'train_history.json'):
                    with open(os.path.join(p, file), 'r') as fp:
                        train_history = {
                            "history" : json.load(fp),
                            "label" : str(p)
                        }

                        history_list.append(train_history)

def smooth(scalars, weight):
    last = scalars[0]
    smoothed = list()
    for point in scalars:
        smoothed_val = last * weight + (1 - weight) * point
        smoothed.append(smoothed_val)
        last = smoothed_val

    return smoothed

search_history("/home/luismalta/Projects/DeepRL/logs/Dueling_DQN")

# with open('/home/luismalta/Projects/DeepRL/logs/Dueling_DQN/log_01-06-2019_22:28/train_history.json') as fp:
#     train_history = {
#         "history" : json.load(fp),
#         "label" : 'DUELING DQN MODELO 7'
#     }
#     history_list.append(train_history)
#
# with open('/home/luismalta/Projects/DeepRL/logs/Dueling_DQN/log_04-07-2019_00:51/train_history.json') as fp:
#     train_history = {
#         "history" : json.load(fp),
#         "label" : 'DUELING DQN MODELO 4'
#     }
#     history_list.append(train_history)
#
# with open('/home/luismalta/Projects/DeepRL/logs/Dueling_DQN/log_10-07-2019_23:44/train_history.json') as fp:
#     train_history = {
#         "history" : json.load(fp),
#         "label" : 'DUELING DQN MODELO 8'
#     }
#     history_list.append(train_history)

plt.rcParams['figure.figsize']= (15,5)
plt.rcParams.update({'font.size': 12})
plt.rcParams.update({'font.weight':0})
plt.get_cmap()

for history in history_list:
    reward = smooth(history["history"]["episode_reward"],0.995)
    #plt.plot(reward, label=history["label"][-21:])
    plt.plot(reward, label="DUELING DQN MODELO " + str(model_cont))
    model_cont += 1

plt.legend()
plt.grid()
plt.title(u'Recompensas por epsódios', loc='left', fontsize=16, fontweight=10, color='black')
plt.xlabel(u"Episódios")
plt.ylabel("Recompensa")
plt.show()


import itertools

def part1(numbers):
    for x, y in itertools.combinations(numbers, 2):
        if x + y == 2020:
            return x * y

def part2(numbers):
    for x, y, z in itertools.combinations(numbers, 3):
        if x + y + z == 2020:
            return x * y * z

def main(inp):
    with open(inp) as f:
        lines = f.read().splitlines()
    numbers = list(map(int, lines))
    res1 = part1(numbers)
    res2 = part2(numbers)
    return res1, res2

if __name__ == '__main__':
    a, b = main('../input/input01.txt')
    print('day01.1:', a)
    print('day01.2:', b)


# import os
import subprocess
import time
from subprocess import PIPE, Popen

''' get hostnames from slurm file '''
# /u/kastanday/viz/viz-workflow/slurm/nodes_array.txt
with open('/u/kastanday/viz/viz-workflow/slurm/nodes_array.txt', 'r') as f:
  hostnames = f.read().splitlines()

print("Syncing footprints to nodes:\n\t", '\n\t'.join(hostnames))

count = 0
for hostname in hostnames:
  # to use ssh in rsync (over a remote sheel) use the following: `rsync -rv --rsh=ssh hostname::module /dest``
  # see https://manpages.ubuntu.com/manpages/focal/en/man1/rsync.1.html (USING RSYNC-DAEMON FEATURES VIA A REMOTE-SHELL CONNECTION)

  ssh = ['ssh', f'{hostname}',]

  ## Compress 'staged' on each node's tmp dir, for faster copy later.
  tar_and_zstd = [ f'tar cf - /tmp/v6_debug_viz_output | pv | zstd -2 > /tmp/{hostname}_staged.tar.zstd' ]
  cmd = ssh + tar_and_zstd
  process_2 = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)

  ## RSYNC TO /scratch
  # rsync = ['rsync', '-r', '--update', '/tmp/v6_debug_viz_output/staged/', f'/scratch/bbki/kastanday/maple_data_xsede_bridges2/v6_debug_viz_output/staged/{hostname}']
  # rsync = ['rsync', '/tmp/{hostname}_staged.tar.zstd', f'/scratch/bbki/kastanday/maple_data_xsede_bridges2/v7_debug_viz_output/staged']
  # cmd = ssh + rsync
  # print(f"'{count} of {len(hostnames)}'. running command: {cmd}")
  # count += 1
  # process = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)

  # stdout, stderr = process.communicate()
  # print(stdout)
  # print(stderr)
  # time.sleep(0.5)
  # break

print("All jobs launched! They will work in the background WITHOUT stdout printing. ")

# optional improvement
# shlex.split(s)  -- turn cmd line args into a list.


import cherrypy
import json
import splunk.appserver.mrsparkle.controllers as controllers
from splunk.appserver.mrsparkle.lib import jsonresponse
from splunk.appserver.mrsparkle.lib.decorators import expose_page
from splunk.appserver.mrsparkle.lib.routes import route
from splunk.rest import simpleRequest
import sys

from splunk.clilib.bundle_paths import make_splunkhome_path
sys.path.append(make_splunkhome_path(["etc", "apps", "SA-ThreatIntelligence", "bin"]))
from custom_search_builder.base                    import CustomSearchBuilderBase
from custom_search_builder.exceptions              import *
from custom_search_builder.make_correlation_search import makeCorrelationSearch
from custom_search_builder.make_lookup_generating_search import makeLookupGeneratingSearch

sys.path.append(make_splunkhome_path(["etc", "apps", "Splunk_SA_CIM", "lib"]))
from cim_models import DataModels

import logging
logger = logging.getLogger('splunk.appserver.SA-ThreatIntelligence.controllers.CustomSearchBuilder')

class CustomSearchBuilder(controllers.BaseController):

    @route('/:get_data_models=get_data_models')
    @expose_page(must_login=True, methods=['GET'])
    def getDataModelsAndObjects(self, **kwargs):

        # Get the session key
        sessionKey = cherrypy.session.get('sessionKey')

        # This will contain all of the information about the data-models and the associated objects
        data_models_info = []

        # Get the list of data-models
        for data_model in DataModels.getDatamodelList(sessionKey):

            try:
                data_models_info.append( {
                                          'name' : data_model,
                                          'objects' : DataModels.getDatamodelObjectList(data_model, sessionKey)
                                          } )
            except:
                pass

        return self.render_json(data_models_info)

    @route('/:get_available_fields=get_available_fields')
    @expose_page(must_login=True, methods=['GET'])
    def getAvailableFieldsFromSpec(self, search_spec, **kwargs):
        # Get the session key
        sessionKey = cherrypy.session.get('sessionKey')

        # Parse the JSON
        search_spec_parsed = json.loads(search_spec)

        # Get instance of CustomSearchBuilderBase
        csb = CustomSearchBuilderBase(sessionKey, logger)

        try:
            available_fields = csb.getAvailableFields(search_spec_parsed)

        except (InvalidResultFilter, InvalidAggregate, InvalidDatamodelObject, InvalidInputlookup) as e:
            return self.render_json( {
                                      'success': False,
                                      'message': 'Search specification is invalid: '  + str(e),
                                      })

        except Exception as e:
            return self.render_json( {
                                      'success': False,
                                      'message': 'Search specification could not be converted: ' + str(e)
                                      })

        return self.render_json( {
                                  'success'   : True,
                                  'available_fields' : available_fields,
                                  'message'    : 'Search specification converted successfully'
                                  })

    @route('/:make_search_from_spec=make_search_from_spec')
    @expose_page(must_login=True, methods=['GET'])
    def makeSearchFromSpec(self, routine, search_spec, **kwargs):

        # Get the session key
        sessionKey = cherrypy.session.get('sessionKey')

        # Parse the JSON
        search_spec_parsed = json.loads(search_spec)

        # Make the correlation search string
        try:
            if routine == 'makeCorrelationSearch':
              raw_search, parses = makeCorrelationSearch(search_spec_parsed, sessionKey=sessionKey, logger=logger)
            elif routine == 'makeLookupGeneratingSearch':
              raw_search, parses = makeLookupGeneratingSearch(search_spec_parsed, sessionKey=sessionKey, logger=logger)
            elif routine == 'raw':
              ## Get instance of CustomSearchBuilderBase
              ## This validates sessionKey and logger
              rsb = CustomSearchBuilderBase(sessionKey, logger)
              rs = search_spec_parsed.get('search', {})
              if rs.get('inputlookup', False):
                raw_search = rsb.makeInputlookup(rs)
              else:
                raw_search = rsb.makeRaw(rs, modelJson=None)
              response, contents = simpleRequest("search/parser", sessionKey=sessionKey, getargs={'q': raw_search, 'parse_only': 't', 'output_mode': 'json'})
              parses = (response.status == 200)
            else:
              return self.render_json( {
                                      'success': False,
                                      'message': 'Routine not supported: ' + str(routine),
                                      })
        except (InvalidResultFilter, InvalidAggregate, InvalidDatamodelObject, InvalidInputlookup) as e:
            return self.render_json( {
                                      'success': False,
                                      'message': 'Search specification is invalid: '  + str(e),
                                      })

        except Exception as e:
            return self.render_json( {
                                      'success': False,
                                      'message': 'Search specification could not be converted: ' + str(e)
                                      })

        return self.render_json( {
                                  'success'    : True,
                                  'raw_search' : raw_search,
                                  'parses'     : parses,
                                  'message'    : 'Search specification converted successfully'
                                  })


# Programa que permita determinar cual es la edad mayor y menor en un grupo de 5 estudiantes.

lista = []
i=0

while i < 5:
    edad = int(input('Cual es tu edad: '))
    lista.append(edad)
    i = i+1

print()
print('La edad mayor es: {} años'.format(max(lista)))
print('La edad menor es: {} años'.format(min(lista)))


# "The __init__.py files are required to make Python treat the
# directories as containing packages"
# -- http://docs.python.org/tutorial/modules.html

from ConfigParser import ConfigParser

from sqlalchemy.engine.url import make_url

from traincheck import TrainingRecordsRd

TRAINING_SECTION = 'training'

def from_config(ini, create_engine):
    cp = ConfigParser()
    cp.readfp(ini.open(), str(ini))
    u = make_url(cp.get(TRAINING_SECTION, 'url'))
    redcapdb = (None if u.drivername == 'sqlite' else 'redcap')

    # Address connection timeouts using pool_recycle
    # ref http://docs.sqlalchemy.org/en/rel_1_0/dialects/mysql.html#connection-timeouts  # noqa
    trainingdb = create_engine(u, pool_recycle=3600)
    account = lambda: trainingdb.connect(), u.database, redcapdb

    tr = TrainingRecordsRd(account)

    return tr.__getitem__


# Corner Detections

import cv2
import numpy as np

# Load image then grayscale
image = cv2.imread('images/chess.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# The cornerHarris function requires the array datatype to be float32
gray = np.float32(gray)

harris_corners = cv2.cornerHarris(gray, 3, 3, 0.05)

#We use dilation of the corner points to enlarge them\
kernel = np.ones((7,7),np.uint8)
harris_corners = cv2.dilate(harris_corners, kernel, iterations = 2)

# Threshold for an optimal value, it may vary depending on the image.
image[harris_corners > 0.025 * harris_corners.max() ] = [255, 127, 127]

cv2.imshow('Harris Corners', image)
cv2.waitKey(0)

# We specific the top 50 corners
corners = cv2.goodFeaturesToTrack(gray, 100, 0.01, 150)

for corner in corners:
    x, y = corner[0]
    x = int(x)
    y = int(y)
    cv2.rectangle(image, (x - 10, y - 10), (x + 10, y + 10), (0, 255, 0), 2)

cv2.imshow("Corners Found", image)
cv2.waitKey()

cv2.destroyAllWindows()


import numpy as np
from ECG.criterion_based_approach.util import get_channel, get_values_ignoring_nan

def get_median_r_amplitude(ecg_signal, sampling_rate, ecg_parameters):
    ecg_signal_v4, _ = get_channel(ecg_signal, sampling_rate, 'V4')
    peaks = ecg_signal_v4[ecg_parameters['R_peaks']]
    offsets = get_values_ignoring_nan(ecg_signal_v4, ecg_parameters['P_offsets'])
    r_amplitudes = np.abs(peaks - offsets)
    return np.nanmedian(r_amplitudes)


# -*- coding: utf-8 -*-
"""
Created on Tue Mar 24 01:57:39 2020

@author: agarcia20
"""

import yfinance as yf
import math

stock = yf.Ticker("XOM")                                                                 # Get ticker
expiration = stock.options[0]                                                            # Get next expiration date
opt = stock.option_chain(expiration)                                                     # Get the option chain

options = opt.calls                                                                      # Get options
for idx_left_body, left_body in options.iterrows():                                      # Iterate over all options
    left_wings = options[options['strike'] < left_body['strike']]                        # Get left wings

    for idx_left, left in left_wings.iterrows():                                         # Iterate over left wings
        right_bodies = options[options['strike'] > left_body['strike']]                  # Get right bodies

        for idx_right_body, right_body in right_bodies.iterrows():                       # Iterate over right bodies
            right_wings = options[options['strike'] > right_body['strike']]              # Get right wings

            for idx_right, right in right_wings.iterrows():                              # Iterate over right wings

                left_count = round(right['strike'] - right_body['strike'], 2) * 1000     # Left raw wing/body count
                right_count = round(left_body['strike'] - left['strike'], 2) * 1000      # Right raw wing/body count

                if (left_count == int(left_count) and right_count == int(right_count)):  # If there is a integer number of contracts try to minimize the quantity
                    gcd = math.gcd(int(left_count), int(right_count))                    # Greated Common Divisor between the number of contracts

                    left_count /= gcd
                    right_count /= gcd

                    if left_count <= 10 and right_count <= 10:                           # Filter all the condors with less than 10 contracts
                        print("Buy %d Contract (Strike %.2f) - Sell %d Contract (Strike %.2f) - Sell %d Contract (Strike %.2f) - Buy %d Contract (Strike %.2f)" %
                            (left_count, left['strike'], left_count, left_body['strike'], right_count, right_body['strike'], right_count, right['strike']))


import queue

class Grafo:
    def __init__(self, numero_vertices):
        self.n_vertices = numero_vertices
        self.matriz = [[0] * self.n_vertices for i in range(self.n_vertices)]  #matriz de adjacência.
        self.lista = [[] for i in range(self.n_vertices)]  #lista de adjacência.

#---------------------------------- Busca em largura(BFS) ----------------------------------#
    def bfs(self, source):
        fila = queue.Queue()
        fila.put(source)

        ant = [-1 for i in range(self.n_vertices)]
        dist = [-1 for i in range(self.n_vertices)]
        dist[source] = 0
        is_visited = [False for i in range(self.n_vertices)]
        is_visited[source] = 0

        #
        while (fila.empty() != True):
            p = fila.get()

            for ver in self.lista[p]:
                if (is_visited[ver] == False):
                    dist[ver] = dist[p] + 1
                    ant[ver] = p
                    fila.put(ver)
                    is_visited[ver] = True

        return dist, ant

    def print_path(self, v1 ,v2, ant): #Retona o melhor caminho entre os vertices
        path = []
        vert2 = v2

        if ant[v2] == -1:
            print(f"Não existe nenhum caminho entre os vértices {v1} e {v2}.")

        while (v2 != v1):
            path.append(v2)
            v2 = ant[v2]

        path.append(v1)
        path.reverse()

        print(f"\nMelhor caminho entre os vértices {v1} e {vert2}:\n", " -> ".join(map(str, path)))


soma = 0
cont = 0

for num in range(1,7):
    numeros = int(input('Digite o {} número: '.format(num)))
    if numeros % 2 == 0:
        soma += numeros
        cont += 1
print('Você digitou um total de {} números pares e a soma entre eles deu {}'.format(cont,soma))


# Aryan Gidwani
# December 10, 2021
# ICS3UO - A
# The purpose of this program is to find how much each letter appears in any
# string that the user inputs in. After calculating how much each letter
# appears in a user-inputted string, it will inform the user of the important
# information.

import sys
# imports a module which helps with the program

def stopProgram(userInput):
    if userInput.lower() == "quit":
        print("Thank you for using this program!")
        # concluding message
        sys.exit()
        # terminates the program

    else:
        pass
        # does nothing

def characterCounter():
    flag = True
    # creates a flag which holds the boolean value of True
    while flag:
        characterDict = {}
        # creates an empty dictionary, where keys and values will be added on later
        chosenString = input("Enter in any string of your choice, and the program will count how many times each character appears!: ")
        # asks the user to input a string of their choice
        chosenString = chosenString.lower()
        # makes all the letters of the string lowercase
        stopProgram(chosenString)
        # checks and sees if the user wanted to quit
        chosenString = list(chosenString)
        # puts the string into a list
        for counter in range(0, len(chosenString)):
            if chosenString[counter] in characterDict:
                characterDict[chosenString[counter]] = characterDict[chosenString[counter]] + 1
                # loops through the dictionary while looping through the user
                # inputted string, and increments the value of how many times
                # a letter is detected

            else:
                characterDict[chosenString[counter]] = 1
                # adds the character to the dictionary and sets the value to 1

        print("Here is the list of characters and how many times they appear! " + "\n" + str(characterDict) + "\n")
        # prints out the dictionary and information

name = input("Hello! What is your name? ")
# asks the user for their name
print("Hello " + name + "! The purpose of this program is to find how much of each character or letter there is in a string that you input! You will input a string, and the program will tell you the rest of the information!")
# introductory message

characterCounter()
# calls the characterCounter function


#!/usr/bin/env python2

import logging
import subprocess
import os.path
import shlex
import importlib.resources
import clamsig
import csv

class ClamSigVis:

    '''
    Use the tooling
    '''

    # Use the default directory
    _freshclam_dir = None

    # Use the default path by default
    _bin_path = None

    #
    _clamftypes = {0: "any file",
                   1: "Portable Executable, both 32 - and 64 - bit ",
                   2: "OLE2 containers, including specific macros.Primarily used by MS Office and MSI installation files",
                   3: "HTML(normalized)",
                   4: "Mail file",
                   5: "Graphics",
                   6: "ELF",
                   7: "ASCII text file(normalized)",
                   8: "Unused",
                   9: "Mach-O files",
                   10: "PDF files",
                   11: "Flash files",
                   12: "Java class files"}

    def __init__(self, signature_name=None, **kwargs):

        self.logger = logging.getLogger("ClamSigVis")

        self.freshclam_dir = kwargs.get("freshclam_dir", self._freshclam_dir)
        self.bin_path = kwargs.get("bin_path", self._bin_path)

        self.clamftypes = kwargs.get("clamftypes", self._clamftypes)
        self.clamflevels = kwargs.get("clamflevels", self.read_flevels())

        self.signature_search_name = signature_name

        self.sig_text_raw = self.get_sig_data()
        self.sig_decoded = self.get_decoded_sig()

    def read_flevels(self):

        flevels = dict()

        with importlib.resources.path(clamsig, "flevel.csv") as flevel_csv:
            with open(flevel_csv, "r") as flevel_csv_fobj:
                reader = csv.DictReader(flevel_csv_fobj)

                for row in reader:
                    flevels[int(row["FLEVEL"])] = row

        return flevels

    def get_sig_data(self):

        '''
        Use sigtool to get the signature string
        :return:
        '''

        get_sig_cmd = list()

        if self.bin_path is not None:
            sigtool_bin = os.path.join(self.bin_path, "sigtool")

        get_sig_cmd.append("sigtool")

        if self.freshclam_dir is not None:

            defs_path = os.path.join(self.freshclam_dir, "defs")

            get_sig_cmd.append("-d {}".format(defs_path.abspath))

        get_sig_cmd.append("--find-sigs {}".format(self.signature_search_name))

        try:
            read_sig_result = subprocess.run(" ".join(get_sig_cmd),
                                             executable="/bin/bash",
                                             shell=True,
                                             timeout=120,
                                             capture_output=True)
        except Exception as sig_read_error:
            self.logger.error("Unable to Read Signature")
            self.logger.info(sig_read_error)
            signature_raw_text = None
        else:
            # Let's Parse the Results

            signature_raw_text = read_sig_result.stdout.decode("utf-8")

            self.logger.debug("Signature Raw Text:\n{}".format(signature_raw_text))

            total_signatures = len(signature_raw_text.splitlines())

            self.logger.debug("Found {} Signature for search term: {}".format(total_signatures, self.signature_search_name))

            if total_signatures == 0:
                raise FileNotFoundError("I was unable to find a signature.")
            elif total_signatures > 1:
                raise ValueError("I found too many signatures!")

        return signature_raw_text

    def get_decoded_sig(self):

        '''
        Decode the Signature and Return the Data Back
        :return:
        '''

        decode_sig_cmd = ['''echo -e "{}" |'''.format(self.sig_text_raw)]

        if self.bin_path is not None:
            sigtool_bin = os.path.join(self.bin_path, "sigtool")

        decode_sig_cmd.append("sigtool --decode-sigs")

        try:
            decode_sig_result = subprocess.run(" ".join(decode_sig_cmd),
                                               executable="/bin/bash",
                                               shell=True,
                                               timeout=120,
                                               capture_output=True)
        except Exception as sig_read_error:
            self.logger.error("Unable to Read Signature")
            # Change back to info later
            self.logger.error(sig_read_error)
            signature_decode = None
        else:
            # Let's Parse the Results

            signature_decode = decode_sig_result.stdout.decode("utf-8")

            self.logger.debug("Signature Decoded Text:\n{}".format(signature_decode))

        return signature_decode


from sentence_transformers import SentenceTransformer
from collections import defaultdict
from graph_model import dialogue_graph
import pickle
import numpy as np
import sys
import torch
from graph_model.cluster_selection.cluster_selection import PredictNextCluster, prepare_input

from graph_model import dialogue_graph
from graph_model import dataset
from graph_model import clustering
from graph_model import embedders
from graph_model import dialogue_sim

sys.modules["dialogue_graph"] = dialogue_graph
sys.modules["dataset"] = dataset
sys.modules["clustering"] = clustering
sys.modules["embedders"] = embedders
sys.modules["dialogue_sim"] = dialogue_sim

class Utterance:
    def __init__(self, string, embedding):
        self.string = string
        self.embedding = embedding

class GraphModel:
    def __init__(self):
        self.cluster_prediction = PredictNextCluster(403, 512, 11)
        self.cluster_prediction.load_state_dict(torch.load("graph_model/cluster_selection/cluster_selection.pt", map_location=torch.device('cpu')))
        self.cluster_prediction.eval()
        self.model = SentenceTransformer("all-MiniLM-L6-v2")
        with open("graph_model/dialogue_sim/graphs/one_serv_10_taxi.pkl", 'rb') as file:
            self.graph = pickle.load(file)
        with open("graph_model/dialogue_sim/data/train_dials.pkl", "rb") as file:
            self.train_dials = pickle.load(file)
        self.transitions = self.train_dials[0].transitions

        self.cluster_to_utts = defaultdict(list)
        for dial in self.train_dials:
            for i in range(len(dial.utterances)):
                self.cluster_to_utts[dial.second_stage_clusters[i]].append(Utterance(dial.utterances[i], dial.lm_embeddings[i]))

        self.cluster_to_embs = {}
        for i, utts in self.cluster_to_utts.items():
            embs = []
            for utt in utts:
                embs.append(utt.embedding)
            self.cluster_to_embs[i] = np.array(embs)

    def get_closest(self, target, utt_embs, k = 5):
        similarity = (utt_embs @ target.reshape(-1, 1)).ravel()
        closest = np.argsort(similarity)[:-k:-1]
        return closest

    def get_next_cluster(self, cur_cluster):
        return np.argmax(self.transitions[cur_cluster])

    def __call__(self, text):
        embedding = self.model.encode(text)
        one_stage_cluster = self.graph.one_stage_clustering._subclusters["USER"].predict_cluster(embedding[0]).id
        second_stage_cluster = self.graph.cluster_kmeans_labels[0][one_stage_cluster]

        prepared_input = prepare_input(embedding[0], self.transitions[second_stage_cluster], self.graph.cluster_embeddings[one_stage_cluster] )
        #next_cluster = self.get_next_cluster(second_stage_cluster)
        next_cluster = torch.argmax(self.cluster_prediction(prepared_input.reshape(1, -1)), 1).item()
        closest_idxs = self.get_closest(embedding, self.cluster_to_embs[next_cluster])
        closest_str = []
        for i in closest_idxs:
            closest_str.append(self.cluster_to_utts[next_cluster][i].string)
        return [closest_str[0]], next_cluster


from recipes.decorators import catch
import pytest

class TestCatch:

    @pytest.mark.parametrize(
        'action, kls, kws',
        [('warn', UserWarning, {}),
         ('raise', ValueError, {}),
         ('raise', TypeError, dict(alternate=TypeError))]
    )
    def test_decor(self, action, kls, kws):

        @catch(action=action, **kws)
        def foo():
            raise ValueError('Nope!')

        ctx = pytest.warns if issubclass(kls, Warning) else pytest.raises
        with ctx(kls):
            foo()

    @pytest.mark.parametrize(
        'action, kls, kws',
        [('warn', UserWarning, {}),
         ('raise', ValueError, {}),
         ('raise', TypeError, dict(alternate=TypeError))]
    )
    def test_context(self, action, kls, kws):
        ctx = pytest.warns if issubclass(kls, Warning) else pytest.raises
        with ctx(kls):
            with catch(action=action, **kws):
                raise ValueError('Nope!')

    @pytest.mark.parametrize('action', ('ignore', 'warn', 'raise'))
    def test_context_no_error(self, action):
        with catch(action=action):
            pass