"""
Script solving the famous Travel Salesman Problem (aka TSP).

Script can be given the following parameters:
    * --nogui: disables graphic user interface display.
    * --maxtime N: specifies maximum time in seconds for the script to look for
        a solution.
    * --filename FILE: uses the file given as input to set the cities list.
    * --maxstagnation N: specifies the number of iterations with stagnation
        before stopping the algorithm.

Authors: M'Poy Julien & Perez Joaquim
Date: 15.01.2017
Location: Haute École Arc, Neuchâtel
"""
from math import ceil
from itertools import chain
import time
import copy
import random
import pygame
import sys
from operator import attrgetter
from functools import total_ordering
from pygame.locals import (
    KEYDOWN, QUIT, MOUSEBUTTONDOWN, K_RETURN, K_ESCAPE,
    K_SPACE
)

"""
City class
"""

class City:
    """Class representing a city."""

    def __init__(self, name, position):
        """Name is city's name and position is a two floats tuple."""
        self.name = name
        self.position = position

        # will contain the next city and the distance to it
        # when creating a solution
        self.next = None
        self.dist = None

    def __eq__(self, other):
        try:
            return self.name == other.name and self.position == other.position
        except AttributeError:
            return False

    def __repr__(self):
        return "{} {}\n".format(self.name, self.position)

    def __hash__(self):
        return hash(self.name)

    def get_closest(self, cities):
        closest = cities[0]
        closest_dist = self.distance_to(closest)
        for city in cities:
            if self.distance_to(city) < closest_dist:
                closest = city
        return closest

    def distance_to(self, other):
        dx, dy = (
            self.position[0] - other.position[0],
            self.position[1] - other.position[1]
        )
        return (dx*dx + dy*dy) ** .5

"""
Solution
"""

@total_ordering
class Solution:
    def __init__(self, cities):
        """
        cities is an ordered list of cities, the last one is linked to the
        first one
        """
        self.cities = copy.copy(cities)
        self.compute_fitness()

    def compute_fitness(self):
        self.fitness = 0
        self.dict = {}

        old_city = self.cities[0]
        for city in chain(self.cities + [old_city]):
            distance = old_city.distance_to(city)
            # add the distance between this city and
            # the previous one to the fitness
            self.fitness += distance
            old_city.next = city
            old_city.dist = distance
            self.dict[old_city.name] = old_city
            old_city = city

    # total_ordering makes solutions comparable from these 2 methods
    def __eq__(self, other):
        return self.fitness == other.fitness

    def __lt__(self, other):
        return self.fitness < other.fitness

    def __repr__(self):
        return "solution with fitness {}".format(self.fitness)

    def mutate(self):
        """
        two blocks inversion (not indispensable)
        ABCDEF becomes CDEFAB

        The solution keeps the same, it only gives more chances to the FA
        segment to be muted.
        """
        pivot = random.randrange(len(self.cities))
        self.cities = self.cities[pivot:] + self.cities[:pivot]

        # i <- minimum born, j <- maximum born
        i = random.randrange(len(self.cities)-1)
        j = random.randrange(i+1, len(self.cities))

        # C
        # D
        # E <-- i
        # F
        # A <-- j
        # B

        top = self.cities[:i]  # CD
        middle = self.cities[i:j]  # EF
        bottom = self.cities[j:]  # AB
        # tidying block
        self.cities = middle + top + bottom  # EFCDAB

        self.compute_fitness()

    @staticmethod
    def create_pseudo_best(cities):
        # petite copie oklm pour ne pas toucher aux objets originaux
        cities = list(cities)
        ordered_cities = []
        city = cities[0]
        ordered_cities.append(city)
        cities.remove(city)
        while cities:
            city = city.get_closest(cities)
            ordered_cities.append(city)
            cities.remove(city)
        return Solution(ordered_cities)

"""
GUI
"""

class Gui:
    """Gui screen using pygame."""
    def __init__(self, cities=None, file_name=''):
        self.screen_x = 500
        self.screen_y = 500
        self.city_color = [10, 10, 200]  # blue
        self.city_radius = 3
        self.font_color = [255, 255, 255]  # white
        pygame.init()
        self.window = pygame.display.set_mode((self.screen_x, self.screen_y))
        pygame.display.set_caption('Travelling Salesman Problem')
        self.screen = pygame.display.get_surface()
        self.font = pygame.font.Font(None, 30)

        if cities:
            self.cities = cities
            self.draw_cities()
            self.text(file_name)
            pygame.display.flip()
            self.wait_for_user_input()
        else:
            self.cities = []
            self.place_cities()

    def wait_for_user_input(self):
        while True:
            event = pygame.event.wait()
            if (event.type == QUIT or (
                    event.type == KEYDOWN and event.key == K_ESCAPE
            )):
                sys.exit(0)
            elif (event.type == KEYDOWN and (
                    event.key == K_RETURN or event.key == K_SPACE
                )
            ):
                break

    def place_cities(self):
        city_counter = 0
        self.screen.fill(0)
        self.text("Placez vos point puis appuyez sur Enter")
        pygame.display.flip()
        while True:
            for event in pygame.event.get():
                if event.type == MOUSEBUTTONDOWN:
                    pos = pygame.mouse.get_pos()
                    name = "v{}".format(city_counter)
                    self.cities.append(City(name, pos))
                    city_counter += + 1
                    self.screen.fill(0)
                    self.draw_cities()
                    self.text("Nombre: {}".format(len(self.cities)))
                    pygame.display.flip()
                elif (event.type == QUIT or (
                        event.type == KEYDOWN and event.key == K_ESCAPE
                    )
                ):
                    sys.exit(0)
                elif (event.type == KEYDOWN and (
                    event.key == K_RETURN or event.key == K_SPACE
                    )
                ):
                    if(len(self.cities) > 2):
                        return

    def draw_cities(self):
        for city in self.cities:
            pygame.draw.circle(
                self.screen, self.city_color, city.position, self.city_radius
            )

    def draw_path(self, solution, msg="", color=[255, 0, 0]):
        self.screen.fill(0)
        pygame.draw.lines(self.screen, color, True, [
            city.position for city in solution.cities]
        )
        self.draw_cities()
        self.text(msg)
        pygame.display.flip()

    def text(self, msg, render=False):
        text = self.font.render(msg, True, self.font_color)
        textRect = text.get_rect()
        self.screen.blit(text, textRect)
        if render:
            pygame.display.flip()

"""
Algorithme
"""

def crossover_from_best_in_parents(father, mother):
    """
    Starting from a city randomly selected, we check both parents'
    nex city and choose the closest one. If this city is already present
    in the solution, we take the other parent's one. If this city is
    already in the solution too, we choose an other city randomly.
    """
    children = []
    for i in range(2):
        cities = []
        names = [city.name for city in father.cities]
        chosen_name = random.choice(names)
        while len(names) > 0:
            names.remove(chosen_name)
            current_city = father.dict[chosen_name]
            cities.append(current_city)
            from_father = father.dict[chosen_name]
            from_mother = mother.dict[chosen_name]

            candidates = []
            if from_father.next.name in names:
                candidates += [from_father]
            if from_mother.next.name in names:
                candidates += [from_mother]

            if len(candidates) > 0:
                # we can use a gene from one the parents
                candidates.sort(key=attrgetter('dist'))
                chosen_name = candidates[0].next.name
            else:
                """
                we cannot because both cities are already in the solution
                we are building.
                """
                if names:
                    chosen_name = random.choice(names)
        children += [Solution(cities)]

    return children

def ox_crossover(x, y, crossover_ratio=0.3):
    """
    OX Crossover between x and y indviduals. Crossover section is defined
    randomly following the crossover_ration parameter.

    The two children are generated and returned as a tuple containing.
    """
    x, y = x.cities, y.cities
    genes_to_crossover = int(ceil(len(x) * crossover_ratio))
    start = random.randint(0, len(x) - genes_to_crossover - 1)
    stop = start + genes_to_crossover
    x_crossover = tuple(x[start:stop])
    y_crossover = tuple(y[start:stop])
    prepared_x = [item if item not in y_crossover else None for item in x]
    x_shifts = prepared_x[stop:].count(None)
    prepared_y = [item if item not in x_crossover else None for item in y]
    y_shifts = prepared_y[stop:].count(None)
    new_x = [item for item in prepared_x if item is not None]
    new_y = [item for item in prepared_y if item is not None]
    new_x = shift_list(new_x, x_shifts)
    new_y = shift_list(new_y, y_shifts)
    new_x = new_x[:start] + list(y_crossover) + new_x[start:]
    new_y = new_y[:start] + list(x_crossover) + new_y[start:]
    return Solution(new_x), Solution(new_y)

def shift_list(items, shifts):
    """Left shift a list of elements."""
    for i in range(shifts):
        items = items[1:] + items[:1]
    return items

def ga_solve(file=None, gui=True, maxtime=0, maxstagnation=200):
    """
    Main function parsing file, initializing UI and launching genetic
    algorithm solving method.
    """

    # dictionnary containing the cities
    # key: city's name, value: City object
    cities = []

    # just because we are already using a gui variable
    gui_diplay = gui

    if file:
        with open(file, encoding='utf-8') as positions_file:
            for line in positions_file:
                # for each line, we create a City object with the coordinates
                cityname, x, y = line.split()
                cities.append(City(cityname, (int(x), int(y))))
            if gui_diplay:
                gui = Gui(cities, file)
    else:
        gui = Gui()
        cities = gui.cities

    t1 = time.time()

    POPULATION_SIZE = 20
    # int because division always returns a float
    HALF = int(POPULATION_SIZE/2)
    QUARTER = int(POPULATION_SIZE/4)
    # mutation rate
    rate = 0.2

    """
    RANGS contains n*0,  (n-1)*1 ... 1*n
        -> example 10, 9,9, 8,8,8, 7,7,7,7, ...
    """
    RANGS = [
        POPULATION_SIZE-i for i in range(POPULATION_SIZE+1) for j in range(i)
    ]

    population = []
    for i in range(POPULATION_SIZE):
        random.shuffle(cities)
        population.append(Solution(cities))

    pseudo_best = Solution.create_pseudo_best(cities)
    population.append(pseudo_best)

    old_best = 0
    stagnation = 0

    method_1 = True

    # genetic algorithm
    while True:
        # population sorting
        population.sort()

        best = Solution(population[0].cities)

        # population = population[:HALF] # selects half of the best solutions

        # more natural selection
        # select a quarter of the best solutions
        population = population[:QUARTER]
        # the select an other quarter randomly
        # population[QUARTER:] remains
        population += random.sample(population, QUARTER)

        # seems more correct but works gives worse results
        # elite, reste = population[:QUARTER], population[QUARTER:]
        # population = elite + random.sample(population, QUARTER)

        # population shuffling
        random.shuffle(population)

        # crossover
        for i in range(0, HALF, 2):  # 0 to HALF 2-by-2
            sol1 = population[i]
            sol2 = population[i+1]
            # add children to the population
            if method_1:
                population += crossover_from_best_in_parents(sol1, sol2)
            else:
                population += list(ox_crossover(sol1, sol2))
            method_1 = not method_1

        # muate 20% of the solutions
        [
            solution.mutate() for solution in random.sample(
                population, int(rate * len(population))
            )
        ]
        population.append(best)

        if best.fitness == old_best:
            stagnation += 1
            # stop if the best solution is the same n time consequently
            if not maxtime and stagnation == maxstagnation:
                break
        else:
            stagnation = 0
            if gui_diplay:
                gui.draw_path(best, msg=str(best.fitness))

        if maxtime:
            dt = time.time() - t1
            if dt > maxtime:
                break

        old_best = best.fitness

    if gui_diplay:
        gui.draw_path(best, msg=str(best.fitness), color=[0, 255, 0])
        gui.wait_for_user_input()

    path = [city.name for city in best.cities]
    return best.fitness, path

