from typing import Callable, List, Union

import numpy as np
from numpy import argsort, ceil, exp, mod, zeros
from numpy.random import geometric, rand, randint, randn

from ...search_space import SearchSpace
from ...solution import Solution
from ...utils import dynamic_penalty, handle_box_constraint

__author__ = "Hao Wang"

# TODO: improve efficiency, e.g. compile it with cython
class MIES:
    """Mixed-integer Evolution Strategy"""

    def __init__(
        self,
        search_space: SearchSpace,
        obj_func: Callable,
        eq_func: Callable = None,
        ineq_func: Callable = None,
        x0: Union[List, Solution] = None,
        ftarget: float = None,
        max_eval: float = np.inf,
        minimize: bool = True,
        elitism: bool = False,
        mu_: int = 4,
        lambda_: int = 10,
        sigma0: float = None,
        eta0: float = None,
        P0: float = None,
        verbose: bool = False,
        eval_type: str = "list",
    ):
        # TODO: constructor is too long...
        self.mu_ = mu_
        self.lambda_ = lambda_
        self.eval_count = 0
        self.iter_count = 0
        self.minimize = minimize
        self.obj_func = obj_func
        self.eq_func = eq_func
        self.ineq_func = ineq_func
        self.stop_dict = {}
        self.verbose = verbose
        self.max_eval = max_eval
        self.ftarget = ftarget
        self.elitism = elitism
        self._penalty_func = dynamic_penalty
        self._eval_type = eval_type

        self._space = search_space
        self.var_names = self._space.var_name
        self.param_type = self._space.var_type

        if self._eval_type == "list":
            self._to_pheno = lambda x: x
        elif self._eval_type == "dict":
            self._to_pheno = lambda x: x.to_dict(space=self._space)

        # index of each type of variables in the dataframe
        self.id_r = self._space.real_id  # index of continuous variable
        self.id_i = self._space.integer_id  # index of integer variable
        self.id_d = self._space.categorical_id  # index of categorical variable

        # the number of variables per each type
        self.N_r = len(self.id_r)
        self.N_i = len(self.id_i)
        self.N_d = len(self.id_d)
        self.dim = self.N_r + self.N_i + self.N_d

        # by default, we use individual step sizes for continuous and
        # integer variables and global strength for the nominal variables
        self.N_p = min(self.N_d, int(1))

        # total length of the solution vector
        self._len = self.dim + self.N_r + self.N_i + self.N_p

        # unpack interval bounds
        self.bounds_r = np.asarray([self._space.bounds[_] for _ in self.id_r])
        self.bounds_i = np.asarray([self._space.bounds[_] for _ in self.id_i])
        # NOTE: bounds might be ragged
        self.bounds_d = [self._space.bounds[_] for _ in self.id_d]
        self._check_bounds(self.bounds_r)
        self._check_bounds(self.bounds_i)

        # step default step-sizes/mutation strength
        par_name = []
        if sigma0 is None and self.N_r:
            sigma0 = 0.05 * (self.bounds_r[:, 1] - self.bounds_r[:, 0])
            par_name += ["sigma" + str(_) for _ in range(self.N_r)]
        if eta0 is None and self.N_i:
            eta0 = 0.05 * (self.bounds_i[:, 1] - self.bounds_i[:, 0])
            par_name += ["eta" + str(_) for _ in range(self.N_i)]
        if P0 is None and self.N_d:
            P0 = 1.0 / self.N_d
            par_name += ["P" + str(_) for _ in range(self.N_p)]

        # column indices: used for slicing
        self._id_var = np.arange(self.dim)
        self._id_sigma = np.arange(self.N_r) + len(self._id_var)
        self._id_eta = np.arange(self.N_i) + len(self._id_var) + len(self._id_sigma)
        self._id_p = np.arange(self.N_p) + len(self._id_var) + len(self._id_sigma) + len(self._id_eta)
        self._id_hyperpar = np.arange(self.dim, self._len)

        # initialize the populations
        if x0 is not None:  # given x0
            par = []
            if self.N_r:
                par += [sigma0]
            if self.N_i:
                par += [eta0]
            if self.N_p:
                par += [P0] * self.N_p

            self.pop = Solution(
                np.tile(np.r_[x0, par], (self.mu_, 1)),
                var_name=self.var_names + par_name,
                verbose=self.verbose,
            )
            fitness0 = self.evaluate(self.pop[0])
            self.fitness = np.repeat(fitness0, self.mu_)
            self.xopt = x0
            self.fopt = sum(fitness0)
        else:  # uniform sampling
            x = np.asarray(self._space.sample(self.mu_), dtype="object")

            par = []
            if self.N_r:
                par += [np.tile(sigma0, (self.mu_, 1))]
            if self.N_i:
                par += [np.tile(eta0, (self.mu_, 1))]
            if self.N_p:
                par += [np.tile([P0] * self.N_p, (self.mu_, 1))]

            par = np.concatenate(par, axis=1)
            x = np.c_[x, par].tolist()

            self.pop = Solution(x, var_name=self.var_names + par_name, verbose=self.verbose)
            self.fitness = self.evaluate(self.pop)
            self.fopt = min(self.fitness) if self.minimize else max(self.fitness)
            _ = np.nonzero(self.fopt == self.fitness)[0][0]
            self.xopt = self.pop[_, self._id_var]

        self.offspring = self.pop[0] * self.lambda_
        self.f_offspring = np.repeat(self.fitness[0], self.lambda_)
        self._set_hyperparameter()

        # stopping criteria
        self.tolfun = 1e-5
        self.nbin = int(3 + ceil(30.0 * self.dim / self.lambda_))
        self.histfunval = zeros(self.nbin)

    def _check_bounds(self, bounds):
        if len(bounds) == 0:
            return
        if any(bounds[:, 0] >= bounds[:, 1]):
            raise ValueError("lower bounds must be smaller than upper bounds")

    def _set_hyperparameter(self):
        # hyperparameters: mutation strength adaptation
        if self.N_r:
            self.tau_r = 1 / np.sqrt(2 * self.N_r)
            self.tau_p_r = 1 / np.sqrt(2 * np.sqrt(self.N_r))

        if self.N_i:
            self.tau_i = 1 / np.sqrt(2 * self.N_i)
            self.tau_p_i = 1 / np.sqrt(2 * np.sqrt(self.N_i))

        if self.N_d:
            self.tau_d = 1 / np.sqrt(2 * self.N_d)
            self.tau_p_d = 1 / np.sqrt(2 * np.sqrt(self.N_d))

    def recombine(self, id1, id2):
        p1 = self.pop[id1].copy()  # IMPORTANT: make a copy
        if id1 != id2:
            p2 = self.pop[id2]
            # intermediate recombination for the mutation strengths
            p1[self._id_hyperpar] = (np.array(p1[self._id_hyperpar]) + np.array(p2[self._id_hyperpar])) / 2

            # dominant recombination for solution parameters
            (_,) = np.nonzero(randn(self.dim) > 0.5)
            p1[_] = p2[_]
        return p1

    def select(self):
        pop = self.pop + self.offspring if self.elitism else self.offspring
        fitness = np.r_[self.fitness, self.f_offspring] if self.elitism else self.f_offspring
        rank = argsort(fitness)

        if not self.minimize:
            rank = rank[::-1]

        _ = rank[: self.mu_]
        self.pop = pop[_]
        self.fitness = fitness[_]

    def evaluate(self, pop, return_penalized=True):
        X = self._to_pheno(pop[:, self._id_var])
        if len(pop.shape) == 1:  # one solution
            X = [X]

        pop.fitness = np.array(list(map(self.obj_func, X))).ravel()
        self.eval_count += pop.N
        _penalized_fitness = (
            self._penalty_func(X, self.iter_count + 1, self.eq_func, self.ineq_func, minimize=self.minimize)
            + pop.fitness
        )
        return _penalized_fitness if return_penalized else pop.fitness

    def mutate(self, individual):
        if self.N_r:
            self._mutate_r(individual)
        if self.N_i:
            self._mutate_i(individual)
        if self.N_d:
            self._mutate_d(individual)
        return individual

    def _mutate_r(self, individual):
        sigma = np.asarray(individual[self._id_sigma], dtype="float")
        # mutate step-sizes
        if len(self._id_sigma) == 1:
            sigma = sigma * exp(self.tau_r * randn())
        else:
            sigma = sigma * exp(self.tau_r * randn() + self.tau_p_r * randn(self.N_r))

        # Gaussian mutation
        R = randn(self.N_r)
        x = np.asarray(individual[self.id_r], dtype="float")
        x_ = x + sigma * R

        # Interval Bounds Treatment
        x_ = handle_box_constraint(x_, self.bounds_r[:, 0], self.bounds_r[:, 1])
        # rounding if a coarser numerical precision is provided
        x_ = self._space[self._space.real_id].round(x_).ravel()
        # NOTE: experimental correction to the step-size when the box constraints are violated
        # the constraint handling method will (by chance) turn bad candidates (which are generated
        # by large step-sizes) to good ones, hence confusing the self-adaptation for step-sizes.
        if 1 < 2:
            individual[self._id_sigma] = np.abs((x_ - x) / R)
        else:
            individual[self._id_sigma] = sigma
        individual[self.id_r] = x_

    def _mutate_i(self, individual):
        eta = np.asarray(individual[self._id_eta].tolist(), dtype="float")
        x = np.asarray(individual[self.id_i], dtype="int")
        if len(self._id_eta) == 1:
            eta = eta * exp(self.tau_i * randn())
        else:
            eta = eta * exp(self.tau_i * randn() + self.tau_p_i * randn(self.N_i))
        eta[eta > 1] = 1

        p = 1 - (eta / self.N_i) / (1 + np.sqrt(1 + (eta / self.N_i) ** 2.0))
        x_ = x + geometric(p) - geometric(p)

        # Interval Bounds Treatment
        x_ = np.asarray(handle_box_constraint(x_, self.bounds_i[:, 0], self.bounds_i[:, 1]), dtype="int")
        individual[self.id_i] = x_
        individual[self._id_eta] = eta

    def _mutate_d(self, individual):
        P = np.asarray(individual[self._id_p], dtype="float")
        #  Unbiased mutation on the mutation probability
        P = 1.0 / (1.0 + (1.0 - P) / P * exp(-self.tau_d * randn()))
        individual[self._id_p] = handle_box_constraint(P, 1.0 / (3.0 * self.N_d), 0.5)

        (idx,) = np.nonzero(rand(self.N_d) < P)
        # TODO: this can be accelerated
        for i in idx:
            levels = self.bounds_d[i]
            individual[self.id_d[i]] = levels[randint(0, len(levels))]

    def stop(self):
        if self.eval_count > self.max_eval:
            self.stop_dict["max_eval"] = True

        if self.eval_count != 0 and self.iter_count != 0:
            fitness = self.f_offspring
            # sigma = np.atleast_2d([__[self._id_sigma] for __ in self.pop])
            # sigma_mean = np.mean(sigma, axis=0)

            # tolerance on fitness in history
            self.histfunval[int(mod(self.eval_count / self.lambda_ - 1, self.nbin))] = fitness[0]
            if (
                mod(self.eval_count / self.lambda_, self.nbin) == 0
                and (max(self.histfunval) - min(self.histfunval)) < self.tolfun
            ):
                self.stop_dict["tolfun"] = True

            # flat fitness within the population
            if fitness[0] == fitness[int(min(ceil(0.1 + self.lambda_ / 4.0), self.mu_ - 1))]:
                self.stop_dict["flatfitness"] = True

            # TODO: implement more stop criteria
            # if any(sigma_mean < 1e-10) or any(sigma_mean > 1e10):
            #     self.stop_dict['sigma'] = True

            # if cond(self.C) > 1e14:
            #     if is_stop_on_warning:
            #         self.stop_dict['conditioncov'] = True
            #     else:
            #         self.flg_warning = True

            # # TolUPX
            # if any(sigma*sqrt(diagC)) > self.tolupx:
            #     if is_stop_on_warning:
            #         self.stop_dict['TolUPX'] = True
            #     else:
            #         self.flg_warning = True

        return any(self.stop_dict.values())

    def _better(self, f1, f2):
        return f1 < f2 if self.minimize else f1 > f2

    # TODO: optimize -> run
    def optimize(self):
        while not self.stop():
            # TODO: vectorize this part
            for i in range(self.lambda_):
                p1, p2 = randint(0, self.mu_), randint(0, self.mu_)
                individual = self.recombine(p1, p2)
                self.offspring[i] = self.mutate(individual)

            # NOTE: `self.fitness` and `self.f_offspring` are penalized function values
            self.f_offspring[:] = self.evaluate(self.offspring)
            self.select()

            curr_best = self.pop[0]
            xopt_, fopt_ = curr_best[self._id_var], self.fitness[0]

            if self._better(fopt_, self.fopt):
                self.xopt, self.fopt = xopt_, fopt_
            self.iter_count += 1

            if self.verbose:
                print("iteration {}, fopt: {}".format(self.iter_count + 1, self.fopt))
                print(self.xopt)

        self.stop_dict["funcalls"] = self.eval_count
        return self.xopt.tolist(), self.fopt, self.stop_dict