"""
MAIN
"""
if __name__ == "__main__":
    import argparse

    parser = argparse.ArgumentParser()
    parser.add_argument("-f", "--filename", help="use the file given as input")
    parser.add_argument(
        "-n", "--nogui",
        help="disable graphic user interface display", action="store_true"
    )
    parser.add_argument(
        "-t", "--maxtime", help="specify the maximum time in seconds", type=int
    )
    parser.add_argument(
        "-s", "--maxstagnation", type=int, default=200,
        help="specify the number of iteration with \
            stagnation before stopping the algorithm"
    )
    args = parser.parse_args()

    distance, path = ga_solve(
        file=args.filename,
        gui=not args.nogui,
        maxtime=args.maxtime,
        maxstagnation=args.maxstagnation
    )

    print("Distance : {}\nPath : {}".format(distance, path))


import functools

import tensorflow as tf

from finetune.util.shapes import shape_list, lengths_from_eos_idx
from finetune.optimizers.recompute_grads import recompute_grad
from finetune.nn.activations import gelu
from finetune.base_models.gpt.featurizer import norm, dropout, get_pos_values

def softmax(x, axis=-1):
    x = x - tf.reduce_max(input_tensor=x, axis=axis, keepdims=True)
    ex = tf.exp(x)
    return ex / tf.reduce_sum(input_tensor=ex, axis=axis, keepdims=True)

def split_states(x, n):
    """Reshape the last dimension of x into [n, x.shape[-1]/n]."""
    *start, m = shape_list(x)
    return tf.reshape(x, start + [n, m // n])

def merge_states(x):
    """Smash the last two dimensions of x into a single dimension."""
    *start, a, b = shape_list(x)
    return tf.reshape(x, start + [a * b])

def conv1d(x, scope, nf, *, w_init_stdev=0.02):
    with tf.compat.v1.variable_scope(scope):
        *start, nx = shape_list(x)
        w = tf.compat.v1.get_variable(
            "w",
            [1, nx, nf],
            initializer=tf.compat.v1.random_normal_initializer(stddev=w_init_stdev),
        )
        b = tf.compat.v1.get_variable("b", [nf], initializer=tf.compat.v1.constant_initializer(0))
        c = tf.reshape(
            tf.matmul(tf.reshape(x, [-1, nx]), tf.reshape(w, [-1, nf])) + b,
            start + [nf],
        )
        return c

def attention_mask(nd, ns, *, dtype):
    """1's in the lower triangle, counting from the lower right corner.
    Same as tf.matrix_band_part(tf.ones([nd, ns]), -1, ns-nd), but doesn't produce garbage on TPUs.
    """
    i = tf.range(nd)[:, None]
    j = tf.range(ns)
    m = i >= j - ns + nd
    return tf.cast(m, dtype)

def attn(x, scope, n_state, *, past, hparams, train=False):
    assert x.shape.ndims == 3  # Should be [batch, sequence, features]
    assert n_state % hparams.n_heads == 0
    if past is not None:
        assert (
            past.shape.ndims == 5
        )  # Should be [batch, 2, heads, sequence, features], where 2 is [k, v]

    def split_heads(x):
        # From [batch, sequence, features] to [batch, heads, sequence, features]
        return tf.transpose(a=split_states(x, hparams.n_heads), perm=[0, 2, 1, 3])

    def merge_heads(x):
        # Reverse of split_heads
        return merge_states(tf.transpose(a=x, perm=[0, 2, 1, 3]))

    def mask_attn_weights(w):
        # w has shape [batch, heads, dst_sequence, src_sequence], where information flows from src to dst.
        _, _, nd, ns = shape_list(w)
        b = attention_mask(nd, ns, dtype=w.dtype)
        b = tf.reshape(b, [1, 1, nd, ns])
        w = w * b - tf.cast(1e10, w.dtype) * (1 - b)
        return w

    def multihead_attn(q, k, v, attn_p_drop, train=False):
        # q, k, v have shape [batch, heads, sequence, features]
        w = tf.matmul(q, k, transpose_b=True)
        w = w * tf.math.rsqrt(tf.cast(v.shape[-1], w.dtype))

        w = mask_attn_weights(w)
        w = softmax(w)
        w = dropout(w, attn_p_drop, train)
        a = tf.matmul(w, v)
        return a

    with tf.compat.v1.variable_scope(scope):
        c = conv1d(x, "c_attn", n_state * 3)
        q, k, v = map(split_heads, tf.split(c, 3, axis=2))
        if past is not None:
            pk, pv = tf.unstack(past, axis=1)
            k = tf.concat([pk, k], axis=-2)
            v = tf.concat([pv, v], axis=-2)
        a = multihead_attn(q, k, v, hparams.attn_p_drop, train=train)
        a = merge_heads(a)
        a = conv1d(a, "c_proj", n_state)
        a = dropout(a, hparams.resid_p_drop, train=train)
        return a

def mlp(x, scope, n_state, *, hparams, train=False):
    with tf.compat.v1.variable_scope(scope):
        nx = x.shape[-1]
        h = gelu(conv1d(x, "c_fc", n_state))
        h2 = conv1d(h, "c_proj", nx)
        h2 = dropout(h2, hparams.resid_p_drop, train=train)
        return h2

def block(x, *, past, hparams, train=False):
    nx = x.shape[-1]
    a = attn(norm(x, "ln_1"), "attn", nx, past=past, hparams=hparams, train=train)
    x = x + a
    m = mlp(norm(x, "ln_2"), "mlp", nx * 4, hparams=hparams, train=train)
    x = x + m
    return x

def past_shape(*, hparams, batch_size=None, sequence=None):
    return [
        batch_size,
        hparams.n_layer,
        2,
        hparams.n_heads,
        sequence,
        hparams.n_embd // hparams.n_heads,
    ]

def expand_tile(value, size):
    """Add a new axis of given size."""
    value = tf.convert_to_tensor(value=value, name="value")
    ndims = value.shape.ndims
    return tf.tile(tf.expand_dims(value, axis=0), [size] + [1] * ndims)

def positions_for(tokens, past_length):
    batch_size = tf.shape(input=tokens)[0]
    nsteps = tf.shape(input=tokens)[1]
    return expand_tile(past_length + tf.range(nsteps), batch_size)

def embed(X, we):
    e = tf.gather(we, X)
    h = tf.reduce_sum(input_tensor=e, axis=2)
    return h

def gpt2_featurizer(
    X,
    encoder,
    config,
    train=False,
    reuse=None,
    **kwargs
):
    initial_shape = tf.shape(input=X)
    X = tf.reshape(X, shape=tf.concat(([-1], initial_shape[-1:]), 0))
    X.set_shape([None, None])

    pos_values = get_pos_values(tf.shape(input=X)[1], encoder.vocab_size)
    X = tf.stack((X, tf.tile(pos_values, [tf.shape(input=X)[0], 1])), 2)

    with tf.compat.v1.variable_scope("model/featurizer", reuse=reuse):
        embed_weights = tf.compat.v1.get_variable(
            name="we",
            shape=[encoder.vocab_size + config.max_length, config.n_embed],
            initializer=tf.compat.v1.random_normal_initializer(stddev=config.weight_stddev),
        )
        if config.train_embeddings:
            embed_weights = dropout(embed_weights, config.embed_p_drop, train)
        else:
            embed_weights = tf.stop_gradient(embed_weights)
        h = embed(X, embed_weights)

        # Transformer
        pasts = [None] * config.n_layer
        for layer, past in enumerate(pasts):
            if (
                (config.n_layer - layer) == config.num_layers_trained
                and config.num_layers_trained != config.n_layer
            ):
                h = tf.stop_gradient(h)
                train_layer = False
            else:
                train_layer = train

            with tf.compat.v1.variable_scope("h%d" % layer):
                block_fn = functools.partial(
                    block, past=past, hparams=config, train=train
                )
                if config.low_memory_mode and train_layer:
                    block_fn = recompute_grad(block_fn, use_entire_scope=True)
                h = block_fn(h)

        h = norm(h, "ln_f")

        # Use hidden state at classifier token as input to final proj. + softmax
        clf_h = tf.reshape(h, [-1, config.n_embed])  # [batch * seq_len, embed]
        clf_token = encoder["_classify_"]
        pool_idx = tf.cast(
            tf.argmax(input=tf.cast(tf.equal(X[:, :, 0], clf_token), tf.float32), axis=1), tf.int32
        )
        batch, length, _ = shape_list(X)
        clf_h = tf.gather(
            clf_h,
            tf.range(batch, dtype=tf.int32) * length + pool_idx,
        )
        clf_h = tf.reshape(
            clf_h, shape=tf.concat((initial_shape[:-1], [config.n_embed]), 0)
        )
        seq_feats = tf.reshape(
            h, shape=tf.concat((initial_shape, [config.n_embed]), 0)
        )

        lengths = lengths_from_eos_idx(eos_idx=pool_idx, max_length=shape_list(X)[0])

        return {
            "embed_weights": embed_weights,
            "features": clf_h,
            "sequence_features": seq_feats,
            "eos_idx": pool_idx,
            "length": lengths
        }


# Do not modify these lines
__winc_id__ = '7b9401ad7f544be2a23321292dd61cb6'
__human_name__ = 'arguments'

# Add your code after this line

def greet(name = 'piet', greeting_template = 'Hello, <name>!'):
    return greeting_template.replace('<name>', name)

def force(mass=0, body='earth'):

    bodies = {
        'sun': 274,
        'mercury': 3.7,
        'venus': 9.8,
        'earth': 9.798,
        'moon': 1.62,
        'mars': 3.71,
        'jupiter': 24.92,
        'saturn': 10.44,
        'neptune': 11.15,
        'uranus': 8.87,
        'pluto': 0.58
    }  # body: surface gravity

    return round(mass * bodies[body], 1)

def pull(m1, m2, d):
    G = 6.674 * (10 ** -11)
    return G * ((m1 * m2) / (d ** 2))


import os
from time import sleep

from dotenv import load_dotenv

from src.util.bedfile import load_replicateIDR_report
from src.util.download.stringdb import (
    download_homology_metrics,
    download_interaction_partners,
    identify_protein,
)

load_dotenv()
PROJECT_PATH = os.getenv("PROJECT_PATH", "~/.cache/eclip")
SAVE_DIR = os.path.join(PROJECT_PATH, "data", "stringdb")

if __name__ == "__main__":
    report = load_replicateIDR_report()
    query_protein = list(report["Target label"].unique())
    data = identify_protein()
    homology = download_homology_metrics()
    print("homology: ", homology.shape)
    for required_score in [0, 400, 700, 900]:
        partners = download_interaction_partners(required_score=required_score)
        print("partners: ", partners.shape)
        tmp = partners[
            partners["preferredName_B"].isin(partners["preferredName_A"].unique())
        ]
        print(required_score, ": ", partners.shape, " -> ", tmp.shape)
        sleep(1)


import ast
import copy
from base_mutator import BaseMutator

class ConditionalOperatorNegationMutator(BaseMutator):
    '''
    Official (brief):  https://docs.python.org/2/library/ast.html
    Green Tree Snakes: http://greentreesnakes.readthedocs.org/

    Comparison operator tokens = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn

    The conditionals negation mutator replaces the relational operators ==, != <, <=, >, >= with their counterparts:

    '=='     is mutated to '!='
    '!='     is mutated to '=='
    '<='     is mutated to '>'
    '>='     is mutated to '<'
    '<'      is mutated to '>='
    '>'      is mutated to '<='
    'is'     is mutated to 'is not'
    'is not' is mutated to 'is'
    'in'     is mutated to 'not in'
    'not in' is mutated to 'in'

    '''
    def __init__(self, base_node):
        BaseMutator.__init__(self, base_node)
        self.original_ops = base_node.ops

        index_count = 0
        for op in base_node.ops:

            if type(op) in [ast.Gt, ast.GtE, ast.Lt, ast.LtE, ast.Eq, ast.NotEq, ast.Is, ast.IsNot, ast.In, ast.NotIn]:
                if type(op) is ast.Eq:
                    ops_mutant_Eq = copy.deepcopy(base_node.ops)
                    ops_mutant_Eq[index_count] = ast.NotEq()
                    self.mutations.append({"ops": ops_mutant_Eq})

                if type(op) is ast.NotEq:
                    ops_mutant_NotEq = copy.deepcopy(base_node.ops)
                    ops_mutant_NotEq[index_count] = ast.Eq()
                    self.mutations.append({"ops": ops_mutant_NotEq})

                if type(op) is ast.LtE:
                    ops_mutant_LtE = copy.deepcopy(base_node.ops)
                    ops_mutant_LtE[index_count] = ast.Gt()
                    self.mutations.append({"ops": ops_mutant_LtE})

                if type(op) is ast.GtE:
                    ops_mutant_GtE = copy.deepcopy(base_node.ops)
                    ops_mutant_GtE[index_count] = ast.Lt()
                    self.mutations.append({"ops": ops_mutant_GtE})

                if type(op) is ast.Lt:
                    ops_mutant_Lt = copy.deepcopy(base_node.ops)
                    ops_mutant_Lt[index_count] = ast.GtE()
                    self.mutations.append({"ops": ops_mutant_Lt})

                if type(op) is ast.Gt:
                    ops_mutant_Gt = copy.deepcopy(base_node.ops)
                    ops_mutant_Gt[index_count] = ast.LtE()
                    self.mutations.append({"ops": ops_mutant_Gt})

                if type(op) is ast.Is:
                    ops_mutant_Is = copy.deepcopy(base_node.ops)
                    ops_mutant_Is[index_count] = ast.IsNot()
                    self.mutations.append({"ops": ops_mutant_Is})

                if type(op) is ast.IsNot:
                    ops_mutant_IsNot = copy.deepcopy(base_node.ops)
                    ops_mutant_IsNot[index_count] = ast.Is()
                    self.mutations.append({"ops": ops_mutant_IsNot})

                if type(op) is ast.In:
                    ops_mutant_In = copy.deepcopy(base_node.ops)
                    ops_mutant_In[index_count] = ast.NotIn()
                    self.mutations.append({"ops": ops_mutant_In})

                if type(op) is ast.NotIn:
                    ops_mutant_NotIn = copy.deepcopy(base_node.ops)
                    ops_mutant_NotIn[index_count] = ast.In()
                    self.mutations.append({"ops": ops_mutant_NotIn})

            index_count += 1

    def reset(self):
        self.base_node.ops = self.original_ops

    def mutate(self, index):
        self.base_node.ops = self.mutations[index]['ops']


# Read input data
with open('robot.txt') as fin:
    n, m = map(int, next(fin).split())

    mat = [[int(x) for x in next(fin).split()] for _ in range(n)]

# Initialize vectors and matrices for dynamic programming
sum_max = [[0 for _ in range(m)] for _ in range(n)]
preds = [[(-1, -1) for _ in range(m)] for _ in range(n)]

# The robot starts in the upper left corner
sum_max[0][0] = mat[0][0]
preds[0][0] = (-1, -1)

for i in range(n):
    for j in range(m):
        up = sum_max[i - 1][j]
        left = sum_max[i][j - 1]
        if up > left:
            sum_max[i][j] = mat[i][j] + up
            preds[i][j] = (i - 1, j)
        else:
            sum_max[i][j] = mat[i][j] + left
            preds[i][j] = (i, j - 1)

# Print the solution
print(sum_max[-1][-1])

current = (n - 1, m - 1)
stack = []

while current != (0, 0):
    stack.append(current)
    current = preds[current[0]][current[1]]

stack.append(current)

print(*reversed(stack), sep='\n')


# https://programmers.co.kr/learn/courses/30/lessons/12924
def solution(n):
    answer = 1

    for i in range(1,n+1):
        s = i
        for j in range(i+1, n+1):
            if s == n :
                answer += 1
            s += j
            if s > n :
                break

    return answer

n = 6
print(solution(n))


# -*- coding: utf-8 -*-：

import numpy as np
import cv2
import time
import subprocess

# cap = cv2.VideoCapture(r'C:\Users\Mr.Five_SSD\Desktop\Material\One_Bike_Cross.mp4')
# cap = cv2.VideoCapture(r'C:\Users\Mr.Five_SSD\Desktop\Material\Many.mp4')
cap = cv2.VideoCapture(r'C:\Users\Mr.Five_SSD\Desktop\Material\Three_people_cross.mp4')

body_cascade = cv2.CascadeClassifier(
    r'C:\Users\Mr.Five_SSD\AppData\Local\Programs\Python\Python36\Lib\site-packages\cv2\data\haarcascade_fullbody.xml')
# cap = cv2.VideoCapture(0)

# fgbg = cv2.createBackgroundSubtractorMOG()
kernel3x3 = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
kernel6x6 = cv2.getStructuringElement(cv2.MORPH_RECT, (4, 4))

fgbg = cv2.createBackgroundSubtractorMOG2(history=500, varThreshold=16, detectShadows=True)
# fgbg = cv2.bgsegm.createBackgroundSubtractorMOG()
# fgbg = cv2.BackgroundSubtractor()

params = cv2.SimpleBlobDetector_Params()
# Change thresholds
# params.minThreshold = 10
# params.maxThreshold = 200

params.minDistBetweenBlobs = 30

# 检测白色
params.filterByColor = True
params.blobColor = 255

# Filter by Area. 面积
params.filterByArea = True
params.minArea = 100
params.maxArea = 2500

# Filter by Circularity 圆度
params.filterByCircularity = False
params.minCircularity = 0.1

# Filter by Convexity 凸性
params.filterByConvexity = False
params.minConvexity = 0.3

# Filter by Inertia 惯性
params.filterByInertia = False
params.minInertiaRatio = 0.01

time_last = -1.0  # 避免刚运行程序时时间差为0，
frame_count = 0

while (cap.isOpened()):
    # get a frame
    ret, frame = cap.read()

    if ret == True:
        keycode = cv2.waitKey(1) & 0xff
        if keycode != 0xff:
            print(keycode, '\n', chr(keycode))
            break

        # time.sleep(0.1)
        gray = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)

        # bodys = body_cascade.detectMultiScale(frame, 1.1, 5)
        # print(bodys)
        # for (x, y, w, h) in bodys:
        #     cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 255, 255), 3)

        # cv2.GaussianBlur(frame, (81, 81), 0)

        fgmask = fgbg.apply(gray)
        cv2.imshow('Foreground', fgmask)

        fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel3x3)
        cv2.imshow('Opening', fgmask)

        ret, binary = cv2.threshold(fgmask, 128, 255, cv2.THRESH_BINARY)  # 去掉阴影
        binary = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel6x6, iterations=2)

        detector = cv2.SimpleBlobDetector_create(params)
        keypoints = detector.detect(binary)

        # _, contours, _ = cv2.findContours(binary, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
        # cnt = contours[4]
        frame_RGB = cv2.cvtColor(binary, cv2.COLOR_GRAY2RGB)
        # cv2.drawContours(frame_RGB, contours, -1, (0, 0, 255), 1)
        # print(contours)

        frame_RGB = cv2.drawKeypoints(frame_RGB, keypoints, np.array([]), (0, 255, 0),
                                      cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
        cv2.minEnclosingTriangle()
        for index in range(np.size(keypoints)):
            x = int(keypoints[index].pt[0])
            y = int(keypoints[index].pt[1])
            w = h = int(keypoints[index].size)
            cv2.rectangle(frame, (x - int(0.6 * w), y - int(1.2 * h)), (x + int(0.6 * w), y + int(1.2 * h)),
                          (0, 255, 0), 1)
        # tu = keypoints

        str_t = time.strftime('%Y-%m-%d %H:%M:%S')
        time_now = time.clock()
        time_delta = time_now - time_last
        time_last = time_now
        fps = 1.0 / time_delta
        fps_t = str('fps: %.3f' % fps)
        det_t = str('calculate time:%.3f s' % time_delta)

        frame_count += 1  # 帧数
        fra_t = str('frame count:%d' % frame_count)

        cv2.putText(frame, fra_t, (450, 20), cv2.FONT_HERSHEY_COMPLEX, 0.5, (0, 255, 0), 1)
        cv2.putText(frame, fps_t, (0, 20), cv2.FONT_HERSHEY_COMPLEX, 0.5, (0, 255, 0), 1)
        cv2.putText(frame, det_t, (0, 460), cv2.FONT_HERSHEY_COMPLEX, 0.5, (0, 0, 255), 1)
        cv2.putText(frame, str_t, (450, 460), cv2.FONT_HERSHEY_COMPLEX, 0.5, (0, 0, 255), 1)

        cv2.imshow('Original', frame)
        cv2.imshow('Closing And Blob', frame_RGB)

        if frame_count == 333:
            subprocess.call("pause", shell=True)

    else:
        break

cap.release()
cv2.destroyAllWindows()


import tensorflow as tf
import numpy as np
from tensorflow.keras import layers
import pandas
import tensorflow_datasets as tfds
import cv2
import tensorflow.keras.backend as K

cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath="checkpoints/1", save_freq='epoch', verbose=1)