import csv
import re
import json
import os
import matplotlib.pyplot as plt
import seaborn as sns
import sys
import math
from datetime import *

window_smoothing_width_days = 50 # stdev of gaussian to convolve over the data
window_size_days = 8 * window_smoothing_width_days # Window size to average # of messages over
num_top_people = 30 # How many of the top people to display
color_spread_skip = num_top_people // 5 # stride over color
enable_group_chats = False
anonymize = False

# for word count
def get_message_weight(text_contents):
    return len(text_contents.split(' '))

# for just per-message
# def get_message_weight(msg):
#     return 1

# how much to weigh a message based on distance
# use a gaussian for smoothing
def get_weight_for_time(message_day, graph_day):
    stdev = window_smoothing_width_days
    return gaussian_pdf(message_day, stdev, graph_day)

# average over window
# def get_weight_for_time(message_day, graph_day):
#     return 1.0 / window_size_days

def gaussian_pdf(mean, stdev, x):
    variance = stdev ** 2
    offset = abs(mean - x)
    return math.exp(-(offset ** 2)/(2 * variance)) / math.sqrt(2 * math.pi * variance)

def spread_list(items, k):
    res = []
    for i in range(0, k):
        res = res + items[i::k]
    return res

if anonymize:
    anon_names = []
    with open('anon_names.txt') as f:
        anon_names = [name.strip() for name in f.readlines()]

name_norm_filename = 'name_normalization.json'
name_normalization = {}
if os.path.exists(name_norm_filename) and os.path.isfile(name_norm_filename):
    with open(name_norm_filename) as f:
        name_normalization = json.load(f)

def normalize_name(name):
    if name in name_normalization:
        return name_normalization[name]
    else:
        return name

def graph_messages_window(all_messages, start_date, end_date):

    delta = end_date - start_date

    xs = [start_date + timedelta(days=i) for i in range(delta.days)]

    # List of tuples of the form (total number of messages, y-values corresponding to every day, their name)
    ys_and_labels = []

    for name in all_messages:
        total_messages = 0
        y_name = [0] * len(xs)

        message_counts = all_messages[name]

        for day in message_counts:
            message_delta = day - start_date
            for windowed_day in range(message_delta.days - int(window_size_days / 2),
                                      message_delta.days + int(window_size_days / 2) + 1):
                if windowed_day > 0 and windowed_day < len(y_name):
                    weight = get_weight_for_time(message_delta.days, windowed_day)
                    inc = message_counts[day] * weight
                    y_name[windowed_day] += inc

            if message_delta.days > 0 and message_delta.days < len(y_name):
                total_messages += message_counts[day]

        ys_and_labels.append((total_messages, y_name, name, total_messages))

    # Display label sorted by most messages
    ys_and_labels.sort(reverse=True)

    # Sort y-values into a set of y-values for each of the top n people and "Other"
    ys = [y_and_label[1] for y_and_label in ys_and_labels[:num_top_people]]
    other_ys = [0] * len(xs)
    total_other_messages = 0
    for y_and_label in ys_and_labels[num_top_people:]:
        y = y_and_label[1]
        for i, count in enumerate(y):
            other_ys[i] += count
        total_other_messages += y_and_label[0]

    top_ys_and_labels = ys_and_labels[:num_top_people]

    anon_mapping = { name: name for _, _, name, _ in top_ys_and_labels }
    if anonymize:
        anon_mapping = { name: anon_names[i] for i, (_, _, name, _) in enumerate(top_ys_and_labels) }

    labels = ["%s (%d)" % (anon_mapping[y_and_label[2]], int(y_and_label[3])) for y_and_label in top_ys_and_labels]
    labels.append("Other (%d)" % int(total_other_messages))

    # Make colors prettier
    pal = sns.color_palette("hls", num_top_people)
    # This is really hardcoded for 20 basically
    colors = spread_list(pal, color_spread_skip)
    other_color = (0.9, 0.9, 0.9) #Grey
    colors.append(other_color)

    plt.rc('xtick', labelsize=16)
    plt.rc('ytick', labelsize=16)
    plt.rc('legend', fontsize=8)
    plt.rc('axes', titlesize=24)
    plt.title("Message word count by person over time")
    plt.stackplot(xs, *ys, other_ys, colors=colors, labels=labels, baseline='wiggle')
    plt.legend(loc='upper right')
    plt.show()

def aggregate_messages(
        messages_by_day_by_person,
        all_messages):

    all_people = set.union(*[ps for _, ps, _ in all_messages])

    for person in all_people:
        if person in messages_by_day_by_person:
            messages_per_day = messages_by_day_by_person[person]
        else:
            messages_per_day = {}
            messages_by_day_by_person[person] = messages_per_day
        for message_date, creditors, weight in all_messages:
            if person in creditors:
                num_creditors = len(creditors)
                if message_date in messages_per_day:
                    messages_per_day[message_date] += 1.0 * weight / num_creditors
                else:
                    messages_per_day[message_date] =  1.0 * weight / num_creditors

# returns a list of (timestamp, participants, weight) tuples, where participants equally share message weight
def process_adium_conversation(convo):
    namespaces = { 'default': "http://purl.org/net/ulf/ns/0.4-02" }
    user_name = convo.get('account')
    messages = [x for x in convo.findall('default:message', namespaces = namespaces)]
    participants = set([normalize_name(p.get('sender')) for p in messages])
    if user_name in participants:
        participants.remove(user_name)
    if len(participants) == 0:
        return []
    if len(participants) != 1 and not enable_group_chats:
        return []

    def get_local_participants(msg):
        sender = normalize_name(msg.get('sender'))
        if sender == user_name:
            return participants
        else:
            return set([sender])

    return [(
        datetime.fromisoformat(msg.get('time')).date(),
        get_local_participants(msg),
        get_message_weight(ET.tostring(msg, method='text').decode())
    ) for msg in messages]

import xml.etree.ElementTree as ET

def get_all_adium_messages(
        data_directory,
        user_name,
        start_date):
    # all_messages: list of (time_seconds, creditors)
    all_messages = []
    for msg_file in [os.path.join(data_directory, c) for c in os.listdir(data_directory)]:
        if msg_file.endswith(".xml"):
            convo = ET.parse(msg_file).getroot()
            all_messages.extend(process_adium_conversation(convo))

    return all_messages

# returns a list of (timestamp, participants, weight) tuples, where participants equally share message weight
def process_facebook_conversation(convo, user_name):
    participants = set([normalize_name(p['name']) for p in convo['participants']])
    if user_name in participants:
        participants.remove(user_name)
    if len(participants) == 0:
        return []
    if len(participants) != 1 and not enable_group_chats:
        return []

    messages = convo['messages']
    # This is a dumb starting message that Facebook leads with sometimes, ignore it
    if 'content' in messages[-1] and messages[-1]['content'].startswith('Say hi to your'):
        messages = messages[:-1]

    def get_local_participants(msg):
        sender = normalize_name(msg['sender_name'])
        if sender == user_name:
            return participants
        else:
            return set([sender])

    return [(
        date.fromtimestamp(msg['timestamp_ms'] / 1000.0),
        get_local_participants(msg),
        get_message_weight(msg.get('content') or '')
    ) for msg in messages]

def get_all_facebook_messages(
        data_directory,
        user_name,
        start_date):
    inbox = os.path.join(data_directory, 'messages', 'inbox')
    all_messages = []
    for thread_dir in [os.path.join(inbox, c) for c in os.listdir(inbox)]:
        for msg_file in [os.path.join(thread_dir, c) for c in os.listdir(thread_dir)]:
            if msg_file.endswith(".json"):
                with open(msg_file) as f:
                    convo = json.load(f)
                    all_messages.extend(process_facebook_conversation(convo, user_name))

    return all_messages