idConv = {0: 0, 1: 217, 2: 482, 3: 491, 4: 497, 5: 566, 6: 569, 7: 571, 8: 574, 9: 701}
convertId = lambda x: idConv[x]
counter = 0
def resize(im, size):
    global counter
    counter += 1
    print(counter)
    #https://jdhao.github.io/2017/11/06/resize-image-to-square-with-padding/
    old_size = im.shape[:2] # old_size is in (height, width) format

    ratio = float(size)/max(old_size)
    new_size = tuple([int(x*ratio) for x in old_size])

    # new_size should be in (width, height) format

    im = cv2.resize(im, (new_size[1], new_size[0]))

    delta_w = size - new_size[1]
    delta_h = size - new_size[0]
    top, bottom = delta_h//2, delta_h-(delta_h//2)
    left, right = delta_w//2, delta_w-(delta_w//2)

    color = [0, 0, 0]
    new_im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT,
        value=color)
    return new_im

ds = tfds.load(name="imagenette/320px-v2", split="validation")
ds = tfds.as_numpy(ds)
dsX = np.array([resize(x['image'], 224) / 255 for x in ds])
classifier = tf.keras.applications.VGG19()
print(classifier)

def lossFunc(targetIdx, vgg, a):
    target = np.zeros(1000)
    target[targetIdx] = 1
    targetTensor = K.constant(target)
    def loss(y_true, y_pred):
        return a * tf.keras.losses.MSE(y_true, y_pred) + (1-a) * tf.keras.losses.categorical_crossentropy(targetTensor, vgg(tf.keras.applications.vgg19.preprocess_input(y_pred))[0])

    return loss

model = tf.keras.Sequential(layers=[
    layers.InputLayer(input_shape=(224, 224, 3)),
    layers.Conv2D(256, 5, strides=1, activation="relu"),
    layers.Conv2D(256, 5, strides=1, activation="relu"),
    layers.MaxPool2D(),

    layers.Conv2D(128, 5, strides=1, activation="relu"),
    layers.Conv2D(128, 5, strides=1, activation="relu"),
    layers.MaxPool2D(),

    layers.Conv2D(64, 5, strides=1, activation="relu"),
    layers.Conv2D(64, 5, strides=1, activation="relu"),
    layers.MaxPool2D(),

    layers.Conv2D(16, 3, strides=1, activation="relu"),
    layers.Conv2D(16, 3, strides=1, activation="relu"),

    layers.Conv2DTranspose(16, 3, strides=1, activation="relu", padding='valid'),
    layers.Conv2DTranspose(16, 3, strides=1, activation="relu", padding='valid'),
    layers.UpSampling2D(),

    layers.Conv2DTranspose(64, 5, strides=1, activation="relu", padding='valid'),
    layers.Conv2DTranspose(64, 5, strides=1, activation="relu", padding='valid'),
    layers.UpSampling2D(),

    layers.Conv2DTranspose(128, 5, strides=1, activation="relu", padding='valid'),
    layers.Conv2DTranspose(128, 5, strides=1, activation="relu", padding='valid'),
    layers.UpSampling2D(),

    layers.Conv2DTranspose(256, 5, strides=1, activation="relu", padding='valid'),
    layers.Conv2DTranspose(256, 5, strides=1, activation="relu", padding='valid'),

    layers.Conv2D(3, kernel_size=1, activation='sigmoid', padding='valid')
])

model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=.0001), loss=lossFunc(417, classifier, 1))
print(model.summary())

model.fit(x=dsX, y=dsX, batch_size=8, callbacks=[cp_callback], epochs=1000)


import argparse
import utils
import numpy as np
import datetime
from ner_config import Config
from models.ner_bilstm import RNN

def evaluate(model, test_set, config):
    '''
        Evaluates a test set

        Input: model, dataset to evaluate, config object
        Ouput: dictionary containing data about the evaluation

    '''
    # Build a confusion matrix
    matrix = [[0 for x in range(len(config.tags))]for y in range(len(config.tags))]
    # Pad and get sequence_lengths and word_lengths if necessary
    words, tags, chars = config.pad(dataset=test_set, use_chars=config.use_chars)
    # Create the feed dictionary
    feed = config.feed(model, words, tags, chars, use_chars=config.use_chars, dropout=1.0)
    # Get the bacth prediction , shape = (batch_size,max_sentence_length)
    sentences = model.predict_batch(feed)
    # for each line
    for pred, label in zip(sentences, tags):
        for i in range(len(pred)):
            matrix[pred[i]][label[i]] += 1

    metrics = dict()
    # Total labels
    metrics["total"] = np.sum(matrix)
    # Save the matrix
    metrics["matrix"] = np.array(matrix)
    # Number of real labels in the test set
    real_labels = np.sum(matrix, axis=0)
    # Number of predicted labels in the test set
    pred_labels = np.sum(matrix, axis=1)
    # Array of correct labels
    correct_labels = np.diagonal(matrix)
    # Total number of correct labels
    total_correct = np.sum(correct_labels)
    # Disable division zero by zero warnings
    # This is due to there being no instances of a certain label
    np.seterr(invalid='ignore')
    # Accuracy
    metrics["accuracies"] = correct_labels / real_labels
    metrics["accuracy"] = (total_correct/metrics["total"])
    # Precision is out of the predicted labels, which ones were correct
    metrics["precisions"] = np.divide(correct_labels, pred_labels)
    # Remove any NaN due to some labels not being present in the test set
    metrics["precisions"][np.isnan(metrics["precisions"])] = 1
    # Get the average
    metrics["precision"] = np.average(metrics["precisions"])
    # Precision is out of the predicted labels, which ones were correct
    metrics["recalls"] = np.divide(correct_labels, real_labels)
    # Remove any NaN due to some labels not being present in the test set
    metrics["recalls"][np.isnan(metrics["recalls"])] = 0
    # Get the average
    metrics["recall"] = np.average(metrics["recalls"])
    # F1
    metrics["f1"] = (2 * metrics["precision"]*metrics["recall"]) / \
        (metrics["precision"]+metrics["recall"])
    metrics["f1s"] = (2 * metrics["precisions"]*metrics["recalls"]) / \
        (metrics["precisions"]+metrics["recalls"])

    return metrics

def getstats(config, results):
    # Initialize
    folds = len(results)
    n_sets = len(results[0])
    acc = [0] * n_sets
    f1 = [0] * n_sets
    precision = [0] * n_sets
    recall = [0] * n_sets
    line = datetime.datetime.now().strftime("%y%m%d%H%M%S") + "\t"
    # Collect
    for f in results:
        for i, dset in enumerate(f):
            acc[i] += dset["accuracy"]
            f1[i] += dset["f1"]
            precision[i] += dset["precision"]
            recall[i] += dset["recall"]
    # Compute
    acc = np.array(acc) / folds
    f1 = np.array(f1) / folds
    precision = np.array(precision) / folds
    recall = np.array(recall) / folds
    # Display
    for i in range(n_sets):
        # Add the metrics
        line += "%s\t%s\t%s\t%s\t" % (format((f1[i]), ".5f"), format(
            acc[i], ".5f"), format(precision[i], ".5f"), format(recall[i], ".5f"))
        print("\nTest set", i + 1, ":\n=================================\n",
              "RESULTS:\n\t Avg F1: \t", format(f1[i] * 100, '.3f'),
              "\n\t Avg Accuracy:  ", format(acc[i] * 100, '.3f'),
              "\n\t Avg Precision: ", format(precision[i] * 100, '.3f'),
              "\n\t Avg Recall: \t", format(recall[i] * 100, '.3f'),
              "\n=================================")
    # Add the config
    line += "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t" % (
        config.pretrained, config.dim_word, config.non_static,
        config.use_crf, config.cell_word, config.dropout, config.use_chars,
        config.dim_char, config.cell_char)
    return line

def classify(text, model, config):
    # Convert into IDs
    dataset = []
    for line in text:
        ids = []
        line = line.strip().split(" ")
        for w in line:
            ids.append(config.word_id(w))
        dataset.append(ids)
    # Pad and get sequence_lengths and word_lengths if necessary
    words, _, chars = config.pad(dataset=dataset, use_chars=config.use_chars, labels=False)
    # Create the feed dictionary
    feed = config.feed(model, words, tags=False, chars=chars,
                       use_chars=config.use_chars, dropout=1.0)
    # Get the bacth prediction , shape = (batch_size,max_sentence_length)
    if config.use_crf:
        predictions = model.predict_batch(feed)
    else:
        logits = model.logits.eval(feed, session=model.sess)
        predicitons = np.argmax(labels_pred, axis=-1)
    # return predictions
    return predictions

def NER_print(predictions, text, config):
    line_text = ""
    line_tags = ""
    for pred, word in zip(predictions, text):
        pred = config.id_to_tag[pred]
        space = max(len(word), len(pred))
        _text = "".join(([c for c in word] + [" "] * space)[:space])
        _tags = "".join(([c for c in pred] + [" "] * space)[:space])
        line_text += _text + " "
        line_tags += _tags + " "
    print(line_text)
    print(line_tags)

def main(args):
    # Build the config class
    config = Config(args, load=True)

    # Define the model
    model = RNN(config)

    # Build model
    model.load_model(config.dir)

    # Applications
    if not (args.text == None or args.tags == None):
        dataset = config.build_dataset(text_list=[args.text], tags_list=[args.tags])
        metrics = evaluate(model, dataset, config)
        print("Precision: ", metrics["precision"], "\nRecall:    ",
              metrics["recall"], "\nF1:        ", metrics["f1"])

    if not(args.input == None or args.output == None):
        # Check if files exist
        if not utils.check_file(args.input):
            raise Exception("File ", args.input, " does not exist")

        # Read file
        text = list(open(args.input, "r").readlines())

        # Get the predictions
        predictions = classify(text=text, model=model, config=config)

        # Make a dict for each prediction with the entities found
        for i, (pred, line) in enumerate(zip(predictions, text)):
            line = line.strip().split(" ")
            entities = {key: [] for key, value in config.tags.items()}
            for tag, word in zip(pred, line):
                tag = config.id_to_tag[tag]
                if not tag == "O" and not word in entities[tag]:
                    entities[tag].append(word)
            predictions[i] = entities

        # Output a file with [text, prediction]
        with open(args.output, "w") as w:
            for line, pred in zip(text, predictions):
                for key, value in pred.items():
                    pred[key] = " ".join(value)
                pred = pred["ORG"] + " " + pred["PRO"] + " " + \
                    pred["VER"] + " " + pred["VUL"] + " " + pred["ID"]
                w.write(line.strip()+"\t"+str(pred)+"\n")

if __name__ == '__main__':
    # Get arguments
    parser = argparse.ArgumentParser(description='Load a NER model')
    parser.add_argument('-model', metavar='Model', default=None,
                        help='(dir for the checkpoint folder)')
    parser.add_argument('-input', metavar='Input file', default=None,
                        help='(Unlabelled file)')
    parser.add_argument('-output', metavar='Ouput file', default=None,
                        help='(Output file)')
    parser.add_argument('-text', metavar='Positive File', default=None,
                        help='(Positive file)')
    parser.add_argument('-tags', metavar='Negative File', default=None,
                        help='(Negative file)')
    args = parser.parse_args()

    # Need to pass a dir where the model is loaded
    if args.model == None:
        raise Exception('Provide a model')

    main(args)


nums1 = [[2,4],[3,6],[5,5]]
nums2 = [[1,3],[4,3]]

ids1 = []
ids2 = []
for el in nums1:
    ids1.append(el[0])
for el in nums2:
    ids2.append(el[0])
print(ids1, ids2)
ans = [[i, 0, 0] for i in range(max(ids1) + max(ids2))]
print(ans)
for el in nums1:
    ans[el[0]][1] += el[1]
    ans[el[0]][2] = 1
    print(el[0], ans)
for el in nums2:
    ans[el[0]][1] += el[1]
    ans[el[0]][2] = 1
ans1 = []
for el in ans:
    if el[2] == 1:
        ans1.append([el[0], el[1]])
print('------', ans1)


#!/usr/bin/python

import os
from wsgiref.handlers import CGIHandler

from flask import Flask
from flask import request, abort, redirect, url_for, jsonify, escape

import urllib2
import json
import sys

from pprint import pprint

sys.path.append(os.path.dirname(__file__))
from lod.freebase import Freebase
from lod.dbpedia import DBPedia
from lod.isbn import Isbn

application = Flask("dbpedia")
application.debug = True

@application.route('/')

@application.route('/isbn:<path:identifier>')
@application.route('/ISBN:<path:identifier>')

@application.route('/dbp:<path:identifier>')
@application.route('/DBP:<path:identifier>')

@application.route('/fb:/<path:identifier>')
@application.route('/fb:<path:identifier>')
@application.route('/FB:/<path:identifier>')
@application.route('/FB:<path:identifier>')

def lod(identifier = None):
    """

DBP: DBPedia

    http://dev.fe2.nl/DBP:Nasa

    http://dev.fe2.nl/DBP:Nasa?label_nl

    http://dev.fe2.nl/DBP:Nasa?label_nl,depiction

    http://dev.fe2.nl/DBP:Nasa?depiction&mode=html

ISBN: Isbn

    http://dev.fe2.nl/ISBN:9023439155

    http://dev.fe2.nl/ISBN:9023439155?title

    http://dev.fe2.nl/ISBN:9023439155?google_title

FB: FreeBase

    http://dev.fe2.nl/fb:/en/herman_brood

    """
    if not identifier == None:
        request_lod_source = request.path.split(':')[0][1:]
        if not request.args == None:
            req = dict(request.args)
        else:
            req = None
        if "mode" in req:
            if "html" == str(req["mode"][0]):
                mode="html"
                req.__delitem__("mode")
            else:
                mode="json"
                req.__delitem__("mode")
        else:
            mode="json"

        if request_lod_source.lower() == "fb":
            fb = Freebase([escape("/"+identifier)], log_path='/tmp', debug=True, backend='pymongo')
            fb.execute()
            data=fb
        elif request_lod_source.lower() == "isbn":
            isbn = Isbn([escape(identifier)], log_path='/tmp', debug=True, backend='pymongo')
            isbn.execute()
            data = isbn
        elif request_lod_source.lower() == "dbp":
            dbp = DBPedia([escape(identifier)], log_path='/tmp', debug=True, backend='pymongo')
            dbp.execute()
            data = dbp
        else:
            return(lod.__doc__)

        if len(data.keys()) > 0:
            if not req == None:
                if len(req.keys()) > 0:
                    for space in data.keys():
                        ret = ""
                        res = {}
                        for name in req.keys()[0].split(','):
                            if name in data[space]:
                                if str(mode) == "json":
                                    res[name] = data[space][name]
                                else:
                                    if data[space][name].lower().find('.jpg') > -1 or \
                                        data[space][name].lower().find('_thumb') > -1 or \
                                        data[space][name].lower().find('.svg') > -1 or \
                                        data[space][name].lower().find('.gif') > -1:
                                        if data[space][name].lower().find('_thumb') > -1:
                                            ret += "
"
                                        else:
                                            ret += "
"

                                    elif data[space][name].find('http://') > -1:
                                        ret += ""+data[space][name]+"
"
                                    else:
                                        ret += "