# returns a list of (timestamp, participants, weight) tuples, where participants equally share message weight
def process_hangouts_conversation(convo, user_name):
    participant_id_to_name = {
        p['id']['chat_id']: normalize_name(p.get('fallback_name') or p['id']['chat_id'])
        for p in convo['conversation']['conversation']['participant_data']
    }
    participants = set([name for _, name in participant_id_to_name.items()])
    if user_name in participants:
        participants.remove(user_name)
    if len(participants) == 0:
        return []
    if len(participants) != 1 and not enable_group_chats:
        return []

    messages = []
    for event in convo['events']:
        if event['event_type'] == 'REGULAR_CHAT_MESSAGE':
            sender = participant_id_to_name[event['sender_id']['chat_id']]
            if sender == user_name:
                creditors = participants
            else:
                creditors = set([sender])
            message_content = event['chat_message']['message_content']
            if 'segment' in message_content:
                message_text =  " ".join([
                    segment['text']
                    for segment in message_content['segment']
                    if segment['type'] == 'TEXT'
                ])

                messages.append((
                    date.fromtimestamp(int(event['timestamp']) // 1000000),
                    creditors,
                    get_message_weight(message_text)
                ))

    return messages

def get_all_hangouts_messages(
        data_directory,
        user_name,
        start_date):
    hangouts_file = os.path.join(data_directory, 'Hangouts', 'Hangouts.json')
    # all_messages: list of (time_seconds, creditors)
    with open(hangouts_file) as f:
        conversations = json.load(f)['conversations']

    all_messages = []
    for convo in conversations:
        all_messages.extend(process_hangouts_conversation(convo, user_name))

    return all_messages

# returns a list of (timestamp, participants, weight) tuples, where participants equally share message weight
def process_gtalk_conversation(convo, user_name):
    def get_date(line):
        try:
            return date.fromisoformat(line[:line.find(' ')])
        except ValueError:
            return None
    def get_sender(line):
        return line[line.find('<') + 1 : line.find('>')]
    def get_message(line):
        return line[line.find('>') + 2:]

    participants = set([normalize_name(get_sender(m)) for m in convo if get_date(m) is not None])
    if user_name in participants:
        participants.remove(user_name)
    if len(participants) == 0:
        return []
    if len(participants) != 1 and not enable_group_chats:
        return []

    def get_local_participants(sender):
        sender = normalize_name(sender)
        if sender == user_name:
            return participants
        else:
            return set([sender])

    messages = []
    last_message = None
    for line in convo:
        dt = get_date(line)
        if dt is not None:
            if last_message is not None:
                last_message[2] = get_message_weight(last_message[2])
                messages.append(last_message)
            last_message = [
                dt,
                get_local_participants(get_sender(line)),
                get_message(line)
            ]
        else:
            assert last_message is not None
            last_message[2] += '\n' + line
    if last_message is not None:
        last_message[2] = get_message_weight(last_message[2])
        messages.append(last_message)
    return messages

def get_all_gtalk_messages(
        data_directory,
        user_name,
        start_date):
    all_messages = []
    for msg_file in [os.path.join(data_directory, c) for c in os.listdir(data_directory)]:
        with open(msg_file) as f:
            convo = [l for l in f.readlines()]
            all_messages.extend(process_gtalk_conversation(convo, user_name))

    return all_messages

def get_all_iphone_messages(
        data_directory,
        user_name,
        start_date):
    contact_mapping = {}
    with open(os.path.join(data_directory, 'contacts.csv')) as csvfile:
        contacts_reader = csv.reader(csvfile)
        for row in contacts_reader:
            normalized_number = re.sub('[- ()]', '', row[0])
            full_name = (row[1] + ' ' + row[2]).strip()
            # contact_mapping[normalized_number] = full_name
            if len(normalized_number) == 10 and normalized_number.isnumeric():
                contact_mapping['+1' + normalized_number] = full_name
            elif len(normalized_number) == 11 and normalized_number.isnumeric() and normalized_number.startswith('1'):
                contact_mapping['+' + normalized_number] = full_name
            elif len(normalized_number) == 12 and normalized_number[1:].isnumeric() and normalized_number.startswith('+1'):
                contact_mapping[normalized_number] = full_name
            elif '@' in normalized_number:
                contact_mapping[normalized_number] = full_name
            else:
                print(normalized_number)
                contact_mapping[normalized_number] = full_name

    def get_name(contact):
        return contact_mapping.get(contact) or contact

    all_messages = []
    with open(os.path.join(data_directory, 'messages.csv')) as csvfile:
        messages_reader = csv.reader(csvfile)
        for row in messages_reader:
            dt = date.fromisoformat(row[0][:row[0].find(' ')])
            interlocutor = normalize_name(get_name(row[1]))
            weight = get_message_weight(row[2])
            all_messages.append((dt, set([interlocutor]), weight))

    return all_messages

def main():
    start_date_str = sys.argv[1]
    start_date = datetime.strptime(start_date_str, '%Y-%m-%d').date()
    end_date_str = sys.argv[2]
    end_date = datetime.strptime(end_date_str, '%Y-%m-%d').date()
    user_name = sys.argv[3]
    messages_by_day_by_person = {}
    for arg in sys.argv[4:]:
        format_spec, data_dir = arg.split(':')
        data_dir = os.path.expanduser(data_dir)
        if format_spec == 'facebook':
            all_messages = get_all_facebook_messages(data_dir, user_name, start_date)
        elif format_spec == 'adium':
            all_messages = get_all_adium_messages(data_dir, user_name, start_date)
        elif format_spec == 'hangouts':
            all_messages = get_all_hangouts_messages(data_dir, user_name, start_date)
        elif format_spec == 'gtalk':
            all_messages = get_all_gtalk_messages(data_dir, user_name, start_date)
        elif format_spec == 'iphone':
            all_messages = get_all_iphone_messages(data_dir, user_name, start_date)
        aggregate_messages(messages_by_day_by_person, all_messages)

    graph_messages_window(messages_by_day_by_person, start_date, end_date)

if __name__ == "__main__":
    main()


import uuid
import datetime

from app.main import db
from app.main.model.resource_access import ResourceAccess

def create(data):

    new_item = ResourceAccess(
        resource_id=data['resource_id'],
        persons_id=data['persons_id'],
        roles_id=data['roles_id'],
        is_active=data['is_active'],
        created_at = datetime.datetime.utcnow()
    )
    save_changes(new_item)
    response_object = {
        'status': 'success',
        'message': 'Successfully registered.'
    }
    return response_object, 201

def get_all():
    return ResourceAccess.query.all()

def get_one(id):
    return ResourceAccess.query.filter_by(id=id).first()

def update(id,data):
    item = ResourceAccess.query.filter_by(id=id).first()
    if item:

        item.resource_id = data['resource_id'] if 'resource_id' in data else item.resource_id
        item.persons_id = data['persons_id'] if 'persons_id' in data else item.persons_id
        item.is_active = data['is_active'] if 'is_active' in data else item.is_active
        item.updated_at = datetime.datetime.utcnow()

        db.session.commit()

        response_object = {
        'status': 'success',
        'message': 'Successfully updated'
        }
        return response_object, 201
    else:
        response_object = {
        'status': 'failure',
        'message': 'Specific person does not exist'
        }
        return response_object, 201

def delete(id):
    item = ResourceAccess.query.filter_by(id=id).first()
    if item:
        db.session.delete(item)
        db.session.commit()
        response_object = {
        'status': 'success',
        'message': 'Successfully deleted'
        }
        return response_object, 201
    else:
        response_object = {
        'status': 'failure',
        'message': 'Specific person does not exist'
        }
        return response_object, 201

def save_changes(data):
    db.session.add(data)
    db.session.commit()


#!/usr/bin/python3
import re
import requests

def fetch_urls(search_term):
    try:
        r = requests.get("http://youtube.com/results?search_query=" + '+'.join(search_term.split()))
    except requests.HTTPError as err:
        print(err)
        exit()

    urls = re.findall('{"videoId":"(\w+)"', r.text)
    urls = list(map(lambda x: 'https://youtube.com/embed/' + x, (sorted(set(urls), key=urls.index))))
    return urls


import os.path
import pytest
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException, TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

from .page_objects import PLUGIN_NAME, PageObjectContainer

class TestCase(object):
    """
    Subclasses have to declare the following fields:
        self.test_name
        self.selenium
    """
    def take_screenshot(self, name):
        """Saves a screenshot into the current directory"""
        if not self.test_name:
            raise RuntimeError('self.test_name is not set')
        filename = '{}__{}.png'.format(self.test_name, name)
        self.selenium.get_screenshot_as_file(os.path.abspath(filename))

    def then_no_js_error(self):
        # fetching browser logs is not supported on IE
        # http://stackoverflow.com/questions/27796950/how-to-get-the-browser-console-logs-of-internet-explorer-using-python-selenium
        # neither on Firefox/geckodriver https://github.com/mozilla/geckodriver/issues/144
        if self.selenium.capabilities['browserName'] in ["internet explorer", "firefox", "MicrosoftEdge"]:
            return
        log = self.selenium.get_log('browser')
        for entry in log:
            message = entry['message']
            assert 'Stack trace:' not in message

class TestConnectPage(TestCase):
    @pytest.fixture(autouse=True)
    def setup(self, base_url: str, console_ip: str, pages: PageObjectContainer, selenium: webdriver.Remote):
        self.base_url = base_url
        self.console_ip = console_ip
        self.ConnectPage = pages.connect_page
        self.OverviewPage = pages.overview_page
        self.selenium = selenium
        self.test_name = None
        return self

    @pytest.mark.nondestructive
    @pytest.mark.verifies(issue='DISPATCH-433')
    def test_open_connect_page(self):
        self.test_name = 'test_open_connect_page'
        self.do_test_open_connect_page()

        self.ConnectPage.wait(self.selenium)
        self.take_screenshot("10")

        # check that when reloaded, the page is not empty below the bar
        self.do_test_open_connect_page()
        self.take_screenshot("20")

    def do_test_open_connect_page(self):
        connect = self.ConnectPage.open(self.base_url, self.selenium)
        connect.wait_for_frameworks()
        return connect

    @pytest.mark.nondestructive
    @pytest.mark.verifies(issue='DISPATCH-433')
    def test_redirect_to_connect_page(self):
        self.test_name = 'test_redirect_to_connect_page'
        bookmark = self.OverviewPage.url(self.base_url)

        self.selenium.get(bookmark)
        self.ConnectPage.wait(self.selenium)
        page = self.ConnectPage(self.selenium)  # check it is not just empty page with toolbar
        self.then_no_js_error()
        self.take_screenshot("10")

    @pytest.mark.nondestructive
    @pytest.mark.verifies(issue='DISPATCH-416')
    @pytest.mark.xfail(reason='DISPATCH-747')
    def test_wrong_ip(self):
        self.test_name = 'test_wrong_ip'
        page = self.given_connect_page()
        page.connect_to('111222', None)

        page.connect_button.click()
        page.wait_for_frameworks()

        self.then_error_message_says('There was a connection error: Unable to connect')
        self.take_screenshot('20')

        self.then_no_js_error()

    @pytest.mark.nondestructive
    @pytest.mark.verifies(issue='DISPATCH-428')
    @pytest.mark.xfail(reason='DISPATCH-746, DISPATCH-747')
    def test_wrong_port(self):
        self.test_name = 'test_wrong_port'

        invalid_port = '0'
        closed_port = '11265'

        page = self.given_connect_page()

        page.connect_to('127.0.0.1', invalid_port)
        page.wait_for_frameworks()
        assert not page.connect_button.is_enabled()

        page.connect_to('127.0.0.1', closed_port)
        page.connect_button.click()
        page.wait_for_frameworks()
        self.then_error_message_says("There was a connection error: Unable to connect")
        self.take_screenshot('10')

        self.then_no_js_error()

    @pytest.mark.nondestructive
    @pytest.mark.parametrize("when_correct_details", [
        lambda self, page: self.when_correct_details(page),
        lambda self, page: page.connect_to(self.console_ip),
    ])
    def test_correct_details(self, when_correct_details):
        self.test_name = 'test_correct_details'
        page = self.given_connect_page()
        when_correct_details(self, page)
        page.wait_for_frameworks()
        page.connect_button.click()
        self.then_login_succeeds()
        self.then_no_js_error()

    @pytest.mark.nondestructive
    @pytest.mark.verifies(issue='DISPATCH-439')
    def test_submit_form_with_enter_key(self):
        self.test_name = 'test_submit_form_with_enter_key'
        page = self.given_connect_page()
        self.when_correct_details(page)
        page.port.send_keys(Keys.ENTER)
        self.then_login_succeeds()
        self.then_no_js_error()

    def given_connect_page(self):
        page = self.ConnectPage.open(self.base_url, self.selenium)
        return page

    def when_correct_details(self, page):
        page.connect_to(self.console_ip, '5673')

    def then_login_succeeds(self):
        try:
            self.OverviewPage.wait(self.selenium)
        except TimeoutException:
            pytest.fail("login did not succeed (within time limit)")

    def then_error_message_says(self, message):
        # without any sort of waiting the test is flaky. suggests that wait_for_frameworks does not work well
        locator = (By.CSS_SELECTOR, 'p.ng-binding')
        WebDriverWait(self.selenium, 10).until(EC.text_to_be_present_in_element(locator, message))
        error = self.selenium.find_element(*locator)
        assert error.text == message
        assert error.is_displayed()

    def then_toast_error_says(self, message):
        error = self.selenium.find_element(By.CSS_SELECTOR, '.toast-error .toast-message')
        assert error.text == message
        assert error.is_displayed()


def lengthOfLongestSubstring(s: str) -> int:
    from collections import Counter
    length = len(s)
    if length <= 1:
        return length
    l, r = 0, 1
    res = 0
    while r <= length:
        if l >= r:
            r += 1
            continue
        string = s[l:r]
        print(f'l: {l} r: {r} string: {string}')
        c = dict(Counter(string))
        x = max(list(c.values()))
        if x > 1:
            l += 1
        else:
            res = max(res, r - l)
            r += 1
    return res

if __name__ == "__main__":
    s = 'pwwkew'
    res = lengthOfLongestSubstring(s)
    print(res)


# import csv
# empfile = open("test.csv")
# reader = csv.reader(empfile)

class Person():
    firstname = ""
    lastname = ""
    gender = ""
    id = 0
    personid = 0

    def __init__(self, fn, ln, g):
        self.firstname = fn
        self.lastname = ln
        self.gender = g
        Person.id = Person.id + 1
        self.personid = Person.id

    def get_name(self):
        return self.firstname + " " + self.lastname
#
# print(Person.id)
# m = Person("ES", "Sujatha", "F")
# print(m.firstname)
# print(m.lastname)
# print(m.gender)
# print(m.get_name())
# print(m.__dict__)
#
# print(Person.id)
# s = Person("Sarang", "P", "M")
# print(s.firstname)
# print(s.lastname)
# print(s.gender)
# print(s.get_name())
# print(s.__dict__)
class Salary():
    pay=12000
    def __init__(self,pay):
        self.pay=pay

    def annual_salary(self):
        return self.pay*12

import datetime
class Employee(Person):
    doj = 12-11-2019
    dept = ""
    empid = ""
    salary = None
    def __init__(self,fn,ln,g,doj=datetime.date.today(),dept="OTH",pay=120000):
        Person.__init__(self,fn,ln,g)
        self.doj=doj
        self.dept=dept
        self.empid=dept+"-"+str(self.personid)
        self.salary=Salary(pay)

# p = Employee("AJ", "Parameswaran", "M")
# m = Employee("AP", "Sujatha", "F")
s = Employee("P", "Sarang", "M")
# print(p.__dict__)
# print(p.get_name())
# print(p.firstname, s.lastname)
#
# print(m.__dict__)
# print(m.get_name())
# print(m.firstname, s.lastname)

print(s.__dict__)
print(s.get_name())
print(s.firstname, s.lastname)
print("Pay = ",s.salary.pay)
print("Annual Salary",s.salary.annual_salary())

class Email():
    email = ""
    def __init__(self,email):
        self.email=email

class Phone():
    phone = ""
    def __init__(self,phone):
        self.phone=phone

class Address():
    city = ""
    state = ""
    def __init__(self,city,state):
        self.city=city
        self.state=state

class ContactDetails():
    address = None
    phone = None
    email = None
    def __init__(self,add=None,ph=None,em=None):
        self.address = add
        self.phone = ph
        self.email = em

add1 = Address("Mumbai","MH")
ph1 = Phone(8451033120)
em1 = Email("sarangparameswaran@gmail.com")
c = ContactDetails(add1,ph1,em1)

print(c.__dict__)
print(c.address.city)
print(c.address.state)
print(c.email.email)
print(c.phone.phone)


# file to store all the constants used in the project.
# here you can change the parameters to change the behaviour of the scripts.

# datetime needed for storing dates and times
from datetime import date, time

# defines the dates within which the activities need to be generated
START_DATE = date(2019, 1, 1)
END_DATE = date(2020, 8, 14)

# defines the hour of the day withing which the activities are allowed
START_WORK_HOURS = time(9, 0, 0)
END_WORK_HOURS = time(17, 0, 0)

# date format conversions for writing to json
SHIPMENT_DATE_FORMAT = '%d %b, %Y'
PERFORMED_DATE_FORMAT = '%d-%m-%Y %X %z'

# various options for parameters that are present in activities
STATUS_LIST = ['Open', 'Waiting for Customer', 'Waiting for Third Party', 'Pending', 'Resolved', 'Closed']
CATEGORY_LIST = ['Phone', 'PC', 'Tablet', 'Laptop']
GROUP_LIST = ['exchange', 'refund', 'return', 'RMA', 'repair']
PRODUCT_LIST = ['storage', 'headphone', 'accessory', 'device']
ISSUE_LIST = ['Incident', 'Warranty']

# static strings found in the activities
PERFORMER_TYPE_STR = 'user'

# config for how much two activities can be separated from each other
RAND_TIMEDELTA_DAYS = 7
MIN_TIMEDELTA_DAYS = 1

# number of digits in user's and agent's IDs
RAND_ID_DIGITS = 4

# faker locale profile for localised addresses and emails
FAKER_LOCALE = 'en_AU'

# system arguments defaults for the program
DEFAULT_COUNT = 100
DEFAULT_JSON_FILE = 'activities.json'
DEFAULT_SQLITE_FILE = 'db.sqlite3'


import pygame
import math
from queue import PriorityQueue

# Set the window to be 800 pixels by 800 pixels
WIDTH = 800
HEIGHT = 800
window = pygame.display.set_mode((WIDTH, HEIGHT))

# Display the window
pygame.display.set_caption("Pathfinder")

# Define colors for grid coloring using RGB format
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0) # Start position
PURPLE = (255, 0, 255) # End position
RED = (255, 0, 0) # Already visited
GREEN = (0, 255, 0) # Available path
WHITE = (255, 255, 255) # Unvisited node
BLACK = (0, 0, 0)  # Roadblock

# For A*
# Create grid tiles class to hold values for the algorithm
class Node:
    def __init__(self, row, col, width, height, totalRows): # width can be used here instead of height as we're working with squares
        self.row = row                                      # however for the sake of readability/proper naming conventions and future iterations
        self.col = col                                      # I have used height.
        self.x = row * width
        self.y = col * height
        self.color = WHITE
        self.neighbors = []
        self.width = width
        self.height = height
        self.totalRows = totalRows

    def getPosition(self):
        return self.row, self.col

    # Check to see if a tile has been visited
    def nodeIsClosed(self):
        return self.color == RED

    def nodeIsOpen(self):
        return self.color == GREEN

    def nodeIsBarrier(self):
        return self.color == BLACK

    def nodeIsStart(self):
        return self.color == YELLOW

    def nodeIsEnd(self):
        return self.color == PURPLE

    def reset(self):
        self.color = WHITE

    # Now we define methods to assign/make the colors
    def makeClosed(self):
        self.color = RED

    def makeOpen(self):
        self.color = GREEN

    def makeBarrier(self):
        self.color = BLACK

    def makeStart(self):
        self.color = YELLOW

    def makeEnd(self):
        self.color = PURPLE

    def makePath(self):
        self.color = BLUE

# Define the methods to draw the nodes on screen
    def draw(self, window):
        pygame.draw.rect(window, self.color, (self.x, self.y, self.width, self.height))

    def updateNeighbors(self, grid):
        self.neighbors = [] # Create a list of neighbors

        # Check if we can check our neighbors below(for out of bounds errors) and check if the neighboring nodes are barriers
        if self.row < self.totalRows - 1 and not grid[self.row + 1][self.col].nodeIsBarrier():  #DOWN
            self.neighbors.append(grid[self.row + 1][self.col])
        # Check if we have room above the current node
        if self.row > 0 and not grid[self.row - 1][self.col].nodeIsBarrier():   #UP
            self.neighbors.append(grid[self.row - 1][self.col])

        if self.col > 0 and not grid[self.row][self.col - 1].nodeIsBarrier():  #LEFT
            self.neighbors.append(grid[self.row][self.col - 1])

        if self.col < self.totalRows - 1 and not grid[self.row][self.col + 1].nodeIsBarrier():  #RIGHT
            self.neighbors.append(grid[self.row][self.col + 1])

    def __lt__(self, other):  # Less than operator for comparisons of tiles
        return False

# Heuristic[h(n)] cost for calculations of 2 points(p1 & p2)
def h(p1, p2):
    x1, y1 = p1
    x2, y2 = p2
    return abs(x1 - x2) + abs(y1 - y2)