"+ name.split('_')[0].title() + ":
" + data[space][name]+"
"
                        if mode == "json":
                            return(jsonify(res))
                        else:
                            return(ret)
                return(jsonify(data))
        return()
    return(lod.__doc__)


import sys
import zlib
from socket import *

class Alice:

    def __init__(self, port_number):
        self.port_number = port_number
        self.clientSocket = socket(AF_INET, SOCK_DGRAM)  # create a socket on Alice's side
        self.clientSocket.settimeout(0.05)
        self.server_name = 'localhost'
        self.curr_seq_num = False  # flips between 0 and 1, start with 0
        self.num_of_feedback_packets = 0
        self.num_of_corrupt_feedback_packets = 0

    def send_data(self, data):
        # do-while loop for creating packets of 64 bytes from bulk data
        while True:
            # make packet with 58 actual message payload bytes
            packet_pay_load = data[0:58]
            data = data[58:]
            packet = self.make_packet(packet_pay_load, int(self.curr_seq_num))

            # do-while loop for repeated sending of packet until correct ACK is received
            while True:
                try:
                    self.clientSocket.sendto(packet, (self.server_name, self.port_number))
                    feedback_packet, server_address = self.clientSocket.recvfrom(64)

                    self.num_of_feedback_packets += 1

                    if self.is_packet_corrupt(feedback_packet):
                        self.num_of_corrupt_feedback_packets += 1

                    if (not self.is_packet_corrupt(feedback_packet)) and \
                            self.is_ack(int(self.curr_seq_num), feedback_packet):
                        # correct ACK packet received
                        break
                except timeout:
                    continue

            self.curr_seq_num = not self.curr_seq_num  # alternate between 0 and 1

            if len(data) == 0:
                # all data sent through packets
                break

    def make_packet(self, packet_pay_load, seq_num_in_int):
        sub_packet = str(seq_num_in_int) + packet_pay_load
        sub_packet_in_bytes = sub_packet.encode()
        checksum = zlib.crc32(sub_packet_in_bytes)
        checksum_in_bytes = checksum.to_bytes(4, 'big')
        packet_in_bytes = checksum_in_bytes + sub_packet_in_bytes

        return packet_in_bytes

    def is_packet_corrupt(self, packet):
        checksum_from_sender = packet[0:4]
        sub_packet_in_bytes = packet[4:]
        checksum_as_computed = zlib.crc32(sub_packet_in_bytes).to_bytes(4, 'big')

        return not checksum_from_sender.__eq__(checksum_as_computed)

    def is_ack(self, expected_seq_num, feedback_packet):
        seq_num_in_bytes = feedback_packet[4:]
        seq_num = seq_num_in_bytes.decode()

        assert len(seq_num) == 1, "wrong length of seq number"

        seq_num_in_int = int(seq_num)
        return seq_num_in_int == expected_seq_num

    def run(self):
        # question assumes no input delay
        data_to_send = ""

        for line in sys.stdin:
            data_to_send += line

        self.send_data(data_to_send)

alice = Alice(int(sys.argv[1]))
alice.run()

# write corruption rate
writer = open("Alice.txt", "w")
writer.write(format(alice.num_of_corrupt_feedback_packets / alice.num_of_feedback_packets, '.2f'))
writer.flush()
writer.close()


import requests

def getForecast(apiObj):
    forecast = {}
    forecast['high'] = apiObj['high']['celsius']
    forecast['low'] = apiObj['low']['celsius']
    forecast['dateFor'] = apiObj['date']['epoch']
    forecast['humidity'] = apiObj['avehumidity']
    return forecast

r = requests.get('http://api.wunderground.com/api/58ad3c15401bd354/forecast/q/NC/Cherryville.json')
response = r.json()
forecasts = response['forecast']['simpleforecast']['forecastday']
data = []
for f in forecasts:
    data = getForecast(f)
    requests.post('http://pharylonapi.azurewebsites.net/api/weather/forecast', data)


cities = []

# city = [name, color, list of possible colors, list of neighbours]

def init_cities():
    global cities
    cities = [
        ['saveni', 'none', ['r', 'g', 'b'], ['botosani', 'iasi', 'trusesti', 'darabani', 'vaslui', 'baicoi', 'gogosari']],
        ['botosani', 'none', ['r', 'g', 'b'], ['iasi', 'saveni']],
        ['iasi', 'none', ['r', 'g', 'b'], ['botosani', 'saveni', 'trusesti']],
        ['trusesti', 'none', ['r', 'g', 'b'], ['iasi', 'saveni', 'darabani']],
        ['darabani', 'none', ['r', 'g', 'b'], ['trusesti', 'saveni', 'vaslui']],
        ['cosula', 'none', ['r', 'g', 'b'], []],
        ['vaslui', 'none', ['r', 'g', 'b'], ['saveni', 'darabani']],
        ['baicoi', 'none', ['r', 'g', 'b'], ['saveni', 'gogosari']],
        ['gogosari', 'none', ['r', 'g', 'b'], ['saveni', 'baicoi']],

    ]

def test_list():
    for city in cities:
        print(city)

def minimum_remaining_value():
    mrv = cities[0]
    index = 0
    for city in cities:
        if city[1] == 'none':
            mrv = city
            index = cities.index(city)
            break

    for city in cities:
        if city[1] == 'none':
            if len(city[2]) < len(mrv[2]):
                mrv = city
                index = cities.index(city)

    return index

def mrv_coloring():
    colored = 0
    while colored < len(cities):
        index = minimum_remaining_value()
        mrv_city = cities[index]
        print(mrv_city[0], mrv_city[2])
        mrv_city[1] = (mrv_city[2]).pop(0)
        print(mrv_city[1])
        for neighbor in mrv_city[3]:
            for city in cities:
                if city[0] == neighbor:
                    if mrv_city[1] in city[2]:
                        city[2].remove(mrv_city[1])
        colored += 1

if __name__ == '__main__':
    init_cities()
    #test_list()
    mrv_coloring()
    test_list()


__author__ = "Sebastian Ahn"
__doc__ = """\
IdentifyBow
===========

**IdentifyBow** is an interactive method of identifying the position and orientation of
drug release from a well. This is done by rendering a bow on the image with two
interactive points: the center and the well.

|

============ ============ ===============
Supports 2D? Supports 3D? Respects masks?
============ ============ ===============
YES          NO           NO
============ ============ ===============

Measurements made by this module
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

-   *Center_X*, *Center_Y*: The position of the center of the microdevice.
-   *Well_X*, *Well_Y*: The position of the well of the microdevice.

"""

import math
from typing import Dict, Union, List, Callable, Tuple

import matplotlib.axes
import matplotlib.figure
import matplotlib.lines
import matplotlib.patches
import numpy
import wx
from PIL import Image
from matplotlib.backend_bases import MouseEvent
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas

import cellprofiler.measurement
import cellprofiler.module
import cellprofiler.pipeline
import cellprofiler.setting
import cellprofiler.workspace

K_UP = "w"
K_DOWN = "s"
K_LEFT = "a"
K_RIGHT = "d"
ARROW_KEYS = K_UP + K_DOWN + K_LEFT + K_RIGHT
epsilon = 20  # pixels

mode2color: Dict[str, str] = {"light": "k", "dark": "w"}

MEASUREMENTS = ["Center_X", "Center_Y", "Well_X", "Well_Y"]

# Helper types
# InteractorParamObj = Dict[str, Union[str, Callable, Tuple[int, int]]]

def cart2pol(x: float, y: float, in_deg: bool = True) -> Tuple[float, float]:
    r = math.sqrt(math.pow(x, 2) + math.pow(y, 2))
    theta = math.atan2(y, x)

    if in_deg:
        theta = math.degrees(theta)

    return r, theta

def pol2cart(r: float, theta: float, in_degs: bool = True) -> Tuple[float, float]:
    if in_degs:
        theta = (theta + 180) % 360 - 180
        theta = math.radians(theta)
    else:
        theta = (theta + (math.pi / 2)) % math.pi - (math.pi / 2)

    x = r * math.cos(theta)
    y = r * math.sin(theta)

    return x, y

def move(key: str, x: int, y: int) -> Tuple[int, int]:
    # image coordinates are relative to an origin that's placed at the top left
    stride = 1

    if key == K_UP:
        y -= stride
    elif key == K_DOWN:
        y += stride
    elif key == K_LEFT:
        x -= stride
    elif key == K_RIGHT:
        x += stride

    return x, y

class BaseInteractor(object):
    def __init__(self, axes: matplotlib.axes.Axes, **kwargs):
        """

        :param axes: Axes on which the interactor is plotted
        :param mode: "light" or "dark" mode
        """
        self.axes: matplotlib.axes.Axes = axes
        self.artists = {}

        self.__render_mode: str = kwargs.get("render_mode", "light")

    def set_render_mode(self, mode: str) -> None:
        self.__render_mode = mode

    def get_render_mode(self) -> str:
        return self.__render_mode

    render_mode = property(get_render_mode, set_render_mode)

    @property
    def color(self) -> str:
        return mode2color[self.render_mode]

    def draw_callback(self, event: MouseEvent) -> None:
        for artist in self.artists.values():
            self.axes.draw_artist(artist)

    def button_press_callback(self, event: MouseEvent) -> None:
        raise NotImplemented

    def button_release_callback(self, event: MouseEvent) -> None:
        raise NotImplemented

    def motion_notify_callback(self, event: MouseEvent) -> None:
        raise NotImplemented

    def key_press_event(self, event: MouseEvent) -> None:
        raise NotImplemented

    def key_release_event(self, event: MouseEvent) -> None:
        raise NotImplemented