def remakePath(prevNode, current, draw):
    while current in prevNode:
        current = prevNode[current]
        current.makePath()
        draw()

# A-Star Algorithm
def astar(draw, grid, start, end):
    count = 0
    openSet = PriorityQueue()
    openSet.put((0, count, start)) # Initialize the open set with our F(n), a count for tiebreaker purposes and start node
    prevNode = {}

    # Intilize g(n) and f(n) as infinity for all nodes except start to calculate path costs
    gScore = {node: float("inf") for row in grid for node in row}
    gScore[start] = 0
    fScore = {node: float("inf") for row in grid for node in row}
    fScore[start] = h(start.getPosition(), end.getPosition())

    # Keep track of items in priority queue using a hash
    openSetHash = {start}

    while not openSet.empty():
        for event in pygame.event.get():
            if event.type == pygame.QUIT or event.key == pygame.K_q:
                pygame.quit()

        current = openSet.get()[2] # Current node we're evaluating
        openSetHash.remove(current)

        if current == end:
            remakePath(prevNode, end, draw)
            # Reset the colors of start and end nodes
            start.makeStart()
            end.makeEnd()
            return True # we found the path!

        # Evaluate f/g scores of the current and neighbor nodes
        for neighbor in current.neighbors:
            tempGscore = gScore[current] + 1

            if tempGscore < gScore[neighbor]: # Update pathing if a better path is found
                prevNode[neighbor] = current
                gScore[neighbor] = tempGscore
                fScore[neighbor] = tempGscore + h(neighbor.getPosition(), end.getPosition())

                if neighbor not in openSetHash:
                    count += 1
                    openSet.put((fScore[neighbor], count, neighbor))
                    openSetHash.add(neighbor)
                    neighbor.makeOpen()
        draw()

        if current != start: # If the current node is not the start node...
            current.makeClosed() # Make it closed as we've already considered it's f/g/h scores in the prev for loop
    return False

# Make the grid
def makeGrid(rows, width):
    grid = []
    gap = width // rows # Use integer division to calculate width of tiles

    for i in range(rows):
        grid.append([])
        for j in range(rows):
            tile = Node(i, j, gap, gap, rows)
            grid[i].append(tile)

    return grid

def drawGridlines(window, rows, width):
    gap = width // rows

    # Draw gridlines
    for i in range(rows):
        pygame.draw.line(window, RED, (0, i*gap), (width, i*gap))
        for j in range(rows):
            pygame.draw.line(window, RED, (j*gap, 0), (j*gap, width))

def drawGrid(window, grid, rows, width):
    window.fill(WHITE)

    for row in grid:
        for node in row:
            node.draw(window)

    drawGridlines(window, rows, width)
    pygame.display.update()

def getClickedPos(pos, rows, width):
    gap = width // rows
    x, y = pos

    row = x // gap
    col = y // gap

    return row, col

def main(window, width):
    ROWS = 20
    grid = makeGrid(ROWS, width)

    # Some helper variables to keep track of program state
    start = None
    end = None

    run = True
    started = False

    while run:
        drawGrid(window, grid, ROWS, WIDTH)
        for event in pygame.event.get():  # Loop through events and check them
            if event.type == pygame.QUIT:
                run = False
            if started:
                continue
            if pygame.mouse.get_pressed()[0]: # Check for LMB press
                pos = pygame.mouse.get_pos()
                row, col = getClickedPos(pos, ROWS, width)
                node = grid[row][col]

                if not start and node != end:
                    start = node
                    start.makeStart()
                elif not end and node != start:
                    end = node
                    end.makeEnd()
                elif node != end and node != start:
                    node.makeBarrier()

            elif pygame.mouse.get_pressed()[2]: # RMB
                pos = pygame.mouse.get_pos()
                row, col = getClickedPos(pos, ROWS, width)
                node = grid[row][col]
                node.reset()

                if node == start:
                    start = None
                elif node == end:
                    end = None
            # Configure keybindings
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_q:
                    run = False
                if event.key == pygame.K_SPACE and not started:
                    for row in grid:
                        for node in row:
                            node.updateNeighbors(grid)

                    astar(lambda: drawGrid(window, grid, ROWS, width), grid, start, end)

                if event.key == pygame.K_c: # Reset the grid
                    start = None
                    end = None
                    grid = makeGrid(ROWS, width)

    pygame.quit()

main(window, WIDTH)


import numpy as np
import pytest
import xarray as xr
from numpy.testing import assert_array_almost_equal

def test_radial_default(client):
    graph = xr.Dataset.from_dict(client.get("/graphs/radial").get_json()["graph"])

    assert graph.dims == {
        "cell": 13,
        "corner": 36,
        "face": 48,
        "link": 60,
        "node": 25,
        "patch": 36,
        "max_cell_faces": 6,
        "max_patch_links": 3,
        "Two": 2,
    }

def test_radial_default_shape(client):
    graph_1 = xr.Dataset.from_dict(client.get("/graphs/radial").get_json()["graph"])
    graph_2 = xr.Dataset.from_dict(
        client.get("/graphs/radial?shape=3,4").get_json()["graph"]
    )

    assert_array_almost_equal(graph_1.x_of_node, graph_2.x_of_node)
    assert_array_almost_equal(graph_1.y_of_node, graph_2.y_of_node)

def test_radial_default_spacing(client):
    graph_1 = xr.Dataset.from_dict(client.get("/graphs/radial").get_json()["graph"])
    graph_2 = xr.Dataset.from_dict(
        client.get("/graphs/radial?spacing=1").get_json()["graph"]
    )

    assert_array_almost_equal(graph_1.x_of_node, graph_2.x_of_node)
    assert_array_almost_equal(graph_1.y_of_node, graph_2.y_of_node)

def test_radial_default_origin(client):
    graph_1 = xr.Dataset.from_dict(client.get("/graphs/radial").get_json()["graph"])
    graph_2 = xr.Dataset.from_dict(
        client.get("/graphs/radial?origin=0.0,0.0").get_json()["graph"]
    )

    assert_array_almost_equal(graph_1.x_of_node, graph_2.x_of_node)
    assert_array_almost_equal(graph_1.y_of_node, graph_2.y_of_node)

@pytest.mark.parametrize("spacing", (0.5, 1.0, 2.0, 4.0))
def test_radial_spacing(client, spacing):
    url = "/graphs/radial?spacing={0}".format(spacing)
    graph = xr.Dataset.from_dict(client.get(url).get_json()["graph"])
    unit = xr.Dataset.from_dict(
        client.get("/graphs/radial?spacing=1.0").get_json()["graph"]
    )

    assert_array_almost_equal(
        np.sqrt(graph.x_of_node**2 + graph.y_of_node**2),
        np.sqrt(unit.x_of_node**2 + unit.y_of_node**2) * spacing,
        5,
    )

@pytest.mark.parametrize("y0", (-1.0, 1.0, 2.0, 4.0))
@pytest.mark.parametrize("x0", (-1.0, 1.0, 2.0, 4.0))
def test_radial_origin(client, x0, y0):
    url = "/graphs/radial?origin={0},{1}".format(y0, x0)
    graph = xr.Dataset.from_dict(client.get(url).get_json()["graph"])
    centered = xr.Dataset.from_dict(
        client.get("/graphs/radial?origin=0.0,0.0").get_json()["graph"]
    )

    assert_array_almost_equal(graph.x_of_node, centered.x_of_node + x0)
    assert_array_almost_equal(graph.y_of_node, centered.y_of_node + y0)


import os
import sys
import collections
import numpy as np

class graph(object):
    def __init__(self):
        self.n_nodes = 0
        self.n_edges = 0
        self.n_feature = 0
        self.graph_dict = collections.defaultdict(list)
        self.feature_embed = None

    def read_graph_files(self, file_path):
        assert os.exists(graph_path)
        assert not os.path.isdir(graph_path)

        fp = open(file_path, "r")
        for line in fp:
            tmp = line.strip("\n").split(' ')
            src, trg = int(tmp[0]), int(tmp[1])
            self.graph_dict[trg].append(src)
            self.n_edges += 1
        self.n_nodes = len(graph)
        print("{}\n{}\n{}".format(file_path, nodes, n_edges))

    def gen_graph_embedding(self, n_features):
        self.n_feature = n_features
        self.feature_embed = np.random.rand(self.nodes, self.n_feature)


from flask import Flask, render_template, redirect, url_for, request
from collections import defaultdict as ddict

app = Flask(__name__)

ban_dict = ddict(lambda: False)
# use decorators to link the function to a url
@app.route('/')
def home():
    return "Hello, World!"  # return a string

@app.route('/welcome')
def welcome():
    return render_template('welcome.html')  # render a template

def val_login_page(request):
    if request.form['username'] != 'admin' or request.form['password'] != 'admin':
        error = 'Invalid Credentials. Please try again.'
    else:
        return render_template('manager.html')

def check_ban(worker_id):
    return ban_dict[worker_id]

def ban_worker(worker_id):
    ban_dict[worker_id] = True

def unban_worker(worker_id):
    ban_dict[worker_id] = False

def get_banned_workers():
    banned = []
    for k, v in ban_dict.iteritems():
        if v:
            banned.append(k)
    return banned

@app.route('/manager', methods=['GET', 'POST'])
def manager():
    error = None
    if request.method != 'POST':
        # first time on the page
        return render_template('manager.html', error=error).replace('REPLACE_ME',info_string)
    if request.form['username'] != 'admin' or request.form['password'] != 'admin':
        error = 'Invalid Credentials.'
        return render_template('manager.html', error=error).replace('REPLACE_ME',info_string)
    info_string = ''
    to_check = [x.strip().upper() for x in request.form['check_ban'].split(',')]
    to_check = filter(lambda x: len(x), to_check)
    to_ban = [x.strip().upper() for x in request.form['ban_worker'].split(',')]
    to_ban = filter(lambda x: len(x), to_ban)
    to_unban = [x.strip().upper() for x in request.form['unban_worker'].split(',')]
    to_unban = filter(lambda x: len(x), to_unban)
    is_banned = [check_ban(x) for x in to_check]
    _ = [ban_worker(x) for x in to_ban]
    _ = [unban_worker(x) for x in to_unban]
    if len(to_check):
        info_string += 'TO CHECK
'
        for tochk, chkv in zip(to_check, is_banned):
            info_string += tochk + ': ' + str(chkv) + '
'
        info_string += '
'
    if len(to_ban):
        info_string += 'TO BAN
'
        info_string += '
'.join(to_ban)
        info_string += '

'
    if len(to_unban):
        info_string += 'TO UNBAN
'
        info_string += '
'.join(to_unban)
        info_string += '