class BowInteractor(BaseInteractor):
    def __init__(self, *args, **kwargs):
        """

        :param cxy: 2-tuple of xy coords for center
        :param wxy: 2-tuple of xy coords for well
        :param span: Optional float
        :param stickout: Optional int
        """
        self.id: str = kwargs.get("id")
        self.cxy: Tuple[int, int] = kwargs.get("cxy")
        self.wxy: Tuple[int, int] = kwargs.get("wxy")
        self.span: float = kwargs.get("span", 90.0)  # degrees
        self.stickout: float = kwargs.get("stickout", 1.1)  # unit-less

        super(BowInteractor, self).__init__(*args, **kwargs)

        self._ind: Union[None, int] = None
        self._ind_last: Union[None, int] = None

        self.init_artists()

    def init_artists(self) -> None:
        main_arrow_props = {
            "alpha": 0.5,
            "animated": True,
            "arrowstyle": "->,head_length=10,head_width=7",
            "color": self.color,
            "linestyle": "solid",
        }

        line_props = {
            "alpha": 0.7,
            "animated": True,
            "color": self.color,
            "linestyle": "",
            "marker": "x",
            "markerfacecolor": self.color,
            "markersize": 8,
        }

        arc_props = {
            "alpha": 0.5,
            "animated": True,
            "color": self.color,
            "linestyle": "dashed",
        }

        prong_props = {
            "alpha": 0.5,
            "animated": True,
            "color": self.color,
            "linestyle": "dashed",
            "linewidth": 1,
        }

        cx, cy = self.cxy
        wx, wy = self.wxy
        dx, dy = wx - cx, wy - cy
        r, angle = cart2pol(dx, dy)
        hspan = self.span / 2

        ex, ey = pol2cart(r * self.stickout, angle)

        # main arrow
        main_arrow = matplotlib.patches.FancyArrowPatch(
            posA=self.cxy, posB=(ex + cx, ey + cy), **main_arrow_props
        )
        self.artists["main_arrow"] = main_arrow
        self.axes.add_patch(main_arrow)

        # line
        line: matplotlib.lines.Line2D = self.axes.plot(
            [cx, wx], [cy, wy], **line_props
        )[0]
        self.artists["line"] = line
        self.axes.add_line(line)

        # arc
        arc = matplotlib.patches.Arc(
            xy=self.cxy,
            width=2 * r,
            height=2 * r,
            angle=angle,
            theta1=-hspan,
            theta2=hspan,
            **arc_props
        )
        self.artists["arc"] = arc
        self.axes.add_patch(arc)

        # prongs
        r_ext = r * self.stickout
        p1_angle = angle - hspan
        p1 = {"tail": pol2cart(r, p1_angle), "head": pol2cart(r_ext, p1_angle)}
        (prong1,) = self.axes.plot(
            [cx + p1["tail"][0], cx + p1["head"][0]],
            [cy + p1["tail"][1], cy + p1["head"][1]],
            **prong_props
        )
        self.artists["prong1"] = prong1
        self.axes.add_line(prong1)

        p2_angle = angle + hspan
        p2 = {"tail": pol2cart(r, p2_angle), "head": pol2cart(r_ext, p2_angle)}
        (prong2,) = self.axes.plot(
            [cx + p2["tail"][0], cx + p2["head"][0]],
            [cy + p2["tail"][1], cy + p2["head"][1]],
            **prong_props
        )
        self.artists["prong2"] = prong2
        self.axes.add_line(prong2)

    # === COMPUTED =========================================================== #
    @property
    def angle(self) -> float:
        cx, cy = self.cxy
        wx, wy = self.wxy
        dx, dy = wx - cx, wy - cy
        _, angle = cart2pol(dx, dy)
        return angle

    # === EXPORT ============================================================= #
    def get_params(self) -> Dict[str, Union[str, Callable, Tuple[int, int]]]:
        return {"id": self.id, "cxy": self.cxy, "wxy": self.wxy}

    # === INTERACTION ======================================================== #
    def get_ind_under_point(self, event: MouseEvent) -> int:
        line = self.artists["line"]

        xy = numpy.asarray(line.get_xydata())
        xyt = line.get_transform().transform(xy)
        xt, yt = xyt[:, 0], xyt[:, 1]

        d = numpy.hypot(xt - event.x, yt - event.y)
        ind_seq = numpy.nonzero(numpy.equal(d, numpy.amin(d)))[0]
        ind = ind_seq[0]

        if d[ind] >= epsilon:
            ind = None

        return ind

    def button_press_callback(self, event: MouseEvent) -> None:
        if event.inaxes is None:
            return
        if event.button != 1:
            return

        self._ind = self.get_ind_under_point(event)
        self._ind_last = self._ind

    def button_release_callback(self, event: MouseEvent) -> None:
        if event.button != 1:
            return

        self._ind = None

    def update_all(self) -> None:
        cx, cy = self.cxy
        wx, wy = self.wxy
        dx, dy = wx - cx, wy - cy
        r, angle = cart2pol(dx, dy)

        ex, ey = pol2cart(r * self.stickout, angle)

        self.artists["main_arrow"].set_positions(self.cxy, (cx + ex, cy + ey))
        self.artists["line"].set_data([cx, wx], [cy, wy])

        arc = self.artists["arc"]
        arc.angle = angle
        arc.width = 2 * r
        arc.height = 2 * r
        arc.center = self.cxy

        r_ext = r * self.stickout
        hspan = self.span / 2
        p1_angle = angle - hspan
        p1 = {"tail": pol2cart(r, p1_angle), "head": pol2cart(r_ext, p1_angle)}
        self.artists["prong1"].set_data(
            [cx + p1["tail"][0], cx + p1["head"][0]],
            [cy + p1["tail"][1], cy + p1["head"][1]],
        )

        p2_angle = angle + hspan
        p2 = {"tail": pol2cart(r, p2_angle), "head": pol2cart(r_ext, p2_angle)}
        self.artists["prong2"].set_data(
            [cx + p2["tail"][0], cx + p2["head"][0]],
            [cy + p2["tail"][1], cy + p2["head"][1]],
        )

    def motion_notify_callback(self, event: MouseEvent) -> None:
        if self._ind is None:
            return
        if event.inaxes is None:
            return
        if event.button != 1:
            return

        x, y = int(round(event.xdata)), int(round(event.ydata))
        if self._ind == 1:
            self._set_arrow_head(x, y)
            self.update_all()

        elif self._ind == 0:
            self._set_arrow_tail(x, y)
            self.update_all()

    def key_press_event(self, event: MouseEvent) -> None:
        if self._ind_last is None:
            return
        if event.inaxes is None:
            return

        key = event.key
        if self._ind_last == 1:
            # arrow head moved
            wx, wy = self.wxy
            wx, wy = move(key, wx, wy)
            self._set_arrow_head(wx, wy)
            self.update_all()

        elif self._ind_last == 0:
            cx, cy = self.cxy
            cx, cy = move(key, cx, cy)
            self._set_arrow_tail(cx, cy)
            self.update_all()

    def key_release_event(self, event: MouseEvent) -> None:
        if self._ind_last is None:
            return
        if event.inaxes is None:
            return

    # === ATOMIC INTERACTION ================================================= #
    def _set_arrow_head(self, x: int, y: int) -> None:
        self.wxy = x, y

    def _set_arrow_tail(self, x: int, y: int) -> None:
        self.cxy = x, y

class BaseInteractorsPanel(wx.Panel):
    def __init__(self, parent=None):
        super(BaseInteractorsPanel, self).__init__(parent=parent)

        self.interactors: List[BaseInteractor] = []
        self.factor = None
        self.image_id = None
        self.background = None

        self.BuildUI()

    def BuildUI(self):
        self.figure: matplotlib.figure.Figure = matplotlib.figure.Figure()
        self.axes: matplotlib.axes.Axes = self.figure.add_subplot(1, 1, 1)
        self.axes.set_aspect("equal")
        self.canvas = FigureCanvas(self, id=wx.ID_ANY, figure=self.figure)
        self.figure.tight_layout()

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.canvas, flag=wx.EXPAND, proportion=1)
        self.SetSizer(sizer)

        self.canvas.mpl_connect("draw_event", self.DrawCallback)
        self.canvas.mpl_connect("button_press_event", self.OnClick)
        self.canvas.mpl_connect("button_release_event", self.OnMouseButtonUp)
        self.canvas.mpl_connect("motion_notify_event", self.OnMouseMoved)
        self.canvas.mpl_connect("key_press_event", self.OnKeyPress)
        self.canvas.mpl_connect("key_release_event", self.OnKeyRelease)

    def DrawCallback(self, event: MouseEvent):
        self.background = self.canvas.copy_from_bbox(self.axes.bbox)

        for interactor in self.interactors:
            interactor.draw_callback(event)

        self.canvas.blit(self.axes.bbox)

    def OnClick(self, event: MouseEvent):
        if event.inaxes != self.axes:
            return
        if event.inaxes.get_navigate_mode() is not None:
            return

        for interactor in self.interactors:
            interactor.button_press_callback(event)

    def OnMouseButtonUp(self, event: MouseEvent):
        if event.inaxes is not None and event.inaxes.get_navigate_mode() is not None:
            return

        for interactor in self.interactors:
            interactor.button_release_callback(event)

    def OnMouseMoved(self, event: MouseEvent):
        if event.inaxes != self.axes:
            return

        self.UpdateInteractors(event)

    def OnKeyPress(self, event: MouseEvent):
        if event.inaxes != self.axes:
            return
        if event.inaxes.get_navigate_mode() is not None:
            return

        for interactor in self.interactors:
            interactor.key_press_event(event)

        self.UpdateInteractors(event)

    def OnKeyRelease(self, event: MouseEvent):
        if event.inaxes != self.axes:
            return
        if event.inaxes.get_navigate_mode() is not None:
            return

        for interactor in self.interactors:
            interactor.key_release_event(event)

        self.UpdateInteractors(event)

    def UpdateInteractors(self, event: MouseEvent):
        if self.background is not None:
            self.canvas.restore_region(self.background)
        else:
            self.background = self.canvas.copy_from_bbox(self.axes.bbox)

        for interactor in self.interactors:
            interactor.motion_notify_callback(event)
            interactor.draw_callback(event)

        self.canvas.blit(self.axes.bbox)

    def Render(self, image: Image):
        self.axes.clear()
        self.axes.imshow(image, interpolation="lanczos", vmin=0, vmax=255)

class DevicesInteractorsPanel(BaseInteractorsPanel):
    def __init__(self, parent=None):
        super(DevicesInteractorsPanel, self).__init__(parent=parent)

    def SetInteractors(
        self, interactors: List[Dict[str, Union[str, Callable, Tuple[int, int]]]]
    ) -> None:
        self.interactors = []
        for interactor in interactors:
            assert {"id", "cxy", "wxy", "artist"}.issubset(interactor.keys())
            artist = interactor["artist"](self.axes, **interactor)
            self.interactors.append(artist)

    def GetInteractors(self) -> List[Dict[str, Union[str, Callable, Tuple[int, int]]]]:
        return [interactor.get_params() for interactor in self.interactors]

class SingleBowAnnotationDialog(wx.Dialog):
    def __init__(self):
        title = "Bow Annotation"
        frame_style = (
            wx.MAXIMIZE_BOX
            | wx.MINIMIZE_BOX
            | wx.RESIZE_BORDER
            | wx.SYSTEM_MENU
            | wx.CAPTION
            | wx.CLOSE_BOX
            | wx.CLIP_CHILDREN
        )
        frame_size = 1500, 800  # width, height

        super(SingleBowAnnotationDialog, self).__init__(
            parent=None, title=title, style=frame_style, size=frame_size
        )

        self.interactorsP = DevicesInteractorsPanel(self)

        buttonSize = (70, 30)
        okBtn = wx.Button(self, id=wx.ID_OK, label="OK", size=buttonSize)
        buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
        buttonSizer.Add(okBtn, flag=wx.ALL, border=5)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.interactorsP, flag=wx.EXPAND, proportion=1)
        sizer.Add(buttonSizer, flag=wx.ALL | wx.CENTER, border=5)
        self.SetSizer(sizer)

    def SetImage(self, image: Image) -> None:
        self.interactorsP.Render(image)

    def SetInteractors(self, *args, **kwargs) -> None:
        self.interactorsP.SetInteractors(*args, **kwargs)

    def GetInteractors(self) -> Dict[str, Union[str, Callable, Tuple[int, int]]]:
        interactors = self.interactorsP.GetInteractors()
        assert len(interactors) == 1
        return interactors[0]