'
    if request.form['submit'] == 'Submit':
        return render_template('manager.html').replace('REPLACE_ME',info_string)
    elif request.form['submit'] == 'List Banned':
        is_banned = get_banned_workers()
        info_string += 'BANNED WORKERS
'
        info_string += '
'.join(is_banned) + '

'
    elif request.form['submit'] == 'Stop':
        info_string += 'Stopping
'
    elif request.form['submit'] == 'Halt':
        info_string += 'Halting
'
    elif request.form['submit'] == 'Shutdown':
        info_string += 'Shutting down
'
    return render_template('manager.html').replace('REPLACE_ME',info_string)

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


from aiohttp import ClientSession
import config
import re

commands = {}

def command(auth=None, aliases=None):
    def inner(func):
        name = func.__name__.lstrip('_')
        commands[name] = [func, auth, aliases]
    return inner

def is_botowner(message):
    return message.author.id in config.config["owners"]

def is_moderator(message):
    if not hasattr(message, "guild"):
        return True
    return message.author.guild_permissions.manage_messages

def cleantext(message):
    if not message:
        return None
    message = re.sub(r"(http://|https://)?(?:discord(?:(?:.|.?dot.?)"
                     r"(?:gg|me|li|to|link)|app(?:.|.?dot.?)"
                     r"com\/invite)|(invite|disco)(?:.|.?dot.?)gg)\/"
                     r"[\da-z]+",r"[INVITE REDACTED]",
                      str(message),
                      flags=re.I|re.M
                    )
    message = message.replace("@everyone","[@\u200beveryone]")
    message = message.replace("@here","[@\u200bhere]")
    return message

async def send(message, text=None, embed=None):
    return await message.channel.send(cleantext(text), embed=embed)

async def reply(message, text=None, embed=None, mention=False):
    return await message.reply(cleantext(text), embed=embed)

async def fetch(url, agent='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'):
    async with ClientSession(headers={'User-Agent': agent}) as session:
        async with session.get(url) as response:
            return await response.read()


#-*- encoding: utf-8 -*-

from django.db import models

class TournamentManager(models.Manager):

    def get_current(self):
        result = Tournament.objects.filter(
                    active=True).order_by('-starting_date')
        if result:
            return result[0]
        else:
            return None

class Category(models.Model):
    name = models.CharField(max_length=30)

    def __unicode__(self):
        return self.name

    def get_tournaments_list(self):
        tournaments = []
        elements = CategoryInTournament.objects.filter(category=self)
        for elem in elements:
            tournaments.append(elem.tournament)

        return tournaments

class Tournament(models.Model):
    name = models.CharField(max_length=20)
    starting_date = models.DateField()
    ending_date = models.DateField()
    image = models.URLField(blank=True, verify_exists=False, max_length=200)
    active = models.BooleanField(default=True)

    objects = TournamentManager()

    def __unicode__(self):
        return self.name

    def get_categories_list(self):
        categories = []
        elements = CategoryInTournament.objects.filter(tournament=self)
        for elem in elements:
            categories.append(elem.category)

        return categories

class CategoryInTournament(models.Model):
    category = models.ForeignKey(Category, related_name='rel_tournaments')
    tournament = models.ForeignKey(Tournament, related_name='rel_categories')

    def __unicode__(self):
        return self.category.name + ' in ' + self.tournament.name

class Player(models.Model):
    name = models.CharField(max_length=50)
    license = models.CharField(max_length=20)

    def __unicode__(self):
        return self.name

class Match(models.Model):
    player1 = models.ForeignKey(Player, related_name='matches1')
    player2 = models.ForeignKey(Player, related_name='matches2')
    player3 = models.ForeignKey(Player, related_name='matches3',
            blank=True, null=True)
    player4 = models.ForeignKey(Player, related_name='matches4',
            blank=True, null=True)
    match_time = models.DateTimeField()
    tournament = models.ForeignKey(Tournament, related_name='matches')
    category = models.ForeignKey(Category, default=0,
            related_name='matches')

    player1_saw_timetable = models.BooleanField(default=False)
    player2_saw_timetable = models.BooleanField(default=False)
    player3_saw_timetable = models.BooleanField(default=False)
    player4_saw_timetable = models.BooleanField(default=False)

    def __unicode__(self):
        return self.player1.name + ' vs ' + self.player2.name


import logging
import os
from datetime import datetime

from aiogram import Bot, types
from aiogram.types import InputFile

from src.cryptach_screener.config.config import Config
from src.cryptach_screener.signal.simple import SimpleSignal

logger = logging.getLogger(__name__)

class TelegramPoster(object):
    def __init__(self, config: Config):
        self.config = config

        self.bot = Bot(token=config.token, parse_mode=types.ParseMode.HTML)

    async def post_signal(self, channel_id: str, direction: str, symbol: str, timeframe: str, image_path: str = None):
        text = f'{symbol}\n' \
               f'{direction}\n' \
               f'{timeframe} '
        logger.info(f'posting message:\n{text}')
        if image_path is not None and os.path.isfile(image_path):
            image = InputFile(image_path)
            result = await self.bot.send_photo(chat_id=channel_id, photo=image, caption=text)
            os.remove(image_path)
        else:
            result = await self.bot.send_message(channel_id, text)
        signal = SimpleSignal(
            timeframe=timeframe,
            text=text,
            posting_time=datetime.now(),
            message_id=result.message_id,
            symbol=symbol
        )
        return signal

    async def send_message(self, channel_id: int, text: str):
        await self.bot.send_message(channel_id, text)


import os
from time import sleep

from hlt.clean_execution import CleanBasf2Execution
from zmq_daq.example_support import get_sockets
from zmq_daq.utils import get_monitor_table, show_monitoring, write_monitoring

import yaml
import argparse

def yaml_settings(yaml_file):
    with open(yaml_file, "r") as f:
        return yaml.load(f)

def command_load(args):
    execution = CleanBasf2Execution()

    for app in args.settings_file["programs"]:
        execution.start(app)

    try:
        execution.wait()
    except KeyboardInterrupt:
        pass

def command_monitor(args):
    # Create and connect all needed sockets
    sockets = get_sockets(args.settings_file)

    # When no additional things are requested, just show the table once and exit
    if not args.watch and not args.dat:
        df = get_monitor_table(sockets, show_detail=args.show_detail)
        show_monitoring(df)
        exit()

    # Else we go into a main loop
    if args.dat:
        f = open(args.dat, "wb")
    try:
        while True:
            if args.watch:
                os.system("clear")

            df = get_monitor_table(sockets, show_detail=args.show_detail)
            if args.watch:
                show_monitoring(df)

            if args.dat:
                write_monitoring(df, f)

            sleep(0.5)
    finally:
        if args.dat:
            f.close()

def command_start(args):
    sockets = get_sockets(args.settings_file)
    for socket in sockets.values():
        socket.send_multipart([b"n", b"", b""])

def command_input_file(args):
    execution = CleanBasf2Execution()

    input_port = args.settings_file["input"]
    remaining_args = []
    if args.raw:
        remaining_args += ["--raw"]
    if args.repeat:
        remaining_args += ["--repeat"]
    execution.start(["b2hlt_file2socket", args.data_file, str(input_port)] + remaining_args)

    try:
        execution.wait()
    except KeyboardInterrupt:
        pass

def command_stop(args):
    sockets = get_sockets(args.settings_file)
    sockets["distributor"].send_multipart([b"l", b"", b""])

    if args.all:
        for socket in sockets.keys():
            if socket == "distributor":
                continue

            sockets[socket].send_multipart([b"l", b"", b""])

def command_terminate(args):
    sockets = get_sockets(args.settings_file)
    sockets["distributor"].send_multipart([b"x", b"", b""])

    if args.all:
        for socket in sockets.keys():
            if socket == "distributor":
                continue

            sockets[socket].send_multipart([b"x", b"", b""])

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="""Try out different modes for the ZMQ HLT.
    By choosing the settings_file, the different modes can be chosen.
    Together with the settings file, a command needs to be chosen.
    Typically, this will be "load" in one console and "input_file" in a different console.
    You can then monitor the process either with the "monitor" command
    or by using "b2hlt_monitor.py".
    """)

    parser.add_argument("settings_file", type=yaml_settings,
                        help="Which config file to load for the test")

    subparsers = parser.add_subparsers(help="Choose the command", dest="command")
    subparsers.required = True

    subparser = subparsers.add_parser("load")
    subparser.set_defaults(func=command_load)

    subparser = subparsers.add_parser("monitor")
    subparser.add_argument(
        "--show-detail",
        action="store_true",
        help="By default, some information are omitted. With this flag, all details are shown (can be very long output).")
    subparser.add_argument("--watch", action="store_true", help="Enter watch mode, where the script is called every 1 second.")
    subparser.add_argument("--dat", help="Write out the results of the monitoring periodically into a dat file. " +
                           "If not combined with --watch, the output will not be shown.")
    subparser.set_defaults(func=command_monitor)

    subparser = subparsers.add_parser("send_stop")
    subparser.add_argument("--all", action="store_true", help="Send the signal to all processes")
    subparser.set_defaults(func=command_stop)

    subparser = subparsers.add_parser("send_terminate")
    subparser.add_argument("--all", action="store_true", help="Send the signal to all processes")
    subparser.set_defaults(func=command_terminate)

    subparser = subparsers.add_parser("send_start")
    subparser.set_defaults(func=command_start)

    subparser = subparsers.add_parser("input_file")
    subparser.add_argument("data_file", help="Which data file to send")
    subparser.add_argument("--raw", help="send and receive raw data instead of event buffers", action="store_true")
    subparser.add_argument("--repeat", help="repeat after the file is finished", action="store_true")
    subparser.set_defaults(func=command_input_file)

    args = parser.parse_args()
    args.func(args)


# !usr/bin/env python2
# -*- coding: utf-8 -*-
#
# Licensed under a 3-clause BSD license.
#
# @Author: Brian Cherinka
# @Date:   2017-05-31 10:27:23
# @Last modified by:   Brian Cherinka
# @Last Modified time: 2017-06-01 00:36:24

import pytest
from stagemanager.stagemanager import StageManager

@pytest.fixture()
def start_sm(sm):
    sm.start_actor()
    yield sm