class IdentifyBow(cellprofiler.module.Module):
    module_name = "IdentifyBow"
    category = "JonasLab Custom"
    variable_revision_number = 0

    def volumetric(self) -> bool:
        return False

    def create_settings(self) -> None:
        module_explanation = (
            "Construct a bow from User-supplied parameters regarding the position and "
            "orientation of drug release from a well. Usage notes: Because this module "
            "is interactive, a graphical user interface must be shown. The eye icon "
            "only toggles the visibility of the result of choosing the bow. Note that "
            "in Analysis mode, each core displays its own window."
        )
        self.set_notes([module_explanation])

        self.image_name = cellprofiler.setting.ImageNameSubscriber(
            text="Select image to identify bow on",
            value=cellprofiler.setting.NONE,
            doc="Select image to identify bow on",
        )

        self.advanced = cellprofiler.setting.Binary(
            text="Use custom settings?",
            value=False,
            doc="Set how the bow is rendered on the image.",
        )

        self.spacer = cellprofiler.setting.Divider(line=True)

        self.span = cellprofiler.setting.Float(
            text="Set bow span", value=90.0, doc="Set the bow span, in degrees."
        )

        self.stickout = cellprofiler.setting.Float(
            text="Set bow stickout",
            value=1.3,
            doc="""\
            Set the bow stickout, as a factor of the distance between the center and
            the well.""",
        )

    def settings(self) -> List[cellprofiler.setting.Setting]:
        return [self.image_name, self.advanced, self.spacer, self.span, self.stickout]

    def visible_settings(self) -> List[cellprofiler.setting.Setting]:
        settings = [self.image_name, self.advanced]
        if self.advanced:
            settings += [self.spacer, self.span, self.stickout]
        return settings

    def get_measurement_columns(self, pipeline: cellprofiler.pipeline.Pipeline):
        return [
            (
                cellprofiler.measurement.IMAGE,
                "Metadata_Bow_" + measurement_name,
                cellprofiler.measurement.COLTYPE_INTEGER,
            )
            for measurement_name in MEASUREMENTS
        ]

    def prepare_run(self, workspace: cellprofiler.workspace.Workspace) -> None:
        for measurement_name in ["CenterX", "CenterY", "WellX", "WellY"]:
            workspace.measurements.add_measurement(
                object_name=cellprofiler.measurement.IMAGE,
                feature_name="Wedge_" + measurement_name,
                data=0,
                data_type=cellprofiler.measurement.COLTYPE_INTEGER,
            )

    def run(self, workspace: cellprofiler.workspace.Workspace) -> None:
        image_name: str = self.image_name.value
        image: Image = workspace.image_set.get_image(image_name).pixel_data

        # get measurements
        params_pre = [
            {
                "id": "0",
                "artist": BowInteractor,
                "cxy": [100, 100],
                "wxy": [200, 200],
                "span": self.span.value,
                "stickout": self.stickout.value,
            }
        ]
        params_post = workspace.interaction_request(self, image, params_pre)
        assert {"id", "cxy", "wxy"} == set(params_post.keys())
        # save measurements
        cx, cy = params_post["cxy"]
        wx, wy = params_post["wxy"]
        workspace.measurements.add_image_measurement(
            feature_name="Bow_Center_X", data=cx
        )
        workspace.measurements.add_image_measurement(
            feature_name="Bow_Center_Y", data=cy
        )
        workspace.measurements.add_image_measurement(feature_name="Bow_Well_X", data=wx)
        workspace.measurements.add_image_measurement(feature_name="Bow_Well_Y", data=wy)

    def handle_interaction(
        self,
        image: Image,
        bow_params_pre: Dict[str, Union[str, Callable, Tuple[int, int]]],
    ) -> Union[Dict[str, Union[str, Callable, Tuple[int, int]]], None]:
        with SingleBowAnnotationDialog() as dialog:
            dialog.SetImage(image)
            dialog.SetInteractors(bow_params_pre)

            result = dialog.ShowModal()
            if result == wx.ID_OK:
                return dialog.GetInteractors()
            raise RuntimeError("Unable to obtain bow parameters!")


import numpy as np
from math import sin, cos

def bar(E, A, L, phi):
    """Computes the stiffness and stress matrix for one element

    Parameters
    ----------
    E : float
        modulus of elasticity
    A : float
        cross-sectional area
    L : float
        length of element
    phi : float
        orientation of element

    Outputs
    -------
    K : 4 x 4 ndarray
        stiffness matrix
    S : 1 x 4 ndarray
        stress matrix

    """

    # rename
    c = cos(phi)
    s = sin(phi)

    # stiffness matrix
    k0 = np.array([[c**2, c * s], [c * s, s**2]])
    k1 = np.hstack([k0, -k0])
    K = E * A / L * np.vstack([k1, -k1])

    # stress matrix
    S = E / L * np.array([[-c, -s, c, s]])

    return K, S

def node2idx(node, DOF):
    """Computes the appropriate indices in the global matrix for
    the corresponding node numbers.  You pass in the number of the node
    (either as a scalar or an array of locations), and the degrees of
    freedom per node and it returns the corresponding indices in
    the global matrices

    """

    idx = np.array([], dtype=int)

    for i in range(len(node)):

        n = node[i]
        start = DOF * (n - 1)
        finish = DOF * n

        idx = np.concatenate((idx, np.arange(start, finish, dtype=int)))

    return idx

def truss(nodes1, nodes2, phi, A, L, E, rho, Fx, Fy, rigid, Solve):
    """Computes mass and stress for an arbitrary truss structure

    Parameters
    ----------
    nodes1 : ndarray of length nbar
        indices of the first nodes for bars. `nodes1` and `nodes2` can be in any order as long as consistent with phi
    nodes2 : ndarray of length nbar
        indices of the other nodes for bars
    phi : ndarray of length nbar (radians)
        defines orientation or bar
    A : ndarray of length nbar
        cross-sectional areas of each bar
    L : ndarray of length nbar
        length of each bar
    E : ndarray of length nbar
        modulus of elasticity of each bar
    rho : ndarray of length nbar
        material density of each bar
    Fx : ndarray of length nnode
        external force in the x-direction at each node
    Fy : ndarray of length nnode
        external force in the y-direction at each node
    rigid : list(boolean) of length nnode
        True if node_i is rigidly constrained

    Outputs
    -------
    mass : float
        mass of the entire structure
    stress : ndarray of length nbar
        stress of each bar

    """

    n = len(Fx)  # number of nodes
    DOF = 2  # number of degrees of freedom
    nbar = len(A)  # number of bars

    # mass
    mass = np.sum(rho * A * L)

    # stiffness and stress matrices
    K = np.zeros((DOF * n, DOF * n), dtype=complex)
    S = np.zeros((nbar, DOF * n), dtype=complex)

    for i in range(nbar):  # loop through each bar

        # compute submatrix for each element
        Ksub, Ssub = bar(E[i], A[i], L[i], phi[i])

        # insert submatrix into global matrix
        idx = node2idx([nodes1[i], nodes2[i]], DOF)  # pass in the starting and ending node number for this element
        K[np.ix_(idx, idx)] += Ksub
        S[i, idx] = Ssub

    # applied loads
    F = np.zeros((n * DOF, 1))

    for i in range(n):
        idx = node2idx([i + 1], DOF)  # add 1 b.c. made indexing 1-based for convenience
        F[idx[0]] = Fx[i]
        F[idx[1]] = Fy[i]

    # boundary condition
    idx = np.squeeze(np.where(rigid))
    remove = node2idx(idx + 1, DOF)  # add 1 b.c. made indexing 1-based for convenience

    K = np.delete(K, remove, axis=0)
    K = np.delete(K, remove, axis=1)
    F = np.delete(F, remove, axis=0)
    S = np.delete(S, remove, axis=1)
    if Solve == True:
        # solve for deflections
        d = np.linalg.solve(K, F)

        # compute stress
        stress = np.dot(S, d).reshape(nbar)
        return mass, stress, K, S, d

    else:
        return K, S

def tenbartruss(A, h, grad_method='FD', aggregate=False):
    """This is the subroutine for the 10-bar truss.
    TODO: You will need to complete it.

    Parameters
    ----------
    A : ndarray of length 10
        cross-sectional areas of all the bars
    grad_method : string (optional)
        gradient type.
        'FD' for finite difference,
        'CS' for complex step,
        'DT' for direct method,
        'AJ' for adjoint method,
        'AD' for automatic differentiation (extra credit).
    aggregate : bool (optional)
        If True, return the KS-aggregated stress constraint. If False, do not aggregate and return all stresses.
        The derivatives implementation for `aggreagate`=True is optional (extra credit).

    Outputs
    -------
    mass : float
        mass of the entire structure
    stress : ndarray of length 10 (if `aggregate`=False); float (if `aggregate`=True)
        stress of each bar or KS-aggregated stress value
    dmass_dA : ndarray of length 10
        derivative of mass w.r.t. each A
    dstress_dA : 10 x 10 ndarray (if `aggregate`=False); ndarray of length 10 if `aggregate`=True
        If `aggregated`=False, dstress_dA[i, j] is derivative of stress[i] w.r.t. A[j]
        If `aggregated`=True,  dstress_dA[j] is derivative of the KS-aggregated stress w.r.t. A[j]
    """

    # --- setup 10 bar truss ----
    # Truss node indexing:
    # wall > 1 ---------- 2 ---------- 3
    #          ++      ++ | ++      ++ |
    #            ++  ++   |   ++  ++   |
    #              ++     |     ++     |
    #            ++  ++   |   ++  ++   |
    #          ++      ++ | ++      ++ |
    # wall > 4 ---------- 5 ---------- 6

    # define bars by [node1, node2]
    bars_node = [
        [1, 2],   # bar 1
        [2, 3],   # bar 2 ...
        [4, 5],
        [5, 6],
        [2, 5],
        [3, 6],
        [1, 5],
        [2, 4],
        [2, 6],
        [3, 5]
    ]

    # arrays of the 1st and 2nd nodes
    nodes1 = []
    nodes2 = []
    for bar in bars_node:
        nodes1.append(bar[0])
        nodes2.append(bar[1])

    # bar orientations
    phi = np.deg2rad(np.array([0, 0, 0, 0, -90, -90, -45, -135, -45, -135]))

    # bar lengths
    bar_l = 10  # m
    ld = bar_l * np.sqrt(2)    # length of diagonal bars
    L  = np.array([bar_l, bar_l, bar_l, bar_l, bar_l, bar_l, ld, ld, ld, ld])

    # Young Modulus of each bar
    E = np.ones(10) * 70 * 10**9  # Pa

    # density of each bar
    rho = np.ones(10) * 2720  # kg/m^3

    # external loads
    P = 5 * 10**5     # N
    Fx = np.zeros(6)
    Fy = np.array([0, 0, 0, 0, -P, -P])

    # boundary condition (set True for clamped nodes)
    rigid = [True, False, False, True, False, False]

    # --- call truss function ----
    # This will compute the mass and stress of your truss structure. This call computes the baseline stress with h = 0

    J = np.zeros((10,10)) #Jacobian is a 10 by 10 matrix
    mass, stress, K, S, d = truss(nodes1, nodes2, phi, A, L, E, rho, Fx, Fy, rigid, Solve = True)
    # TODO: You may want to return additional variables from `truss` function for the implicit analytic methods.
    #       Feel free to modify `truss` function.

    # --- compute derivatives for provided grad_type ----
    # TODO: Implement derivatives for each method here

    #Within FD implementations. We have a double for loop in which we loop through each stress, and within each stress, we perturb the corresponding area to find the derivative dSigma_i/dA_j
    if grad_method == 'FD':
        # implement a finite difference
        for j in range(10):
            A[j] = A[j] + h #Perturb the specific bar area

            mass_new, stress_new, K_new, S_new, d_new = truss(nodes1, nodes2, phi, A, L, E, rho, Fx, Fy, rigid, Solve = True)

            J[:,j] = (stress_new - stress)/h

            A[j] = A[j] - h #Return to original array

    elif grad_method == 'CS':
        # implement complex step
        for j in range(10):
            A[j] = A[j] + h*1j #Perturb the specific bar area in imaginary values

            mass_new, stress_new, K_new, S_new, d_new = truss(nodes1, nodes2, phi, A, L, E, rho, Fx, Fy, rigid, Solve = True)

            J[:,j] = np.imag(stress_new)/(h)

            A[j] = np.real(A[j]) #Return to original array

    elif grad_method == 'DT_CS':
        dr_dx = np.zeros((len(d),len(A)))
        for i in range (10):
            A[i] = A[i] + h*1j
            K_new, S_new = truss(nodes1, nodes2, phi, A, L, E, rho, Fx, Fy, rigid, Solve = False)
            dr_dx_i = (np.imag(K_new@d))/h
            dr_dx[:,i] = dr_dx_i.squeeze()
            A[i] = A[i] - h*1j #Reset array back to its original state
        phi = np.linalg.solve(K,dr_dx)
        J   = -S@phi

    elif grad_method == 'AJ_CS':
        dr_dx = np.zeros((len(d),len(A)))
        for i in range (10):
            A[i] = A[i] + h*1j
            K_new, S_new = truss(nodes1, nodes2, phi, A, L, E, rho, Fx, Fy, rigid, Solve = False)
            dr_dx_i = (np.imag(K_new@d))/h
            dr_dx[:,i] = dr_dx_i.squeeze()
            A[i] = A[i] - h*1j #Reset array back to its original state
        xi = np.linalg.solve(K,S.T)
        J   = -xi.T@dr_dx

    return mass, stress, J


from itertools import combinations, permutations
n = int(input())

board = [list(map(int, input().split())) for _ in range(n)]

def getScore(players):
    enemies = [i for i in range(1, n+1) if i not in players]
    return abs(sum([board[p1-1][p2-1]+board[p2-1][p1-1] for p1, p2 in combinations(players, 2)]) -
               sum([board[q1-1][q2-1]+board[q2-1][q1-1] for q1, q2 in combinations(enemies, 2)]))

def solution(n, board):
    return min([getScore(players) for players in list(combinations(range(1, n+1), n//2))])

print(solution(n, board))


import pandas as pd
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import MinMaxScaler
from sklearn.svm import SVC

train_data = pd.read_csv("../data_csv/train.csv")
test_data = pd.read_csv("../data_csv/test.csv")

# Split train to x and y
y = train_data["label"]
del train_data["label"]

# Split the data
X_train, X_test, y_train, y_test = train_test_split(train_data, y, random_state=1)

# Scale data
scaler = MinMaxScaler()
# Model
clf = SVC(C=8)
# Pipeline
pipeline = Pipeline([('transformer', scaler), ('estimator', clf)])

scores = cross_val_score(pipeline, X_train, y_train, cv=10)
print("Accuracy: %0.4f (+/- %0.2f)" % (scores.mean(), scores.std()))

X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
clf.fit(X_train, y_train)

X_test = scaler.transform(X_test)
cost_train = mean_squared_error(y_train, clf.predict(X_train))
cost_test = mean_squared_error(y_test, clf.predict(X_test))
print("Cost train: %f Cost test: %f" % (cost_train, cost_test))

train_score = clf.score(X_train, y_train)
test_score = clf.score(X_test, y_test)
print("Train score: %f Test score: %f" % (train_score, test_score))

# Fit unlabeled data
test_data = scaler.transform(test_data)
Y = pd.Series(clf.predict(test_data))
Y.name = "Label"
image_id = pd.Series(range(1, Y.shape[0] + 1))
image_id.name = "ImageId"
prediction_data = pd.concat([image_id, Y], axis=1)
# Create prediction csv
prediction_data.to_csv("../data_csv/prediction.csv", index=False)


from functools import cache

def solve():
    n,m,d = list(map(int,input().split(" ")))
    a = list(map(int,input().split(" ")))

    @cache
    def recursion(prevDay,m,i):
        if m==0 or i==n: return 0
        # take
        ans = a[i]-d*(i+1-prevDay)+recursion(i+1,m-1,i+1)
        # not take
        ans = max(ans,recursion(prevDay,m,i+1))
        return ans

    dp = [[[0,0]]*(m+1) for _ in range(n+1)]
    for mi in range(m,0,-1):
        for ii in range(n):
            # take
            ans = a[ii]-d*(ii+1-prevDay)+recursion(ii+1,mi-1,ii+1)
            # not take
            ans = max(ans,recursion(prevDay,mi,ii+1))
            return ans

    print(dp)

    return recursion(0,m,0)

def getIns():
    for _ in range(int(input())):
        print(solve())

# getIns()

from contextlib import redirect_stdout
with open('out.txt', 'w') as f:
    with redirect_stdout(f): getIns()


import boto3
client = boto3.client('s3')

# This Function will Read File from S3 Bucket whenever any file with .txt extension is created in S3
# Bucket - pythondatademo123
# Region - us-east-1

def file_handler(event, context):

    # Read data from S3 Bucket
    data = client.get_object(
        Bucket='pythondatademo123',
        Key='demo/data.txt'
    )

    contents = data['Body'].read()

    # Print data to Log - CloudWatch
    print(contents)


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

import os
import tempfile

import tensorflow as tf
from tensorflow_model_analysis.api import model_eval_lib
from tensorflow_model_analysis.eval_saved_model import testutil
from tensorflow_model_analysis.eval_saved_model.example_trainers import csv_linear_classifier
from tensorflow_model_analysis.eval_saved_model.example_trainers import custom_estimator
from tensorflow_model_analysis.eval_saved_model.example_trainers import fixed_prediction_estimator
from tensorflow_model_analysis.eval_saved_model.example_trainers import linear_classifier
from tensorflow_model_analysis.eval_saved_model.post_export_metrics import metric_keys
from tensorflow_model_analysis.eval_saved_model.post_export_metrics import post_export_metrics
from tensorflow_model_analysis.slicer import slicer

class EvaluateTest(testutil.TensorflowModelAnalysisTest):

  def setUp(self):
    self.longMessage = True

  def _getTempDir(self):
    return tempfile.mkdtemp()

  def _exportEvalSavedModel(self, classifier):
    temp_model_location = os.path.join(self._getTempDir(), 'eval_export_dir')
    _, model_location = classifier(None, temp_model_location)
    return model_location

  def _writeTFExamplesToTFRecords(self, examples):
    data_location = os.path.join(self._getTempDir(), 'input_data.rio')
    with tf.python_io.TFRecordWriter(data_location) as writer:
      for example in examples:
        writer.write(example.SerializeToString())
    return data_location

  def _writeCSVToTextFile(self, examples):
    data_location = os.path.join(self._getTempDir(), 'input_data.csv')
    with open(data_location, 'w') as writer:
      for example in examples:
        writer.write(example + '\n')
    return data_location

  def assertMetricsAlmostEqual(self, got_value, expected_value):
    for (s, m) in got_value:
      self.assertIn(s, expected_value)
      self.assertDictElementsAlmostEqual(m, expected_value[s])

  def assertPlotsAlmostEqual(self, got_value, expected_value):
    for (s, m) in got_value:
      self.assertIn(s, expected_value)
      self.assertDictMatrixRowsAlmostEqual(m, expected_value[s])

  def testRunModelAnalysis(self):
    model_location = self._exportEvalSavedModel(
        linear_classifier.simple_linear_classifier)
    examples = [
        self._makeExample(age=3.0, language='english', label=1.0),
        self._makeExample(age=3.0, language='chinese', label=0.0),
        self._makeExample(age=4.0, language='english', label=1.0),
        self._makeExample(age=5.0, language='chinese', label=1.0)
    ]
    data_location = self._writeTFExamplesToTFRecords(examples)
    slice_spec = [slicer.SingleSliceSpec(columns=['language'])]
    eval_result = model_eval_lib.run_model_analysis(
        model_location,
        data_location,
        slice_spec=slice_spec,
        example_weight_key='age')
    # We only check some of the metrics to ensure that the end-to-end
    # pipeline works.
    expected = {
        (('language', 'chinese'),): {
            'accuracy': 0.5,
            'my_mean_label': 0.5,
            metric_keys.EXAMPLE_WEIGHT: 8.0,
            metric_keys.EXAMPLE_COUNT: 2.0,
        },
        (('language', 'english'),): {
            'accuracy': 1.0,
            'my_mean_label': 1.0,
            metric_keys.EXAMPLE_WEIGHT: 7.0,
            metric_keys.EXAMPLE_COUNT: 2.0,
        }
    }
    self.assertEqual(eval_result.config.model_location, model_location)
    self.assertEqual(eval_result.config.data_location, data_location)
    self.assertEqual(eval_result.config.slice_spec, slice_spec)
    self.assertMetricsAlmostEqual(eval_result.slicing_metrics, expected)
    self.assertFalse(eval_result.plots)

  def testRunModelAnalysisWithPlots(self):
    model_location = self._exportEvalSavedModel(
        fixed_prediction_estimator.simple_fixed_prediction_estimator)
    examples = [
        self._makeExample(prediction=0, label=1.0),
        self._makeExample(prediction=0.7, label=0.0),
        self._makeExample(prediction=0.8, label=1.0),
        self._makeExample(prediction=1.0, label=1.0)
    ]
    data_location = self._writeTFExamplesToTFRecords(examples)
    eval_result = model_eval_lib.run_model_analysis(
        model_location,
        data_location,
        add_metrics_callbacks=[post_export_metrics.auc_plots()])
    # We only check some of the metrics to ensure that the end-to-end
    # pipeline works.
    expected_metrics = {(): {metric_keys.EXAMPLE_COUNT: 4.0,}}
    expected_plots = {
        (): {
            metric_keys.AUC_PLOTS_MATRICES: [(8001, [
                2, 1, 0, 1, 1.0 / 1.0, 1.0 / 3.0
            ])],
        }
    }
    self.assertMetricsAlmostEqual(eval_result.slicing_metrics, expected_metrics)
    self.assertPlotsAlmostEqual(eval_result.plots, expected_plots)

  def testRunModelAnalysisForCSVText(self):
    model_location = self._exportEvalSavedModel(
        csv_linear_classifier.simple_csv_linear_classifier)
    examples = [
        '3.0,english,1.0', '3.0,chinese,0.0', '4.0,english,1.0',
        '5.0,chinese,1.0'
    ]
    data_location = self._writeCSVToTextFile(examples)
    eval_result = model_eval_lib.run_model_analysis(
        model_location, data_location, file_format='text')
    # We only check some of the metrics to ensure that the end-to-end
    # pipeline works.
    expected = {(): {'accuracy': 0.75, metric_keys.EXAMPLE_COUNT: 4.0}}
    self.assertMetricsAlmostEqual(eval_result.slicing_metrics, expected)

  def testMultipleModelAnalysis(self):
    model_location_1 = self._exportEvalSavedModel(
        linear_classifier.simple_linear_classifier)
    model_location_2 = self._exportEvalSavedModel(
        custom_estimator.simple_custom_estimator)
    examples = [
        self._makeExample(age=3.0, language='english', label=1.0),
        self._makeExample(age=3.0, language='chinese', label=0.0),
        self._makeExample(age=4.0, language='english', label=1.0),
        self._makeExample(age=5.0, language='chinese', label=1.0)
    ]
    data_location = self._writeTFExamplesToTFRecords(examples)
    eval_results = model_eval_lib.multiple_model_analysis(
        [model_location_1, model_location_2],
        data_location,
        slice_spec=[slicer.SingleSliceSpec(features=[('language', 'english')])])
    # We only check some of the metrics to ensure that the end-to-end
    # pipeline works.
    self.assertEqual(2, len(eval_results._results))
    expected_result_1 = {
        (('language', 'english'),): {
            'my_mean_label': 1.0,
            metric_keys.EXAMPLE_COUNT: 2.0
        }
    }
    expected_result_2 = {
        (('language', 'english'),): {
            'mean_label': 1.0,
            metric_keys.EXAMPLE_COUNT: 2.0
        }
    }
    self.assertMetricsAlmostEqual(eval_results._results[0].slicing_metrics,
                                  expected_result_1)
    self.assertMetricsAlmostEqual(eval_results._results[1].slicing_metrics,
                                  expected_result_2)

  def testMultipleDataAnalysis(self):
    model_location = self._exportEvalSavedModel(
        linear_classifier.simple_linear_classifier)
    data_location_1 = self._writeTFExamplesToTFRecords([
        self._makeExample(age=3.0, language='english', label=1.0),
        self._makeExample(age=3.0, language='english', label=0.0),
        self._makeExample(age=5.0, language='chinese', label=1.0)
    ])
    data_location_2 = self._writeTFExamplesToTFRecords(
        [self._makeExample(age=4.0, language='english', label=1.0)])
    eval_results = model_eval_lib.multiple_data_analysis(
        model_location, [data_location_1, data_location_2],
        slice_spec=[slicer.SingleSliceSpec(features=[('language', 'english')])])
    self.assertEqual(2, len(eval_results._results))
    # We only check some of the metrics to ensure that the end-to-end
    # pipeline works.
    expected_result_1 = {
        (('language', 'english'),): {
            metric_keys.EXAMPLE_COUNT: 2.0,
        }
    }
    expected_result_2 = {
        (('language', 'english'),): {
            metric_keys.EXAMPLE_COUNT: 1.0,
        }
    }
    self.assertMetricsAlmostEqual(eval_results._results[0].slicing_metrics,
                                  expected_result_1)
    self.assertMetricsAlmostEqual(eval_results._results[1].slicing_metrics,
                                  expected_result_2)

if __name__ == '__main__':
  tf.test.main()


from PyQt5 import QtCore, QtGui
from PyQt5.QtWidgets import QApplication, QWidget
import sys

class Example(QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.setGeometry(300, 300, 250, 150)
        self.show()

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Q:
            print ("Killing")
            self.deleteLater()
        elif event.key() == QtCore.Qt.Key_Enter:
            self.proceed()
        event.accept()

    def proceed(self):
        print ("Call Enter Key")

def main():
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()