class TestStageManager(object):
    def test_start(self, sm, capsys):
        pid = sm.get_pid()
        assert pid is None
        sm.start_actor()
        out, err = capsys.readouterr()
        assert "Starting new {0}".format(sm.actor) in out
        assert sm.process.pid is not None

    def test_stop(self, start_sm, capsys):
        assert start_sm.process.pid is not None
        start_sm.stop_actor()
        out, err = capsys.readouterr()
        assert "Stopping product {0}".format(start_sm.actor) in out
        pid = start_sm.get_pid()
        assert pid is None

    def test_get_status(self, start_sm, capsys):
        start_sm.get_status()
        out, err = capsys.readouterr()
        assert "{0} is running".format(start_sm.actor) in out
        assert start_sm.process.pid is not None

    def test_kill(self, start_sm, capsys):
        assert start_sm.process.pid is not None
        start_sm.kill_actor()
        out, err = capsys.readouterr()
        assert "Killing product {0}".format(start_sm.actor) in out
        pid = start_sm.get_pid()
        assert pid is None

    def test_restart(self, start_sm, capsys):
        oldpid = start_sm.get_pid()
        start_sm.restart_actor()
        newpid = start_sm.get_pid()
        out, err = capsys.readouterr()
        assert oldpid != newpid
        assert "Stopping product {0}".format(start_sm.actor) in out
        assert "Starting new {0}".format(start_sm.actor) in out

    def test_getprocesses(self, start_sm):
        procs = start_sm.get_processes()
        assert procs is not None

    def test_listprocesses(self, start_sm, capsys):
        start_sm.list_processes()
        out, err = capsys.readouterr()
        assert start_sm.actor in out

class TestStageSetupEnv(object):
    @pytest.mark.parametrize("name", [("modules"), ("eups")])
    def test_no_setups(self, sm, unload, name):
        prodpath = sm._get_actor_path()
        assert prodpath is None
        with pytest.raises(RuntimeError):
            sm.__getattribute__("_try_{0}".format(name))()

    @pytest.mark.parametrize(
        "host, user, errmsg",
        [
            (None, None, "Current Host must be sdss4-hub"),
            (True, None, "Current User must be sdss4"),
        ],
        ids=["wronghost", "wronguser"],
    )
    def test_wrongsystem(self, actor, host, user, errmsg):
        with pytest.raises(AssertionError) as cm:
            StageManager(actor=actor, overhost=host, overuser=user)
        assert errmsg in str(cm.value)


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

from sklearn.datasets import fetch_covtype
from khds import parser, Experiment
from khds import UniversalDataset
from khds import Algorithm
from khds import LinearNet
import pandas as pd

class TabularDataset(UniversalDataset):

    '''
    Name                    Abbr # Train # Validation # Test # Num # Cat Task type Batch size
    California Housing      CA      13209       3303        4128 8 0 Regression 256
    Adult                   AD      26048       6513        16281 6 8 Binclass 256
    Helena                  HE      41724       10432       13040 27 0 Multiclass 512
    Jannis                  JA      53588       13398       16747 54 0 Multiclass 512
    Higgs Small             HI      62752       15688       19610 28 0 Binclass 512
    ALOI                    AL      69120       17280       21600 128 0 Multiclass 512
    Epsilon                 EP      320000      80000       100000 2000 0 Binclass 1024
    Year                    YE      370972      92743       51630 90 0 Regression 1024
    Covtype                 CO      371847      92962       116203 54 0 Multiclass 1024
    Yahoo                   YA      473134      71083       165660 699 0 Regression 1024
    Microsoft               MI      723412      235259      241521 136 0 Regression 1024
    '''

    def __init__(self, name, train=True, seed=3463):
        super().__init__()

        if name == 'ca':
            data = fetch_covtype()
            labels = data['target']
            data = pd.DataFrame(data['data'])

        elif name == 'ja':
            data = pd.read_csv('jannis.csv')
            labels = data['class']
            data = data.drop(columns=['class'])

        else:
            raise NotImplementedError

        self.data = torchvision.datasets.MNIST(root=path, train=train, transform=torchvision.transforms.ToTensor())

    def __getitem__(self, index):
        return {'x': self.data.data[index].float() / 255, 'y': self.data.targets[index]}

    def __len__(self):
        return len(self.data)

class MNISTAlgorithm(Algorithm):

    def __init__(self, *args, **argv):
        super().__init__(*args, **argv)
        self.scheduler = torch.optim.lr_scheduler.ExponentialLR(self.optimizers['net'].dense, gamma=0.99)

    def postprocess_epoch(self, sample, aux, results, epoch, train=True):

        x, y = sample['x'], sample['y']

        results['images']['sample'] = x[:16].view(16, 1, 28, 28).data.cpu()

        if train:
            self.scheduler.step()
            results['scalar'][f'lr'] = self.optimizers['net'].dense.param_groups[0]['lr']

        aux = {}
        return aux, results

    def iteration(self, sample, aux, results, train=True):

        x, y = sample['x'], sample['y']

        x = x.view(len(x), -1)
        net = self.networks['net']
        opt = self.optimizers['net']

        y_hat = net(x)
        loss = F.cross_entropy(y_hat, y, reduction='mean')

        if train:

            opt.zero_grad()
            loss.backward()
            opt.step()

        # add scalar measurements
        results['scalar']['loss'].append(float(loss))
        results['scalar']['acc'].append(float((y_hat.argmax(1) == y).float().mean()))
        aux = {}

        return aux, results

def run_mnist(rank, world_size, experiment):

    dataloader = {}
    for k, v in {'train': True, 'test': False}.items():

        dataloader[k] = MNISTDataset(experiment.path_to_data, train=v).dataloader(batch_size=experiment.batch_size,
                                                                       num_workers=experiment.cpu_workers,
                                                                       pin_memory=True)

    # choose your network
    net = LinearNet(784, 256, 10, 4)

    # we recommend using the algorithm argument to determine the type of algorithm to be used
    Alg = globals()[experiment.algorithm]
    alg = Alg(net, dataloader, experiment)

    # simulate input to the network
    x = next(alg.data_generator(train=False))[1]['x']
    x = x.view(len(x), -1)

    experiment.writer_control(enable=not(bool(rank)), networks=alg.get_networks(), inputs={'net': x})

    for results in iter(alg):
        experiment.save_model_results(results, alg,
                                      print_results=True, visualize_results='yes',
                                      store_results='logscale', store_networks='logscale',
                                      visualize_weights=True,
                                                    argv={'images': {'sample': {'dataformats': 'NCHW'}}})

if __name__ == '__main__':

    # here you put all actions which are performed only once before initializing the workers
    # for example, setting running arguments and experiment:

    args = parser.parse_args()

    # we can set here arguments that are considered as constant for this file (mnist_example.py)
    args.project_name = 'mnist'
    args.root_dir = '/home/shared/data/results'
    args.algorithm = 'MNISTAlgorithm'
    args.path_to_data = '/home/elad/projects/mnist'

    experiment = Experiment(args)

    # here we initialize the workers (can be single or multiple workers, depending on the configuration)
    experiment.run(run_mnist)


import sys, json
import awspice
import botocore
if sys.version_info >= (3, 3):
    from unittest.mock import patch
else:
    from mock import patch

calls = [
    'DescribeInstances',
]

def load(filepath):
    with open(filepath) as file:
        content = json.loads(file.read())
    return content

@patch("botocore.client.BaseClient._make_api_call")
def test_get_instances(mock):
    mock.return_value=load('test/data/ec2/instances.json')
    region = 'eu-west-1'
    x = awspice.connect(region).service.ec2.get_instances()
    assert all(instance['Region']['RegionName'] == region for instance in x)


import cv2
from keras.models import load_model
import numpy as np
face_cascade = cv2.CascadeClassifier("C:/Users/Dell/AppData/Local/Programs/Python/Python310/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml")
result=["DoMixi","Nhism","Phuong","Ram-bo","Thay ba"]
model=load_model("nhan_dien.h5")
def anh(dirr):
    img=cv2.imread(dirr)
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, 1.3,5)

    for (x,y,w,h) in faces:
        roi=cv2.resize(img[y:y+h,x:x+w],(64,64))
        kq=np.argmax(model.predict(roi.reshape(-1,64,64,3)))
        cv2.putText(img,result[kq],(x+10,y-10),cv2.FONT_HERSHEY_COMPLEX,0.5,(255,0,0))
    while True:
        cv2.imshow('Face Detection',img)

        # Nhấn 'q' để thoát
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
def vd(dirr=0):
    cap=cv2.VideoCapture(dirr)
    while True:
        ret,fram=cap.read()
        if ret==False:
            break
        gray = cv2.cvtColor(fram, cv2.COLOR_BGR2GRAY)

        faces = face_cascade.detectMultiScale(gray, 1.3,5)
        for (x,y,w,h) in faces:
            roi=cv2.resize(fram[y:y+h,x:x+w],(64,64))
            kq=np.argmax(model.predict(roi.reshape(-1,64,64,3)))
            cv2.putText(fram,result[kq],(x+10,y-10),cv2.FONT_HERSHEY_COMPLEX,0.5,(255,0,0),1)
        cv2.imshow('Face Detection',fram)
        if cv2.waitKey(1)  & 0xFF == ord('q'):
            break

if __name__=="__main__":
    vd(0)
    # anh("C:\\Users\\Dell\\Pictures\\Screenshots\\Screenshot 2023-06-30 213401.png")


from django.conf.urls import url
from django.urls import path, include

from rest_framework import routers

from .views import (
    ImgView,
    LogicImgView, OptImgView, ImgUtilView
)
app_name = 'kuukann'

router = routers.DefaultRouter()
router.register(r'img', ImgView)

urlpatterns = [
    url(r'^', include(router.urls)),

    path('logic_img', LogicImgView.as_view()),
    path('opt_img/<int:lucy>', OptImgView.as_view()),
    path('util_img/<int:lucy>', ImgUtilView.as_view())
]


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

import os
import glob
import shutil

import conf
from web.models import Shelter, Category, ShelterPicture
from bootstrap import db

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

import os
import glob
import shutil

import conf
from web.models import Shelter, Category, ShelterPicture
from bootstrap import db
from PIL import Image, ImageFile
from os.path import join

from sqlalchemy import func

def insensitive_glob(pattern):
    def either(c):
        return '[%s%s]'%(c.lower(),c.upper()) if c.isalpha() else c
    return glob.glob(''.join(map(either,pattern)))

def build_replace_func(chars, attr, replace_with=''):
    for character in chars:
        attr = func.replace(attr, character, replace_with)
    return attr

def import_shelters_pictures(folder):

    ImageFile.LOAD_TRUNCATED_IMAGES = True
    imgwidth = 1280
    types = ('*.jpg', '*.jpeg', '*.png', '*.gif')

    shelters = Shelter.query.all()

    for shelter in shelters:
        shelter_rid = shelter.get_values_of_attribute(attribute_name='ID')[0].name
        print("Shelter_rid '{}' ...".format(shelter_rid))
        print("Shelter id '{}' ...".format(shelter.id))

        files = []
        for ext in types:
              files.extend(insensitive_glob(join(folder + shelter_rid + '/', ext)))

        for picture in files:
            picture_name = os.path.splitext(os.path.basename(picture))[0]+'.jpg'
            print("Picture name '{}' ...".format(picture_name))

            try:
                category_name = picture_name.split('_')[1]
                picture_subject = os.path.splitext(picture_name.split('_')[2])[0]
            except:
                print("failed")
                continue

            IGNORE_CHARS = [' ']
            needle = build_replace_func(IGNORE_CHARS, Category.name)
            print("Picture subject '{}' ...".format(picture_subject))
            print("Category name '{}' ...".format(category_name))
            category = Category.query.filter(func.lower(needle)==func.lower(category_name.replace(" ", "")),
                                    Category.parent_id!=None).first()

            if category:
                print ("Category ID: '{}' ...".format(category.id))
                if picture_subject.lower() == 'facade':
                    new_picture = ShelterPicture(file_name=picture_name,
                                    shelter_id=shelter.id,
                                    category_id=category.id,
                                    is_main_picture=True)
                else:
                    new_picture = ShelterPicture(file_name=picture_name,
                                    shelter_id=shelter.id,
                                    category_id=category.id)

                db.session.add(new_picture)
                db.session.commit()

                path = os.path.join(conf.SHELTERS_PICTURES_SERVER_PATH,
                                                            str(shelter.id))
                if not os.path.exists(path):
                    os.makedirs(path)

                #shutil.copy(picture, path)

                im = Image.open(picture)

                width, height = im.size

                hsize = int(float(im.size[1]))
                print((imgwidth, hsize, width, height))

				#if width is wider than max width, then scale both height and width
                if width > imgwidth:
                    ratio = (imgwidth/width)
                    height = int(height*ratio)
                    width = imgwidth
                    print((ratio))

                try:
                	resized_im = im.resize((width,height), Image.BICUBIC)
                	resized_im.save(os.path.join(path , picture_name), "JPEG", quality=70, optimize=True, progressive=True)
                except OSError:
                   im.save(os.path.join(path, picture_name), "JPEG", quality=70, optimize=True, progressive=True)
                   pass

                print("Copy from '{}' ...".format(picture))
                print("Copy to '{}' ...".format(path))


import argparse
import numpy as np
import nrrd
import nibabel as nib
def main():
    """Take a list of seedpoints in pts format and create a labed nrrd files

    Returns
    -------

    """

    parser = argparse.ArgumentParser(
        description='This script performs tracking along a multi vector field')

    parser.add_argument('-i', help='Infile')
    parser.add_argument('-o', help='Outfile')
    parser.add_argument('-n', help='nrrd file with meta data')
    parser.add_argument("-r", help="create region", action='store_false')
    args = parser.parse_args()
    seeds = np.loadtxt(args.i)
    wm, meta = nrrd.read(args.n)
    labels = np.zeros(wm.shape, dtype=np.float32)
    trafo = np.zeros((4,4))
    trafo[:3,:3] = meta['space directions']
    trafo[3,3] = 1
    trafo[:3,3] = meta['space origin']
    trafo = np.linalg.inv(trafo)
    sc = np.ones((seeds.shape[0], 4))
    sc[:, :3] = seeds[:,:3]
    for i in range(seeds.shape[0]):
      #  sc = np.ones(4)

        sc[i] = trafo @ sc[i]
        if args.r:
            labels[int(sc[i,0]), int(sc[i,1]), int(sc[i,2])] = 1
    if not args.r:
        smin = np.min(sc, axis=0)
        print(smin)
        smax = np.max(sc, axis=0) + 2
        labels[int(smin[0]):int(smax[0]), int(smin[1]):int(smax[1]), int(smin[2]):int(smax[2])] = 1

    if args.o.endswith('nrrd'):
        nrrd.write(args.o, np.int16(labels), meta)
    elif args.o.endswith('nii.gz'):
        affine = np.zeros((4,4))
        affine[3,3] = 1
        affine[:3,:3] = meta['space directions']
        affine[:3,3] = meta['space origin']
        out_img = nib.Nifti1Image(np.int16(labels), affine)
        nib.save(out_img, args.o)
    else:
        print('unsupported format. Only nrrd and nii.gz are supported')

if __name__ == '__main__':
    main()


# =============================================================================
# Fog Blocking Clustering
# =============================================================================
#
# Implementation of a blocking clusterer that starts by dispatching given
# items to one or more buckets before computing pairwise comparisons on them.
#
import dill
from collections import defaultdict
from multiprocessing import Pool
from fog.clustering.utils import make_similarity_function, clusters_from_pairs

# TODO: max_block_size to avoid ngrams with high DF
# TODO: worker using a VPTree
# TODO: custom inner algorithm
# TODO: fuzzy blocking variant
# TODO: possibility not to merge if sure cannot collide twice
# TODO: the worker_graph is not used right now, the code does not use it (make a clusters from graph also)

def block_worker(payload):
    """
    Worker function used compute pairwise distance/similarity over a whole
    block.

    """
    similarity, block, serialized, graph = payload

    if serialized:
        similarity = dill.loads(similarity)

    pairs = []
    n = len(block)

    for i in range(n):
        A = block[i]

        for j in range(i + 1, n):
            B = block[j]

            if graph is not None and A in graph and B in graph[A]:
                continue

            if similarity(A, B):
                pairs.append((A, B))

    return pairs

def blocking(data, block=None, blocks=None, similarity=None, distance=None,
             radius=None, min_size=2, max_size=float('inf'), processes=1,
             mode='connected_components'):
    """
    Function returning an iterator over found clusters using the blocking
    method.

    It works by dispatching given items into one or more buckets before
    computing pairwise comparisons on each bucket.

    Args:
        data (iterable): Arbitrary iterable containing data points to gather
            into clusters. Will be fully consumed.
        block (callable): A function returning an item's block.
        blocks (callable): A function returning an item's blocks.
        similarity (callable): If radius is specified, a function returning
            the similarity between two points. Else, a function returning
            whether two points should be deemed similar. Alternatively, one can
            specify `distance` instead.
        distance (callable): If radius is specified, a function returning
            the distance between two points. Else, a function returning
            whether two point should not be deemed similar. Alternatively, one
            can specify `similarity` instead.
        radius (number, optional): produced clusters' radius.
        min_size (number, optional): minimum number of items in a cluster for
            it to be considered viable. Defaults to 2.
        max_size (number, optional): maximum number of items in a cluster for
            it to be considered viable. Defaults to infinity.
        processes (number, optional): number of processes to use.
            Defaults to 1.
        mode (string, optional): 'fuzzy_clusters', 'connected_components'.
            Defaults to 'connected_components'.

    Yields:
        list: A viable cluster.

    """

    # Formatting similarity
    similarity = make_similarity_function(similarity=similarity, distance=distance, radius=radius)

    # Single block or blocks?
    if blocks is None:
        graph = defaultdict(list)
        worker_graph = None

        def add(x, y):
            x.append(y)
    else:
        graph = defaultdict(set)
        worker_graph = graph

        def add(x, y):
            x.add(y)

    # Grouping items into buckets
    buckets = defaultdict(list)

    for item in data:
        if blocks is None:
            buckets[block(item)].append(item)
        else:
            bs = set(blocks(item))

            for b in bs:
                buckets[b].append(item)

    # Actual clustering
    def clustering():
        if processes == 1:
            for bucket in buckets.values():
                if len(bucket) < 2:
                    continue

                if type(bucket) is not list:
                    bucket = list(bucket)

                yield from block_worker((similarity, bucket, False, worker_graph))
        else:

            pickled_similarity = dill.dumps(similarity)

            pool_iter = (
                (pickled_similarity, bucket if type(bucket) is list else list(bucket), True, None)
                for bucket
                in buckets.values()
                if len(bucket) > 1
            )

            with Pool(processes=processes) as pool:
                for pairs in pool.imap_unordered(block_worker, pool_iter):
                    yield from pairs

    yield from clusters_from_pairs(
        clustering(),
        fuzzy=blocks is not None,
        min_size=min_size,
        max_size=max_size,
        mode=mode
    )


from PIL import Image
import os
import matplotlib.pyplot as plt
import numpy as np
from numpy import savetxt

#para que funcione multicomputador sin tener que cambiar la ruta
ganado_enfermo = os.getcwd()+"/archivosCSV/ganado enfermo CSVs"
ganado_sano=os.getcwd()+"/archivosCSV/ganado sano CSVs"

def matriz_csv(n_archivo_csv):
    matriz_csv_imagen = np.loadtxt(open(n_archivo_csv, "rb"), delimiter=",").astype(int)
    return matriz_csv_imagen

def NN_interpolation(img,newH,newW):
    oldH, oldW= np.array(img).shape
    newimg = np.zeros((newH,newW),dtype=np.uint8)
    for i in range(newH-1):
        for j in range(newW-1):
            oldx = round(i*(oldH/newH))
            oldy = round(j*(oldW/newW))
            newimg[i,j] = img[oldx,oldy]
    return newimg
#This funtion code is contributed by https://www.programmersought.com/article/36124682709/#:~:text=The%20nearest%20neighbor%20interpolation%20method%20adds%20the%20value%20of%20the,significantly%2C%20often%20containing%20jagged%20edges.

def compression(image):
    newHgth,newWgt = np.array(image).shape
    compress = NN_interpolation(image,round(newHgth/2),round(newWgt/2))
    return compress

def decompression(image):
    newHgth,newWgt = np.array(image).shape
    final_interpolation = NN_interpolation(image,newHgth*2,newWgt*2)
    return final_interpolation

directorio = ganado_sano
contenido = os.listdir(directorio)
original_image = matriz_csv(directorio+'/'+contenido[1])

image_orig = Image.fromarray(original_image)
img_compress = compression(original_image)
finalC = Image.fromarray(img_compress)
img_descompress = decompression(img_compress)
finalD = Image.fromarray(img_descompress)

image_orig.show()
finalC.show()
finalD.show()

savetxt('dataOriginal.csv', original_image, delimiter=',')
savetxt('dataNN.csv',finalC, delimiter=',')

proyecto/codigo/Entrega 2/Tested compression algorithms/Nearest_neighbor.py


import cv2
img = cv2.imread("example_images/kitten.jpg")

cv2.imshow("original image", img)
cv2.waitKey(0)

# Convert to Grayscale
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow("Gray image", img_gray)
cv2.waitKey(0)

# Convert to HSV
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# Extract the Hue/Saturation/Value channel and show only hue component
hue = img_hsv[:, :, 0]
saturation = img_hsv[:, :, 1]
value = img_hsv[:, :, 2]
cv2.imshow("Hue", hue)
cv2.waitKey(0)