from random import sample, random

# CONSTANT
POPULATION = 100
PAIRS = int(POPULATION / 2)
TOP_N = 30
CROSSOVER_RATE = 0.7
MUTATION_RATE = 0.5
CONVERGED_NUMBER = 15

# Types
# Chromosome: (number (fitness), ChromosomeValue)
# ChromosomeValue: number[number (index)]
# Restaurant: {
#     _id: string
#     profile: {
#         categories: {
#             name_en: string
#         }[]
#         price_range: number
#     }
# }
# User: {
#     categories: string[]
#     price_range: number
# }

def genetic_algorithm_recommender(restaurants, users, genes=6, get_matrix=False, varbose=False):

    # return: number
    def compute_fitness(chromosome_value):
        group_score = 0

        for user in users:
            score_sum = 0
            user_categories = user['categories']
            user_categories_set = set(user_categories)
            user_price_range = user.get('price_range', -1)
            if not user_price_range:
                user_price_range = None

            for index in chromosome_value:
                score = 0
                restaurant = restaurants[index]
                restaurant_categories = [category['name_en'] for category in restaurant['profile']['categories']]
                restaurant_price_range = restaurant['profile']['price_range'] or None
                restaurant_distance = restaurant['dist']['calculated'] or None

                preference_score = 0
                for index, user_category in enumerate(user_categories):
                    if user_category in restaurant_categories:
                        preference_score += len(user_categories) - index

                price_score = 0
                if user_price_range and restaurant_price_range:
                    gap = user_price_range - restaurant_price_range
                    if gap == 0:
                        price_score = 3
                    elif gap == 1:
                        price_score = 2
                    elif gap == 2:
                        price_score = 1

                # distance_score = 0
                # if restaurant_distance:
                #     if restaurant_distance < 1000:
                #         distance_score = 3
                #     elif restaurant_distance < 3000:
                #         distance_score = 1

                history_score = 0

                score = preference_score + price_score + history_score
                score_sum += score

            group_score += score_sum

        return group_score

    def get_top_n_chromosomes(chromosomes, top_n):
        return sorted(chromosomes, key= lambda chromosome: chromosome[0], reverse=True)[:top_n]

    # return: [(list[] (ChromosomeValue), list (ChromosomeValue))]
    def get_pairs(chromosomes):
        pairs = []
        selected_chromosomes = get_top_n_chromosomes(chromosomes, TOP_N)
        for _ in range(PAIRS):
            new_pair = []
            count = 0
            while True:
                if count == 100:
                    break
                new_pair = sample(range(len(selected_chromosomes)), 2)
                count += 1
                if new_pair not in pairs:
                    pairs.append(new_pair)
                    break
        return [(selected_chromosomes[pair[0]], selected_chromosomes[pair[1]]) for pair in pairs]

    # return [ChromosomeValue, ChromosomeValue]
    def crossover(chromosome_value_1, chromosome_value_2):
        new_chromosome_value_1 = []
        new_chromosome_value_2 = []
        for index, each_chromosome_value_1 in enumerate(chromosome_value_1):
            each_new_chromosome_value_1 = chromosome_value_1[index]
            each_new_chromosome_value_2 = chromosome_value_2[index]

            is_swap = False
            if each_chromosome_value_1 not in chromosome_value_2 and each_new_chromosome_value_2 not in chromosome_value_1 and random() < CROSSOVER_RATE:
                is_swap = True

            if is_swap:
                each_new_chromosome_value_1 = chromosome_value_2[index]
                each_new_chromosome_value_2 = chromosome_value_1[index]

            new_chromosome_value_1.append(each_new_chromosome_value_1)
            new_chromosome_value_2.append(each_new_chromosome_value_2)
        return [new_chromosome_value_1, new_chromosome_value_2]

    def mutate(chromosome_value):
        if random() < MUTATION_RATE:
            mutated_chromosome_value = []
            for each_chromosome_value in chromosome_value:
                if random() < MUTATION_RATE:
                    count = 0
                    while True:
                        if count == 100:
                            mutated_chromosome_value.append(each_chromosome_value)
                            break
                        else:
                            count += 1
                            new_gene = sample(range(len(restaurants)), 1)[0]
                            if new_gene not in chromosome_value and new_gene not in mutated_chromosome_value:
                                mutated_chromosome_value.append(new_gene)
                                break
                else:
                    mutated_chromosome_value.append(each_chromosome_value)
            return [chromosome_value, mutated_chromosome_value]

        return [chromosome_value]

    def generate_new_generation(pairs):
        crossovered_chromosomes = []
        new_generation = []
        # crossover
        for pair in pairs:
            chromosome_1 = pair[0]
            chromosome_2 = pair[1]
            new_chromosomes = crossover(chromosome_1[1], chromosome_2[1])
            crossovered_chromosomes += new_chromosomes
        # mutation
        for chromosome_value in crossovered_chromosomes:
            new_generation += mutate(chromosome_value)
        return new_generation

    def add_fitness_for_population(chromosome_values):
        return [(compute_fitness(chromosome_value), chromosome_value) for chromosome_value in chromosome_values]

    def initialize_population():
        # check for dup
        return [sample(range(len(restaurants)), genes) for _ in range(POPULATION)]

    def is_converged(generation_highest_fitnesses):
        return len(generation_highest_fitnesses) > CONVERGED_NUMBER and generation_highest_fitnesses[-1] == generation_highest_fitnesses[-CONVERGED_NUMBER]

    population = initialize_population()
    generation_highest_fitnesses = []
    generation_highest_fitness_chromosomes = []

    number_of_generation = 0
    while True:
        number_of_generation += 1
        chromosomes = add_fitness_for_population(population)
        highest_fitness_chromosome = max(chromosomes)
        generation_highest_fitnesses.append(highest_fitness_chromosome[0])
        generation_highest_fitness_chromosomes.append(highest_fitness_chromosome)
        print(f"Gen#{number_of_generation}: {highest_fitness_chromosome}") if varbose else ''
        if number_of_generation == 100 or is_converged(generation_highest_fitnesses):
            print(f"Result: {highest_fitness_chromosome}") if varbose else ''
            recommended_restaurants = [restaurants[index] for index in highest_fitness_chromosome[1]]
            return recommended_restaurants if not get_matrix else (recommended_restaurants, generation_highest_fitness_chromosomes)
        pairs = get_pairs(chromosomes)
        population = generate_new_generation(pairs)

def test_genetic_algorithm_recommender(count=6):
    # import requests

    import json
    # response = requests.get('https://neutron-dot-restaurant-recommender-system.et.r.appspot.com/api/restaurants/nearby?lat=13.64999266005064&lon=100.49433963566172&dist=10000&limit=100')
    with open('recommender/test_data/nearby_restaurants.json') as f:
        response = json.load(f)
    input_restaurants = response
    input_restaurants = [restaurant for restaurant in input_restaurants if restaurant['type'] == 'restaurant']
    user_irin = {
        "name": "irin",
        "categories": ['Korean', 'Japanese', 'Italian', 'Thai', 'Shabu Shabu'],
        "price_range": 2,
    }
    user_north = {
        "name": "north",
        "categories": ['Thai', 'Japanese', 'Korean', 'Shabu Shabu', 'Steakhouse'],
        "price_range": 3,
    }
    users = [user_irin, user_north]
    recommended_retaurants, generations = genetic_algorithm_recommender(input_restaurants, users, get_matrix=True, genes=count)
    # pprint([(restaurant['name'], [cat['name_en'] for cat in restaurant['profile']['categories']]) for restaurant in recommended_retaurants])
    return recommended_retaurants, generations

if __name__ == '__main__':
    from pprint import pprint
    recommended_retaurants, generations = test_genetic_algorithm_recommender(count=6)
    pprint(generations)
    pprint([(restaurant['name'], [cat['name_en'] for cat in restaurant['profile']['categories']], restaurant['profile']['price_range']) for restaurant in recommended_retaurants])


from time import sleep, time

import Viewer
from PIL import Image, ImageDraw
from math import *

from ConstantTime import GameClock

class Point:

    def __init__(self, x, y):
        self.x = x
        self.y = y

    @property
    def tuple(self):
        return self.x, self.y

    def draw(self, canvas: ImageDraw.ImageDraw):
        canvas.point(self.tuple, 'black')

g = 9.81
pi2 = pi * 2

class Pendulum:

    def __init__(self, length=30.0, mass=2.0, angle=2.0, velocity=0.0, acc=0.0, damping=0.999):
        self.start = Point(0, 0)
        self.length = length
        self._mass = mass
        self._angle = radians(angle)
        self.velocity = velocity
        self.damping = damping
        self.acc = acc
        self.child = None  # type:Pendulum
        self.parent = None  # type:Pendulum

    @property
    def angle(self):
        return degrees(self._angle)

    def __repr__(self):
        return '<Pendulum angle:{:.2f} mass:{} acceleration:{:.2f} velocity:{:.2f}>'.format(self.angle, self.mass,
                                                                                self.acc, self.velocity)

    @angle.setter
    def angle(self, value):
        self._angle = radians(value)

    @property
    def mass(self):
        if self.child and False:
            return self._mass + self.child.mass * abs(cos(self.child._angle))
        else:
            return self._mass

    def update(self,delta):
        if self.child:

            m1 = self.mass
            m2 = self.child.mass
            a1 = self._angle
            a2 = self.child._angle
            r1 = self.length
            r2 = self.child.length
            a1_v = self.velocity
            a2_v = self.child.velocity
            num1 = -g * (2 * m1 + m2) * sin(a1)
            num2 = -m2 * g * sin(a1 - 2 * a2)
            num3 = -2 * sin(a1 - a2) * m2
            num4 = a2_v * a2_v * r2 + a1_v * a1_v * r1 * cos(a1 - a2)
            den = r1 * (2 * m1 + m2 - m2 * cos(2 * a1 - 2 * a2))
            self.acc = (num1 + num2 + num3 * num4) / den
            self.child.update(delta)

        else:
            m1 = self.parent.mass
            m2 = self.mass
            a1 = self.parent._angle
            a2 = self._angle
            r1 = self.parent.length
            r2 = self.length
            a1_v = self.parent.velocity
            a2_v = self.velocity
            num1 = 2 * sin(a1 - a2)
            num2 = (a1_v * a1_v * r1 * (m1 + m2))
            num3 = g * (m1 + m2) * cos(a1)
            num4 = a2_v * a2_v * r2 * m2 * cos(a1 - a2)
            den = r2 * (2 * m1 + m2 - m2 * cos(2 * a1 - 2 * a2))
            self.acc = (num1 * (num2 + num3 + num4)) / den

        if self._angle >= pi2:
            self._angle -= floor(self._angle / pi2) * pi2
        elif self._angle <= -pi2:
            self._angle += abs(floor(self._angle / pi2)) * pi2
        self.velocity += self.acc*delta
        self._angle += self.velocity
        self.velocity *= self.damping
        if self.child:
            self.child.start = self.end_point

    def draw(self, canvas: ImageDraw.ImageDraw):
        canvas.line((self.start.tuple, self.end_point.tuple), 'black')
        x, y = self.end_point.tuple
        canvas.ellipse((x - 5, y - 5, x + 5, y + 5), 'black')
        if self.child:
            self.child.draw(canvas)

    @property
    def end_point(self):
        x = self.start.x + self.length * sin(self._angle)
        y = self.start.y + self.length * cos(self._angle)
        return Point(x, y)

    @property
    def last(self):
        if self.child:
            return self.child.last
        else:
            return self

    def append(self, other: 'Pendulum'):
        self.child = other
        other.start = self.end_point
        other.parent = self

prev_point = None

def draw(fps):
    global prev_point
    if prev_point:
        canvas_lines.line((a.last.end_point.tuple, prev_point.tuple), fill='black', width=0)
    a.draw(canvas)
    viewer.root.wm_title('FPS: {:.2f}\r'.format(fps))
    canvas.multiline_text((20, 20), "A1:{}\nA2:{}".format(a, a2), fill='black')
    viewer.update()
    canvas.rectangle(((0, 0), im.size), 'white')
    prev_point = a.last.end_point

if __name__ == '__main__':
    frame_time = 1 / 60
    im = Image.new('RGB', (800, 800), (255, 255, 255))
    lines = Image.new('RGB', (800, 800), (255, 255, 255))
    viewer = Viewer.Viewer([im, lines])
    # viewer = Viewer.Viewer([im])
    viewer.start()
    viewer.wait_for_load()
    canvas = ImageDraw.ImageDraw(im)
    canvas_lines = ImageDraw.ImageDraw(lines)
    # a = Pendulum(angle=0, length=100, mass=10, damping=0.999)
    a = Pendulum(angle=degrees(pi / 2), length=100, mass=40, damping=1)
    a.start = Point(im.size[0] // 2, im.size[1] // 2)
    # a2 = Pendulum(angle=0, length=100, mass=10, damping=0.999)
    a2 = Pendulum(angle=degrees(pi / 2), length=100, mass=40, damping=1)
    # a3 = Pendulum(angle=degrees(pi / 2), length=100, mass=40, damping=1)
    # a4 = Pendulum(angle=degrees(pi / 4), length=50, mass=10, damping=0.999)
    a.append(a2)
    # a2.append(a3)
    # a3.append(a4)
    t = time()
    t_delta = 0
    while 1:
        if t_delta <= 0:
            t_delta = frame_time
        a.update(t_delta)
        draw(1 / t_delta)
        t_delta = time() - t

        t = time()


# coding: utf-8

from __future__ import absolute_import
from datetime import date, datetime  # noqa: F401

from typing import List, Dict  # noqa: F401

from swagger_server.models.base_model_ import Model
from swagger_server.models.equipment import Equipment
from swagger_server.models.source import Source
from swagger_server.models.workout import Workout
from swagger_server import util

class Everything(Model):
    """NOTE: This class is auto generated by the swagger code generator program.

    Do not edit the class manually.
    """

    def __init__(self, sources: List[Source]=None, workouts: List[Workout]=None, tags: List[str]=None, exercises: List[str]=None, equipment: List[Equipment]=None):  # noqa: E501
        """Everything - a model defined in Swagger

        :param sources: The sources of this Everything.  # noqa: E501
        :type sources: List[Source]
        :param workouts: The workouts of this Everything.  # noqa: E501
        :type workouts: List[Workout]
        :param tags: The tags of this Everything.  # noqa: E501
        :type tags: List[str]
        :param exercises: The exercises of this Everything.  # noqa: E501
        :type exercises: List[str]
        :param equipment: The equipment of this Everything.  # noqa: E501
        :type equipment: List[Equipment]
        """
        self.swagger_types = {
            'sources': List[Source],
            'workouts': List[Workout],
            'tags': List[str],
            'exercises': List[str],
            'equipment': List[Equipment]
        }

        self.attribute_map = {
            'sources': 'sources',
            'workouts': 'workouts',
            'tags': 'tags',
            'exercises': 'exercises',
            'equipment': 'equipment'
        }

        self._sources = sources
        self._workouts = workouts
        self._tags = tags
        self._exercises = exercises
        self._equipment = equipment

    @classmethod
    def from_dict(cls, dikt) -> 'Everything':
        """Returns the dict as a model

        :param dikt: A dict.
        :type: dict
        :return: The Everything of this Everything.  # noqa: E501
        :rtype: Everything
        """
        return util.deserialize_model(dikt, cls)

    @property
    def sources(self) -> List[Source]:
        """Gets the sources of this Everything.

        :return: The sources of this Everything.
        :rtype: List[Source]
        """
        return self._sources

    @sources.setter
    def sources(self, sources: List[Source]):
        """Sets the sources of this Everything.

        :param sources: The sources of this Everything.
        :type sources: List[Source]
        """

        self._sources = sources

    @property
    def workouts(self) -> List[Workout]:
        """Gets the workouts of this Everything.

        :return: The workouts of this Everything.
        :rtype: List[Workout]
        """
        return self._workouts

    @workouts.setter
    def workouts(self, workouts: List[Workout]):
        """Sets the workouts of this Everything.

        :param workouts: The workouts of this Everything.
        :type workouts: List[Workout]
        """

        self._workouts = workouts

    @property
    def tags(self) -> List[str]:
        """Gets the tags of this Everything.

        :return: The tags of this Everything.
        :rtype: List[str]
        """
        return self._tags

    @tags.setter
    def tags(self, tags: List[str]):
        """Sets the tags of this Everything.

        :param tags: The tags of this Everything.
        :type tags: List[str]
        """

        self._tags = tags

    @property
    def exercises(self) -> List[str]:
        """Gets the exercises of this Everything.

        :return: The exercises of this Everything.
        :rtype: List[str]
        """
        return self._exercises

    @exercises.setter
    def exercises(self, exercises: List[str]):
        """Sets the exercises of this Everything.

        :param exercises: The exercises of this Everything.
        :type exercises: List[str]
        """

        self._exercises = exercises

    @property
    def equipment(self) -> List[Equipment]:
        """Gets the equipment of this Everything.

        :return: The equipment of this Everything.
        :rtype: List[Equipment]
        """
        return self._equipment

    @equipment.setter
    def equipment(self, equipment: List[Equipment]):
        """Sets the equipment of this Everything.

        :param equipment: The equipment of this Everything.
        :type equipment: List[Equipment]
        """

        self._equipment = equipment


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

import datetime
import numpy as np
import pandas as pd
import re
import warnings
import wordfreq

from lexicon_English import Words

warnings.filterwarnings("ignore", 'This pattern is interpreted as a regular expression, and has match groups.')

def print_time(message=None):
    now = datetime.datetime.now()
    time_str = now.strftime('%H:%M:%S')
    if message is None:
        print(time_str, end="\t")
    else:
        print(f"{time_str}\t{message}")

def sentences_to_df(sentences):
    sentences_txt = [" ".join(sentence) for sentence in sentences]
    df = pd.DataFrame({"sentence": sentences_txt})
    return df

def df_to_sentences(df):
    sentences_txt = df["sentence"]
    sentences = [sentence_txt.split(" ") for sentence_txt in sentences_txt]
    return sentences

def godown_dict_keys(d, ks):
    res = set()
    if len(ks) == 0:
        return d
    elif (type(d) is list):
        return d
    elif (type(d) is not dict):
        return res
    else:
        next_ds = [next_d for k, next_d in d.items() if re.search(ks[0], k)]
        for next_d in next_ds:
            res = res.union(godown_dict_keys(next_d, ks[1:]))
    return res

def reg_unigrams(w_list, border=r"\b"):
    return "|".join(rf"{border}{w}{border}" for w in w_list)

def reg_bigrams(w1_list, w2_list):
    return f"({reg_unigrams(w1_list)})" + r"\s" + f"({reg_unigrams(w2_list)})"

def remove_faulty_agreements(df):
    # Warning: adjency between noun and verb does not guarantee agreement
    # Here it is protected because we look at (noun, verb) pairs very early
    # Beware of RC, auxiliaries, etc.

    patterns_a = []

    pro_inanimate = ["it"]
    noun_inanimate = godown_dict_keys(Words, ['nouns_inanimate', '.*'])
    verb_animate = godown_dict_keys(Words, [r'\bverbs\b|\bverbs_intran_anim\b|\bmatrix_verbs\b', '.*', '.*'])
    pattern_animacy = "[A-Za-z]+\s" + reg_bigrams(noun_inanimate, verb_animate)
    pattern_it_animacy = reg_bigrams(pro_inanimate, verb_animate)

    patterns_a.append(pattern_it_animacy)
    patterns_a.append(pattern_animacy)

    pro_verb_s = ["he", "she", "it"]
    noun_sg_anim = godown_dict_keys(Words, [r'(\bnouns\b|\bnouns_inanimate\b)', '.*', 'singular'])
    noun_sg_inanim = godown_dict_keys(Words, [r'(\bnouns_inanimate\b)', 'singular'])
    noun_sg = noun_sg_anim.union(noun_sg_inanim)
    proper_names = godown_dict_keys(Words, [r'\bproper_names\b', '.*', '.*'])

    pro_verb_no_s = ["I", "you", "we", "they"]
    noun_pl = godown_dict_keys(Words, [r'\bnouns\b|\bnouns_inanimate\b', '.*', 'plural'])

    verb_sg = godown_dict_keys(Words, ['verbs', 'present', 'singular'])
    verb_pl = godown_dict_keys(Words, ['verbs', 'present', 'plural'])

    pattern_PN_sg = reg_bigrams(proper_names, verb_pl)
    pattern_noun_sg = "[A-Za-z]+\s" + reg_bigrams(noun_sg, verb_pl)
    pattern_pro_sg = reg_bigrams(pro_verb_s, verb_pl)
    pattern_pl = "[A-Za-z]+\s" + reg_bigrams(noun_pl, verb_sg)
    pattern_pro_pl = reg_bigrams(pro_verb_no_s, verb_sg)

    patterns_a.append(pattern_PN_sg)
    patterns_a.append(pattern_noun_sg)
    patterns_a.append(pattern_pro_sg)
    patterns_a.append(pattern_pl)
    patterns_a.append(pattern_pro_pl)

    patterns = []
    for pattern in patterns_a:
        patterns.append(f"^{pattern}")
        patterns.append(f"(that|whether)\s{pattern}")
    patterns.append("which\s.*" + reg_bigrams(noun_sg, verb_pl))
    patterns.append("which\s" + reg_bigrams(noun_pl, verb_sg))
    patterns.append("which\s.*" + reg_bigrams(noun_inanimate, verb_animate))
    patterns.append(reg_bigrams(["who"], verb_pl))

    quant_sg = ["every", "no"]
    quant_pl = ["all", "few"]
    pattern_q_sg = reg_bigrams(quant_sg, noun_pl)
    pattern_q_pl = reg_bigrams(quant_pl, noun_sg)
    patterns.append(f"{pattern_q_sg}")
    patterns.append(f"{pattern_q_pl}")

    patterns.sort(key=len)

    for pattern in patterns:
        mask = df["sentence"].str.contains(pattern)
        df = df[~mask]

    return df

def extract_verb(POS, anim_feature, Wkey):
    if (POS == "embedverb_Matrix"):
        return ""
    W = Words[Wkey]
    res = ""
    res = f"""
{POS}[finite=true, TENSE=pres, NUM=sg, PERS=1{anim_feature}] -> '{"'|'".join(W['present']['plural'])}'
{POS}[finite=true, TENSE=pres, NUM=sg, PERS=2{anim_feature}] -> '{"'|'".join(W['present']['plural'])}'
{POS}[finite=true, TENSE=pres, NUM=sg, PERS=3{anim_feature}] -> '{"'|'".join(W['present']['singular'])}'
{POS}[finite=true, TENSE=pres, NUM=pl{anim_feature}] -> '{"'|'".join(W['present']['plural'])}'
"""
#block future for now:
#{POS}[finite=true, TENSE=future{anim_feature}] -> '{"'|'".join(W['future'])}'"""
    if "-finite" in W.keys():
        res += f"""
{POS}[finite=false{anim_feature}] -> '{"'|'".join(W['-finite'])}'\n"""
        res += "\n"
    if "past" in W.keys():
        res += f"""
{POS}[finite=true, TENSE=past{anim_feature}] -> '{"'|'".join(W['past'])}'\n"""
        res += "\n"
    return res

def fix_poss_anim(df):
    df.loc[df.poss=='her', 'poss_ANIM'] = True
    df.loc[df.poss=='his', 'poss_ANIM'] = True
    return df

def add_features_to_dict(d, pos_tuple):
    word, pos = pos_tuple
    for i_item, (key, val) in enumerate(pos.items()):
        if i_item == 0: # Get subj/verb/object from *type* of pos
            svo = None
            if '_' in val:
                svo, svo_type = val.split('_')
                if svo_type != '':
                    d[f'{svo}_type'] = svo_type
                    d[f'{svo}'] = word
        else:  # Features of pos
            if svo is not None:
                feature_name = key
                d[f'{svo}_{feature_name}'] = val
    return d

def check_incongruence(f1, f2, role1=None, role2=None, poss_type=None):
    if pd.isnull(f1) or pd.isnull(f2):
        return np.nan
    elif role1=='poss' and poss_type!=role2:
        # Verify that the possessive is of the current role.
        # Since, poss-subj congruence means 'poss' is the possessive of the subject
        # And poss-obj congruence means the 'poss' is of the object.
        return np.nan
    else:
        return (f1 != f2)

def get_agreement_mismatch(row, role1, role2, agr_features=None):
    if agr_features is None:
        agr_features = ["GEN", "NUM", "PERS", "ANIM"]
    agreement_mismatch = {}
    if pd.isnull(row[f"{role1}_type"]) or pd.isnull(row[f"{role2}_type"]):
        # How do we mark that?
        # return np.nan?
        # agreement_match = {feature: np.nan for feature in agr_features}
        pass
    else:
        for feature in agr_features:
            agreement_mismatch[feature] = check_incongruence(
                row[f"{role1}_{feature}"],
                row[f"{role2}_{feature}"])
    agreement_mismatch["overall"] = any(
        agr_value for agr_value in agreement_mismatch.values()
        if agr_value is not np.nan
        )
    return agreement_mismatch

def order_columns(df, bring2front):
    # sort columns by name
    cols = sorted(list(df))

    # Move sentence to front column and save
    for name in bring2front:
        cols.insert(0, cols.pop(cols.index(name)))
        df = df.loc[:, cols]
    return df

def remove_repeated_sentences(df):
    df = df.drop_duplicates(subset=['sentence'])
    return df

def remove_sentences_with_repeated_lemma(df):
    # Remove sentences where a lemma is repeated
    # verbs are not included if one verb is trans and the other is intrans
    SINGLE_STRINGS = godown_dict_keys(Words, ['proper_names', 'singular', '.*'])
    SINGLE_STRINGS = [rf"\b{w}\b" for w in SINGLE_STRINGS]
    SINGLE_PAIRS = ([
            Words['nouns']['masculine'][NUM] +
            Words['nouns']['feminine'][NUM] +
            Words['nouns_inanimate'][NUM]
            for NUM in ['singular', 'plural']])
    SINGLE_PAIRS = [
        rf"\b{n_sg}\b|\b{n_pl}\b"
        for (n_sg, n_pl) in zip(*SINGLE_PAIRS)]
    REG_EX = SINGLE_STRINGS + SINGLE_PAIRS
    for E in REG_EX:
        doubleE = f"({E}).*({E})"
        mask = (df['sentence'].str.contains(doubleE))
        df = df[~mask]
    df = df.reset_index(drop=True)
    return df

def remove_impossible_binding(df):
    # remove "He saw him", "I saw me", etc.
    binding_problems = (
        (df["subj_type"] == "PRO") &
        (df["obj_type"] == "PRO") &
        (~(df["obj_REFL"] == True)) &
        (df["incongruence_subj_obj_count"]==0)
    )
    for test_exclude in ["I saw me", "She saw her"]:
        assert (test_exclude in df[binding_problems]["sentence"]) or ( not (test_exclude in df["sentence"]) )
    for test_include in ["I saw myself", "She saw herself"]:
        assert not (test_include in df[binding_problems]["sentence"])
    df = df[~binding_problems]
    df = df.reset_index(drop=True)
    return df

def calc_incongruence_counts(df):
    df = calc_incongruence_count(df, "subj", "obj")
    df = calc_incongruence_count(df, "poss", "subj")
    df = calc_incongruence_count(df, "poss", "obj")
    df = calc_incongruence_count(df, "subj", "embedsubj")
    return df

def calc_incongruence_count(df, role1, role2, features=None):
    if features is None:
        features = ['NUM', 'GEN', 'PERS', 'ANIM']
    df = calc_incongruence_feature(df, role1, role2)
    cols = [f"incongruent_{role1}_{role2}_{feat}" for feat in features]
    cols = [c for c in cols if c in df.columns]
    df[f"incongruence_{role1}_{role2}_count"] = df[cols].sum(axis=1, min_count=1)
    return df

def calc_incongruence_feature(df, role1, role2):
    for feat in ['NUM', 'GEN', 'PERS', 'ANIM']:
        if f'{role1}_{feat}' in df.columns and f'{role2}_{feat}' in df.columns:
            df[f'incongruent_{role1}_{role2}_{feat}'] = df.apply(lambda row:
                                                    check_incongruence(row[f'{role1}_{feat}'],
                                                                     row[f'{role2}_{feat}'],
                                                                     role1, role2,
                                                                     row['poss_type']),
                                                    axis=1)
    return df

def add_sentence_length(df):
    df['sentence_length'] = df.apply(lambda row:
                                     len(row['sentence'].split()),
                                     axis=1)
    return df

def add_has_property(df, groups=['subjrel', 'objrel', 'embed', 'main']):
    for group in groups:
        df[f'has_{group}'] = df.apply(lambda row:
                                      row['sentence_GROUP'].startswith(f'{group}'),
                                      axis=1)

    df['has_relative_clause'] = df.apply(lambda row:
                                         (row['has_subjrel'] or row['has_objrel']),
                                         axis=1)
    return df

def sanity_checks(sentence, tree):
    for fragment_test in [
        "dog see ",  # not a perfect test: "The boy that saw the dogs see the man"
        "dogs falls"  # not a perfect test: "The boy that saw the dogs falls"
    ]:
        if fragment_test in sentence:
            print("WARNING")
            print(sentence)
            print(tree)
        return

def compute_mean_zipf(row, words=['subj', 'embedsubj', 'verb', 'embedverb'],
                      lang='en'):
    zipfs = []
    for word in words:
        if not pd.isnull(row[word]):
            zipfs.append(wordfreq.zipf_frequency(row[word],
                                                 lang=lang))
    return np.floor(np.mean(zipfs))

def add_word_zipf(df):
    df['mean_zipf'] = df.apply(lambda row: compute_mean_zipf(row), axis=1)
    return df

def get_clause_type(row):
    if row['sentence_GROUP'].startswith(('main_', 'embed_')):
        # remove prefix (embed_/main_) and suffix (_clause) from sentence_GROUP
        return row['sentence_GROUP'].split('_')[1]
    else:
        return np.nan

def add_clause_type(df):
    df['clause_type'] = df.apply(lambda row: get_clause_type(row), axis=1)
    return df

def get_aux_tense(row):
    if row['sentence_GROUP'].startswith("main_obj"):
        return row['do_TENSE']
    else:
        return row['verb_TENSE']

def modify_tense_of_obj_quest(df):
    df['verb_TENSE'] = df.apply(lambda row: get_aux_tense(row), axis=1)
    return df

def check_lr_attractor(row):
    if row['sentence_GROUP'] in ['pp', 'objrel']:
        return check_incongruence(row['subj_NUM'], row['embedsubj_NUM'])
    elif row['sentence_GROUP'] == 'subjrel':
        return check_incongruence(row['subj_NUM'], row['embedobj_NUM'])
    else:
        return np.nan

def lr_agreement_with_attractor(df):
    df['long_range_agreement_with_attractor'] = df.apply(lambda row: check_lr_attractor(row),
                                                         axis=1)
    return df

def calc_simple_binding(row):
    bound_variable = np.nan
    coref_variable = np.nan
    if pd.isnull(row['quantifier']):
        if (row['subj_type'] == "PRO"):
            coref_variable = (row["obj_REFL"] == True)
        elif (row['poss_type'] == "subj"):
            agreement_mismatch = get_agreement_mismatch(row, "poss", "obj")
            coref_variable = not agreement_mismatch["overall"]
        elif (row['obj_type'] == "PRO"):
            coref_variable = (row["obj_REFL"] == True)
        elif (row['poss_type'] == "obj"):
            agreement_mismatch = get_agreement_mismatch(row, "poss", "subj")
            coref_variable = not agreement_mismatch["overall"]
    elif not (pd.isnull(row['quantifier'])):
        if (row['obj_type'] == "PRO"):
            bound_variable = (row["obj_REFL"] == True)
        elif (row['poss_type'] == "obj"):
            agreement_mismatch = get_agreement_mismatch(row, "poss", "subj")
            bound_variable = not agreement_mismatch["overall"]
    return {
        'bound_variable': bound_variable,
        'coref_variable': coref_variable}

def add_binding(df):
    binding_cols = df.apply(calc_simple_binding, axis=1, result_type="expand")
    df = pd.concat([df, binding_cols], axis=1)
    return df


import streamlit as st
import pandas as pd
import datetime

import altair as alt
from iexfinance.stocks import get_historical_data

import json
token = json.load(open("iexfinance_token.json")).get("token")

tech_list = ['AAPL', 'MSFT', 'AMZN', 'GOOG', 'FB', 'BABA', 'TSLA', 'NVDA', 'PYPL', 'INTC',
             'CRM', 'AMD', 'ATVI', 'MTCH', 'EA', 'TTD', 'ZG', 'YELP']

tday = datetime.date.today()
start = tday - datetime.timedelta(days=30)

@st.cache
def load_data(ticker):
    df = get_historical_data(ticker, start, tday, output_format='pandas', token=token)
    df['date'] = df.index
    return df

st.write("""
# Big Tech Stock Price App

""")

ticker = st.selectbox('Company: ', tech_list)

if ticker:

    source = pd.DataFrame({
        'date': load_data(ticker)['date'],
        f'{ticker} value': load_data(ticker)['fClose']
    })

    c = alt.Chart(source).mark_line().encode(x='date', y=alt.Y(f'{ticker} value', scale=alt.Scale(zero=False)))
    st.altair_chart(c, use_container_width=True)

if st.button('Show more'):
    st.write(load_data(ticker))


from flask import Flask
from flask_sock import Sock

app = Flask(__name__)
sock = Sock(app)

@sock.route('/')
def reverse(ws):
    ws.send("DYLAN")
    while True:
        text = ws.receive()
        ws.send(text[::-1])
        #ws.send("HELLO WORLD")

if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=80)


from selenium.webdriver.common.by import By

from task3.framework.base_form import BaseForm
from task3.framework.elements.basic_element import BasicElement
from task3.framework.elements.slider import Slider
from task3.framework.utils.logger_utils import LoggerUtils

class SliderPage(BaseForm):
    __unique_element = BasicElement(
        (By.XPATH, "//div[@id='sliderContainer']"), "unique element on slider page"
    )
    __slider_input = BasicElement(
        (By.XPATH, "//input[@id='sliderValue']"), "input box with slider value"
    )
    __slider = Slider((By.XPATH, "//input[@type='range']"), "slider")

    def __init__(self):
        super().__init__(
            self.__unique_element,
            "page with a slider",
        )

    def set_slider_value_to(self, desired_value):
        self.__slider.click()
        current_value = self.get_slider_value()
        LoggerUtils.log_info(
            f"{self.page_name} - changing slider value from {current_value} to {desired_value}"
        )
        difference = desired_value - current_value
        if difference > 0:
            self.__slider.increase_value_by(difference)
        else:
            self.__slider.decrease_value_by(difference)

    def get_slider_value(self):
        slider_text = self.__slider_input.get_attribute("value")
        return int(slider_text)


from bs4 import BeautifulSoup
import datetime
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import traceback
import re

## Dirty hack for imports.
import sys
import os
sys.path.append(os.path.abspath('../app'))
from config import db, MLB

driver_path = '/usr/local/bin/chromedriver'
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.binary_location = '/Applications/Brave Browser.app/Contents/MacOS/Brave Browser'
driver = webdriver.Chrome(options=chrome_options, executable_path=driver_path)

date_regex = r"\w{3,9}?\s\d{1,2}, \d{4}?"

def get_mlb():
    base_url = "https://www.espn.com/mlb/scoreboard/_/date/"
    # seasons = ["2010", "2011", "2012", "2013", "2014", "2015",
    #            "2016", "2017", "2018", "2019", "2020"]
    seasons = ["2020", "2021"]
    days = ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11",
            "12", "13,", "14", "15", "16", "17", "18", "19", "20", "21", "22",
            "23", "24", "25", "26", "27", "28", "29", "30", "31", ]
    months = ["01", "02", "03", "04", "05",
              "06", "07", "08", "09", "10", "11", "12"]
    urls = []
    dates = []
    for season in seasons:
        for month in months:
            for day in days:
                urls.append(f"{base_url}{season}{month}{day}")
                dates.append(f'{season}-{month}-{day}')

    for url, date in zip(urls, dates):
        print(url)
        print(date)
        try:
            driver.get(url)
        except:
            driver.get(url)
            time.sleep(3)
        try:
            soup = BeautifulSoup(driver.page_source, 'html.parser')
            events = soup.find(id='scoreboard-page')
            evs = events.find(id='events')
            # date_container = soup.find(
            #     "div", attrs={"class": "carousel-day"})
            # date = date_container.find("span")
            # datereg = re.findall(date_regex, date.text)
            # try:
            #     date_obj = datetime.datetime.strptime(
            #         datereg[0], "%B %d, %Y")
            #     date = date_obj.strftime('%Y-%m-%d')
            # except:
            #     date_obj = datetime.datetime.strptime(
            #         datereg[0], "%b %d, %Y")
            #     date = date_obj.strftime('%Y-%m-%d')

            away_win_games = evs.find_all(
                'article', attrs={"class": "scoreboard baseball final away-winner js-show"})
            home_win_games = evs.find_all(
                'article', attrs={"class": "scoreboard baseball final home-winner js-show"})
            print(len(away_win_games))
            print(len(home_win_games))
        except:
            traceback.print_exc()
            print(len(away_win_games))
        if (len(away_win_games) > 0):
            for game in away_win_games:
                try:
                    away_team = game.find('tr', attrs={'class': 'away'})
                    away_name = away_team.find(
                        'span', attrs={'class': 'sb-team-short'})
                    away_total = away_team.find('td', attrs={'class': 'total'})
                except:
                    traceback.print_exc()
                try:
                    home_team = game.find('tr', attrs={'class': 'home'})
                    home_name = home_team.find(
                        'span', attrs={'class': 'sb-team-short'})
                    home_total = home_team.find('td', attrs={'class': 'total'})
                except:
                    traceback.print_exc()
                print("Making entry")
                print({"date": date, "score": f"{away_total.text} - {home_total.text}",
                       "teams": f"{away_name.text} vs {home_name.text}"})
                Game = MLB(
                    date=date,
                    score=f"{home_total.text} - {away_total.text}",
                    teams=f"{home_name.text} vs {away_name.text}")

                exists = db.session.query(MLB.id).filter_by(
                    date=date, teams=f"{home_name.text} vs {away_name.text}").scalar() is not None
                if not exists:
                    print(
                        f"Making entry: {date}---{home_name.text} vs {away_name.text}")
                    db.session.add(Game)
                    db.session.commit()
        if (len(home_win_games) > 0):
            for game in home_win_games:
                try:
                    away_team = game.find('tr', attrs={'class': 'away'})
                    away_name = away_team.find(
                        'span', attrs={'class': 'sb-team-short'})
                    away_total = away_team.find('td', attrs={'class': 'total'})
                except:
                    traceback.print_exc()
                try:
                    home_team = game.find('tr', attrs={'class': 'home'})
                    home_name = home_team.find(
                        'span', attrs={'class': 'sb-team-short'})
                    home_total = home_team.find('td', attrs={'class': 'total'})
                except:
                    traceback.print_exc()
                Game = MLB(
                    date=date,
                    score=f"{home_total.text} - {away_total.text}",
                    teams=f"{home_name.text} vs {away_name.text}")

                exists = db.session.query(MLB.id).filter_by(
                    date=date, teams=f"{home_name.text} vs {away_name.text}").scalar() is not None
                if not exists:
                    print(
                        f"Making entry: {date}---{home_name.text} vs {away_name.text}")
                    db.session.add(Game)
                    db.session.commit()
                print("Making entry")
                print({"date": date, "score": f"{away_total.text} - {home_total.text}",
                       "teams": f"{away_name.text} vs {home_name.text}"})

if __name__ == "__main__":
    get_mlb()


"""
MpApi.Aio - Unofficial Asynchronous Open Source Client for MuseumPlus MpRIA

    from MpApi.aio.session import Session
    from MpApi.aio.client import Client
    from mpapi.module import Module

    c = Client(baseURL=baseURL)

    async with Session(user=user, pw=pw) as session:
        xml = await c.getDefinition(session, mtype="Object")
        m = await c.getDefinition2(session, mtype="Object")

        xml = await c.run_saved_query(session, mtype=mtype, ID=ID, xml=query_xml)
        m = await c.run_saved_query2(session, mtype=mtype, ID=ID, limit=l, offset=o)

        txt = await c.search(session, xml=xml)
        m = await c.search2(session,query)

SEE ALSO
    https://github.com/mokko/MpApi
    http://docs.zetcom.com/ws
"""

import asyncio
import aiohttp
from aiohttp import ClientSession
import logging
import sys
from lxml import etree  # type: ignore
from mpapi.search import Search
from mpapi.module import Module
from MpApi.aio.session import Session
from types import TracebackType
from typing import Any, Optional, Type, Union
from yarl import URL
from pathlib import Path

# ET: Any
ETparser = etree.XMLParser(remove_blank_text=True)

"""
aiohttp seems to accept baseURL only a host. Path parts after the host get ignored or overwritten
"""

DEBUG = True

class Counter:
    def __init__(self):
        self._count = 0

    async def __aenter__(self) -> None:  # params from init? ,
        self._count += 1
        if DEBUG:
            print(f"DEBUG-client: {self._count} connections")

    async def __aexit__(
        self,
        exc_type: Optional[Type[BaseException]],
        exc: Optional[BaseException],
        tb: Optional[TracebackType],
    ):
        self._count -= 1
        if DEBUG:
            print(f"DEBUG-client: {self._count} connections")

class Client:
    def __init__(self, *, baseURL: str) -> None:
        self.baseURL = baseURL
        self.appURL = URL(baseURL) / "ria-ws/application"
        self.count = Counter()

    async def get_definition(self, session: ClientSession, *, mtype: str = None) -> str:
        if mtype is None:
            url = self.appURL / "module/definition"
        else:
            url = self.appURL / f"module/{mtype}/definition"

        async with self.count:
            response = await session.get(url)
            # Seemingly, I have to use await here otherwise I get errors.
            # I dont understand why I cant return a coro here and await it later.
            # Perhaps, because the session is closed then.
            txt = await response.text()
        return txt

    async def get_definition2(
        self, session: ClientSession, *, mtype: str = None
    ) -> Module:
        txt = await self.get_definition(session, mtype=mtype)
        return Module(xml=txt)

    async def run_saved_query(
        self, session: ClientSession, *, ID: int, mtype: str, xml: str
    ) -> str:
        """
        Run a pre-existing saved search
        POST http://.../ria-ws/application/module/{module}/search/savedQuery/{__id}

        Zetcom reminds us: A request body must be provided, in order to control the paging.
        For example:

        <application
            xmlns="http://www.zetcom.com/ria/ws/module/search"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.zetcom.com/ria/ws/module/search http://www.zetcom.com/ria/ws/module/search/search_1_4.xsd">
            <modules>
              <module name="Object">
                <search limit="10" offset="0" />
              </module>
            </modules>
        </application>
        """
        url = self.appURL / f"module/{mtype}/search/savedQuery/{ID}"

        async with self.count:
            response = await session.post(url, data=xml)
            txt = await response.text()
        return txt

    async def run_saved_query2(
        self,
        session: ClientSession,
        *,
        ID: int,
        mtype: str,
        limit: int = -1,
        offset: int = 0,
    ) -> Module:
        """
        Like run_saved_query just with
        - limit and offset as parameters
        - query validation
        - returns results in Module
        """

        xml = f"""
                <application
                    xmlns="http://www.zetcom.com/ria/ws/module/search"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://www.zetcom.com/ria/ws/module/search
                    http://www.zetcom.com/ria/ws/module/search/search_1_6.xsd">
                    <modules>
                      <module name="{mtype}">
                        <search limit="{limit}" offset="{offset}" />
                      </module>
                    </modules>
                </application>
            """
        q = Search(fromString=xml)
        q.validate(mode="search")
        txt = await self.run_saved_query(session, ID=ID, mtype=mtype, xml=xml)
        return Module(xml=txt)

    async def search(self, session: ClientSession, *, xml: str) -> str:
        ET = etree.fromstring(bytes(xml, "UTF-8"))
        mtype = ET.xpath(
            "/s:application/s:modules/s:module/@name",
            namespaces={"s": "http://www.zetcom.com/ria/ws/module/search"},
        )[0]
        if not mtype:
            raise TypeError("Unknown module")

        url = self.appURL / f"module/{mtype}/search"

        # print(f"{mtype=} {url=}")

        async with self.count:
            response = await session.post(url, data=xml)
            txt = await response.text()
            # print(f"{response.request_info=}")
        return txt

    async def search2(self, session: ClientSession, *, query: Search) -> Module:
        query.validate(mode="search")
        txt = await self.search(session, xml=query.toString())
        return Module(xml=txt)  # txt.encode()

if __name__ == "__main__":
    pass


from typing import List

import altair as alt
import cv2
import larq_zoo as lz
import numpy as np
import pandas as pd
import streamlit as st
import tensorflow as tf

def load_network(network_name: str) -> tf.keras.models.Model:
    net_class = getattr(lz.sota, network_name, None)
    if net_class is None:
        net_class = getattr(lz.literature, network_name, None)
    return net_class()

def resize_image(image: np.ndarray, desired_shape: tuple) -> np.ndarray:
    input_h, input_w = image.shape[:2]
    target_h, target_w = desired_shape[1:3]
    if not (input_h == target_h and input_w == target_w):
        image = image.astype(np.float32) / 255.0
        if input_h / input_w >= target_h / target_w:
            # If we're here then the current aspect ratio is 'too tall', so
            # we resize to perfectly fit the width.
            #     We can do this by setting `preserve_aspect_ratio=True`,
            # and using the correct target width with a huge target height
            # (since when preserving the aspect ratio the target dimensions
            # are maxima).
            resized_image = tf.image.resize(
                image,
                (int(1e6 * target_w), target_w),
                preserve_aspect_ratio=True,
            )
        else:
            # Or otherwise, resize to perfectly fit the height.
            resized_image = tf.image.resize(
                image,
                (target_h, int(1e6 * target_h)),
                preserve_aspect_ratio=True,
            )

        # Then crop to the target size (there will be no padding).
        image = (
            255
            * tf.image.resize_with_crop_or_pad(
                resized_image, target_h, target_w
            ).numpy()
        )

        image = image.astype(np.uint8)

    return image[np.newaxis, ...]

def decoded_prediction_plot(decoded_predictions: List[List[list]]) -> alt.BoxPlot:
    decoded_predictions = decoded_predictions[0]
    class_names = [p[1] for p in decoded_predictions]
    confidences = [float(p[2]) for p in decoded_predictions]
    return (
        alt.Chart(pd.DataFrame({"class": class_names, "confidence": confidences}))
        .mark_bar()
        .encode(x="confidence", y=alt.Y("class:N", sort="-x"))
    )

def main():
    st.title("Larq zoo models")

    modules = ["sota", "literature"]
    with st.sidebar:
        filters = st.multiselect("category", options=modules, default=modules)
    networks = []
    for filter in filters:
        networks.extend(getattr(lz, filter).__all__)

    chosen_network = st.selectbox("Choose network", options=["choose one"] + networks)

    if chosen_network != "choose one":
        st.write(chosen_network)
        if (
            "loaded_network" not in st.session_state
            or st.session_state.loaded_network_name != chosen_network
        ):
            with st.spinner(f"loading {chosen_network}"):
                st.session_state.loaded_network = load_network(chosen_network)
                st.session_state.loaded_network_name = chosen_network

        if chosen_network != "choose one":
            net = st.session_state.loaded_network
            uploaded_file = st.file_uploader("Choose an image")
            if uploaded_file is not None:
                image = cv2.imdecode(
                    np.frombuffer(uploaded_file.getvalue(), np.uint8), -1
                )
                if image.shape[-1] == 3:
                    # bgr to rgb
                    image = image[..., ::-1].copy()
                elif image.shape[-1] == 4:
                    image = image[..., :-1][..., ::-1].copy()

                image_resized = resize_image(image, net.input.shape)
                st.image(image_resized)

                prediction = net(-1 + image_resized / 127.5).numpy()
                decoded_predictions = lz.decode_predictions(prediction, top=1000)
                st.altair_chart(
                    decoded_prediction_plot(decoded_predictions),
                    use_container_width=True,
                )

if __name__ == "__main__":
    main()


"""
    @author:gauthierLi
    @data:03/27/2022
    @func:test only
"""
import json
import os
import cv2
import csv
import torch
import numpy as np
from PIL import Image
import pycocotools.coco as coco

from model.model import kernel_extract_network
import torch.nn.functional as F
from data_loader.data_loaders import MnistDataLoader
from data_loader.coco import coco_dataloader
from data_loader.pretrain_coco import pretrain_coco_dataloader
from data_loader.branch_data import *
from utils.centerNetGT import centerNetGT

from model.model import kernel_extract_network, kernel_generator, classify_decoder
from torchvision.models import convnext_base

def _get_format_bbox(label_info):
    bbox_lst = []
    for item in label_info:
        category_id = item['category_id']
        box = item["bbox"]
        format_box = [(box[0] + box[2] / 2, box[1] + box[3] / 2, box[2] / 2, box[3] / 2), category_id]
        bbox_lst.append(format_box)
    return bbox_lst

def draw_bbox(img, bboxAndlabel):
    for boxandlabel in bboxAndlabel:
        print(boxandlabel)
        box = boxandlabel[:-1]
        text_info = str(boxandlabel[-1])
        text_len = len(text_info)
        x1, y1, x2, y2 = [int(box[0] - box[2]), int(box[1] - box[3]), int(box[0] + box[2]), int(box[1] + box[3])]
        img = cv2.rectangle(img, (x1, y1),
                            (x2, y2), (255, 0, 0), 2)
        img = cv2.rectangle(img, (int(box[0] - box[2]), int(box[1] - box[3]) - 16),
                            (int(box[0] - box[2]) + text_len * 11, int(box[1] - box[3])), (250, 250, 20), -1)
        img = cv2.putText(img, text_info, (int(box[0] - box[2]), int(box[1] - box[3]) - 5), cv2.FONT_HERSHEY_COMPLEX,
                          0.5, (0, 0, 0))
        cv2.imshow("img", img)
        cv2.waitKey(0)

def tst_dataLoader():
    device = torch.device("cuda")
    dataLoader = coco_dataloader(
        f"/home/gauthierli-org/data/data/fewshot", batch_size=2,
        training=True)
    for img, bboxAndlabel, gt in dataLoader:
        print("img shape", img.size())
        print("bbox shape", bboxAndlabel.shape)
        print("gt shape", gt.size(), type(gt))
        # img = img.squeeze().numpy().astype(np.uint8).transpose((1, 2, 0))[:, :, ::-1]
        # img = np.ascontiguousarray(img)
        # # cv2.imshow("img", img)
        # # cv2.waitKey()
        # label = int(bboxAndlabel[0][0][-1])
        # center = gt.numpy()[label - 1]
        # w = gt.numpy()[-4]
        # print("org", bboxAndlabel)
        # # back = centerNetGT.parse_to_standard(0, gt)
        # # print("back", back)
        # cv2.imshow("center", center)
        # cv2.imshow("w", w)
        # draw_bbox(img, bboxAndlabel[0])
        # # draw_bbox(img, back)

def tst_MNist_dataLoader():
    data_loader = MnistDataLoader("data/", 2)
    for data, label in data_loader:
        print(data)
        print(label)
        break

def tst_backbone():
    device = torch.device("cuda")
    a = torch.ones([2, 3, 243, 243]).to(device)
    tst_kernel_extract = kernel_extract_network()
    tst_kernel_extract.to(device)
    print(tst_kernel_extract(a).size())
    lst = tst_kernel_extract(a)[0].cpu().data.numpy()
    print("total class {}, after softmax is {}".format(len(lst), lst.sum()))

    cg_encoder = kernel_generator(inchannel=3, stride=1, pad=1)
    cg_encoder.to(device)
    cg_encoder.eval()
    print(cg_encoder(a).size())

def tst_PIL():
    img_path = r"/home/gauthierli-org/data/data/coco/val2017/000000000776.jpg"
    img = Image.open(img_path)
    print(img.size)

def tst_csv_reader():
    path = r"/home/gauthierli-org/data/data/vehicle-logos-dataset/structure.csv"
    csv_file = open(path, "r")
    data_list_dict = list(csv.DictReader(csv_file))
    KV_map = {}
    parse_map = {}
    v = 0
    for ele in data_list_dict:
        if ele["Template Name"] not in KV_map.keys():
            KV_map[ele["Template Name"]] = v
            parse_map[v] = ele["Template Name"]
            v += 1

    print(KV_map)
    print("\n")
    print(parse_map)

def tst_branch_dataloader():
    device = torch.device("cuda")
    root = r"/home/gauthierli-org/data/data/vehicle-logos-dataset/"
    train_loader = branch_data_loader(root, 2, True, 0.2)
    val_loader = train_loader.split_validation()
    tst_kernel_extract = kernel_extract_network()
    tst_kernel_extract.to(device)
    for img, label in val_loader:
        print(img.size())
        print(label.size(), inverse_dict[label.data.numpy().argmax()])
        result = tst_kernel_extract(img.to(device))
        print(F.cross_entropy(result, label.to(device)))

def tst_torch_tensor():
    ten1 = torch.tensor([[9, 8, 7]])
    ten2 = torch.tensor([[7, 5, 2]])
    print(ten1 == ten2)

def tst_cocotools():
    annos_path = r"/home/gauthierli-org/data/data/fewshot/fewshotlogodetection_round1_{}_202204/{}/annotations/instances_{}2017.json".format(
        "train", "train", "train")
    data = coco.COCO(annotation_file=annos_path)
    coco_class = dict([(v["id"], v["name"]) for k, v in data.cats.items()])
    category_id = list(coco_class.keys())
    print(data.anns[56])
    print(list(data.anns.items())[56])

    category_slice_dict = {}
    for category_id in category_id:
        category_slice_dict[category_id] = []
        imgs = data.getImgIds(catIds=category_id)
        for img_id in imgs:
            annos = data.getAnnIds(imgIds=img_id)
            # print("annos: ", annos, "\n")
            label_info = data.loadAnns(annos)
            # print("label_info: ", label_info, "\n")
            img_info = data.loadImgs(img_id)
            # print("img_info ", img_info, "\n")
            for item in label_info:
                tmp_dict = {}
                tmp_dict['id'] = item['id']
                tmp_dict['file_name'] = img_info[0]["file_name"]
                tmp_dict['bbox'] = item['bbox']
                tmp_dict['category_id'] = category_id
                category_slice_dict[category_id].append(tmp_dict)

    file_handle = open(r"test_area/category_slice_dict.json", "w")
    json.dump(category_slice_dict, file_handle, indent=4)
    file_handle.close()

    # annos = data.getAnnIds(imgIds=ids[0])
    # label_info = data.loadAnns(annos)
    # img_Info = data.loadImgs(ids[0])
    # print(label_info, "\n \n", img_Info)

def resize_img(path, size=(243, 243)):
    img = cv2.imread(path)
    img = img.transpose((2, 0, 1)).astype(np.float32)
    img = torch.from_numpy(img).unsqueeze(dim=0)
    resize = torchvision.transforms.Resize((243, 243))
    img = resize(img)
    return img

def tst_pretrain_coco():
    root = r"/home/gauthierli-org/data/data/fewshot"
    loader = pretrain_coco_dataloader(root=root, batch_size=1)
    for img, label in loader:
        img = img.squeeze().numpy().astype(np.uint8).transpose((1, 2, 0))[:, :, ::-1]
        cv2.imshow(f"img {label}", img)
        print(label)
        cv2.waitKey()
        cv2.destroyWindow(f"img {label}")

if __name__ == "__main__":
    # tst_backbone()
    # tst_MNist_dataLoader()
    tst_dataLoader()
    # tst_PIL()
    # tst_csv_reader()
    # tst_branch_dataloader()
    # tst_torch_tensor()
    # tst_cocotools()
    # tst_pretrain_coco()


import logging

from opentelemetry import trace
from opentelemetry._logs import set_logger_provider
from opentelemetry.exporter.otlp.proto.grpc._log_exporter import (
    OTLPLogExporter,
)
from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import (
    BatchSpanProcessor,
    ConsoleSpanExporter,
)

trace.set_tracer_provider(TracerProvider())
trace.get_tracer_provider().add_span_processor(
    BatchSpanProcessor(ConsoleSpanExporter())
)

logger_provider = LoggerProvider(
    resource=Resource.create(
        {
            "service.name": "shoppingcart",
            "service.instance.id": "instance-12",
        }
    ),
)
set_logger_provider(logger_provider)

exporter = OTLPLogExporter(insecure=True)
logger_provider.add_log_record_processor(BatchLogRecordProcessor(exporter))
handler = LoggingHandler(level=logging.NOTSET, logger_provider=logger_provider)

# Attach OTLP handler to root logger
logging.getLogger().addHandler(handler)

# Log directly
logging.info("Jackdaws love my big sphinx of quartz.")

# Create different namespaced loggers
logger1 = logging.getLogger("myapp.area1")
logger2 = logging.getLogger("myapp.area2")

logger1.debug("Quick zephyrs blow, vexing daft Jim.")
logger1.info("How quickly daft jumping zebras vex.")
logger2.warning("Jail zesty vixen who grabbed pay from quack.")
logger2.error("The five boxing wizards jump quickly.")

# Trace context correlation
tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span("foo"):
    # Do something
    logger2.error("Hyderabad, we have a major problem.")

logger_provider.shutdown()


# from HeatmapGenerator import ModelType
from dataset import *
import pandas as pd
import torch
import torchvision.transforms as transforms
from torch.utils.data import Dataset, DataLoader
from itertools import cycle
import sklearn.metrics as sklm
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import accuracy_score, roc_curve, auc, roc_auc_score

def make_pred_multilabel(model, test_df, val_df, path_image, device):
    """
    Gives predictions for test fold and calculates AUCs using previously trained model
    Args:

        model: densenet-121 from torchvision previously fine tuned to training data
        test_df : dataframe csv file
        PATH_TO_IMAGES:
    Returns:
        pred_df: dataframe containing individual predictions and ground truth for each test image
        auc_df: dataframe containing aggregate AUCs by train/test tuples
    """

    BATCH_SIZE = 32
    workers = 8
    n_classes = 14

    normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])

    dataset_test = NIH(test_df, path_image=path_image, transform=transforms.Compose([
        transforms.Scale(256),
        transforms.CenterCrop(256),
        transforms.ToTensor(),
        normalize]))
    test_loader = DataLoader(dataset_test, BATCH_SIZE, shuffle=False,
                             num_workers=workers, pin_memory=True)

    dataset_val = NIH(val_df, path_image=path_image, transform=transforms.Compose([
        transforms.Scale(256),
        transforms.CenterCrop(256),
        transforms.ToTensor(),
        normalize]))
    val_loader = DataLoader(dataset_val, BATCH_SIZE, shuffle=True,
                            num_workers=workers, pin_memory=True)

    size = len(test_df)
    print("Test _df size :", size)
    size = len(val_df)
    print("val_df size :", size)

    # criterion = nn.BCELoss().to(device)
    model = model.to(device)
    # to find this thresold, first we get the precision and recall withoit this, from there we calculate f1 score, using f1score, we found this theresold which has best precsision and recall.  Then this threshold activation are used to calculate our binary output.

    PRED_LABEL = ['Atelectasis',
            'Cardiomegaly',
            'Effusion',
            'Infiltration',
            'Mass',
            'Nodule',
            'Pneumonia',
            'Pneumothorax',
            'Consolidation',
            'Edema',
            'Emphysema',
            'Fibrosis',
            'Pleural_Thickening',
            'Hernia']

    # for mode in ["Threshold"]:
    for mode in ["test"]:
        # create empty dfs
        pred_df = pd.DataFrame(columns=["path"])
        bi_pred_df = pd.DataFrame(columns=["path"])
        true_df = pd.DataFrame(columns=["path"])

        if mode == "Threshold":
            loader = val_loader
            Eval_df = pd.DataFrame(columns=["label", 'bestthr'])
            thrs = []

        if mode == "test":
            loader = test_loader
            TestEval_df = pd.DataFrame(columns=["label", 'auc', "auprc"])

            Eval = pd.read_csv("results/Threshold.csv")
            thrs = [Eval["bestthr"][Eval[Eval["label"] == "Atelectasis"].index[0]],
                    Eval["bestthr"][Eval[Eval["label"] == "Cardiomegaly"].index[0]],
                    Eval["bestthr"][Eval[Eval["label"] == "Effusion"].index[0]],
                    Eval["bestthr"][Eval[Eval["label"] == "Infiltration"].index[0]],
                    Eval["bestthr"][Eval[Eval["label"] == "Mass"].index[0]],
                    Eval["bestthr"][Eval[Eval["label"] == "Nodule"].index[0]],
                    Eval["bestthr"][Eval[Eval["label"] == "Pneumonia"].index[0]],
                    Eval["bestthr"][Eval[Eval["label"] == "Pneumothorax"].index[0]],
                    Eval["bestthr"][Eval[Eval["label"] == "Consolidation"].index[0]],
                    Eval["bestthr"][Eval[Eval["label"] == "Edema"].index[0]],
                    Eval["bestthr"][Eval[Eval["label"] == "Emphysema"].index[0]],
                    Eval["bestthr"][Eval[Eval["label"] == "Fibrosis"].index[0]],
                    Eval["bestthr"][Eval[Eval["label"] == "Pleural_Thickening"].index[0]],
                    Eval["bestthr"][Eval[Eval["label"] == "Hernia"].index[0]]]

        for i, data in enumerate(loader):
            inputs, labels, item = data

            inputs = inputs.to(device)
            labels = labels.to(device)

            true_labels = labels.cpu().data.numpy()

            batch_size = true_labels.shape

            model.eval()
            with torch.no_grad():
                outputs = model(inputs)
                probs = outputs.cpu().data.numpy()

            # get predictions and true values for each item in batch
            for j in range(0, batch_size[0]):
                thisrow = {}
                bi_thisrow = {}
                truerow = {}

                truerow["path"] = item[j]
                thisrow["path"] = item[j]
                if mode == "test":
                    bi_thisrow["path"] = item[j]
                    # iterate over each entry in prediction vector; each corresponds to
                    # individual label
                for k in range(len(PRED_LABEL)):
                    thisrow["prob_" + PRED_LABEL[k]] = probs[j, k]
                    truerow[PRED_LABEL[k]] = true_labels[j, k]

                    if mode == "test":
                       bi_thisrow["bi_" + PRED_LABEL[k]] = probs[j, k] >= thrs[k]

                pred_df = pred_df.append(thisrow, ignore_index=True)
                true_df = true_df.append(truerow, ignore_index=True)
                if mode == "test":
                    bi_pred_df = bi_pred_df.append(bi_thisrow, ignore_index=True)

            if (i % 200 == 0):
                print(str(i * BATCH_SIZE))

        for column in true_df:
            if column not in PRED_LABEL:
                continue
            actual = true_df[column]
            pred = pred_df["prob_" + column]

            thisrow = {}
            thisrow['label'] = column

            if mode == "test":
                bi_pred = bi_pred_df["bi_" + column]
                thisrow['auc'] = np.nan
                thisrow['auprc'] = np.nan
            else:
                thisrow['bestthr'] = np.nan

            try:
#                 n_booatraps = 1000
#                 rng_seed = int(size / 100)
#                 bootstrapped_scores = []

#                 rng = np.random.RandomState(rng_seed)
#                 for i in range(n_booatraps):
#                     indices = rng.random_integers(0, len(actual.as_matrix().astype(int)) - 1, len(pred.as_matrix()))
#                     if len(np.unique(actual.as_matrix().astype(int)[indices])) < 2:
#                         continue

#                     score = sklm.roc_auc_score(
#                         actual.as_matrix().astype(int)[indices], pred.as_matrix()[indices])
#                     bootstrapped_scores.append(score)

#                 thisrow['auc'] = np.mean(bootstrapped_scores)

                if mode == "test":
                    fpr = dict()
                    tpr = dict()
                    roc_auc = dict()
                    for i in range(n_classes):
                        a = true_labels[:, i].astype(int)
                        b = probs[:, i]
                        fpr[i], tpr[i], _ = roc_curve(true_labels[:, i].astype(int), probs[:, i])
                        roc_auc[i] = auc(fpr[i], tpr[i])
                    thisrow['auc'] = roc_auc_score(actual.to_numpy().astype(int), pred.to_numpy())
                    thisrow['auprc'] = sklm.average_precision_score(actual.to_numpy().astype(int), pred.to_numpy())
                    # Compute micro-average ROC curve and ROC area
                    fpr["micro"], tpr["micro"], _ = roc_curve(true_labels[:, i], probs[:, i])
                    roc_auc["micro"] = auc(fpr["micro"], tpr["micro"])
                    # 绘制多分类问题的ROC曲线
                    # First aggregate all false positive rates
                    all_fpr = np.unique(np.concatenate([fpr[i] for i in range(n_classes)]))

                    # Then interpolate all ROC curves at this points
                    mean_tpr = np.zeros_like(all_fpr)
                    for i in range(n_classes):
                        mean_tpr += np.interp(all_fpr, fpr[i], tpr[i])

                    # Finally average it and compute AUC
                    mean_tpr /= n_classes

                    fpr["macro"] = all_fpr
                    tpr["macro"] = mean_tpr
                    roc_auc["macro"] = auc(fpr["macro"], tpr["macro"])

                    # Plot all ROC curves
                    plt.figure()
                    lw = 2
                    plt.plot(
                        fpr["micro"],
                        tpr["micro"],
                        label="micro-average ROC curve (area = {0:0.2f})".format(roc_auc["micro"]),
                        color="deeppink",
                        linestyle=":",
                        linewidth=4,
                    )

                    plt.plot(
                        fpr["macro"],
                        tpr["macro"],
                        label="macro-average ROC curve (area = {0:0.2f})".format(roc_auc["macro"]),
                        color="navy",
                        linestyle=":",
                        linewidth=4,
                    )

                    colors = cycle(["aqua", "darkorange", "cornflowerblue"])
                    for i, color in zip(range(n_classes), colors):
                        plt.plot(
                            fpr[i],
                            tpr[i],
                            color=color,
                            lw=lw,
                            label="ROC curve of class {0} (area = {1:0.2f})".format(i, roc_auc[i]),
                        )

                    plt.plot([0, 1], [0, 1], "k--", lw=lw)
                    plt.xlim([0.0, 1.0])
                    plt.ylim([0.0, 1.05])
                    plt.xlabel("False Positive Rate")
                    plt.ylabel("True Positive Rate")
                    plt.title("Some extension of Receiver operating characteristic to multiclass")
                    plt.legend(loc="lower right")
                    plt.savefig('results/mutilroc1.png')
                else:

                    p, r, t = sklm.precision_recall_curve(actual.as_matrix().astype(int), pred.as_matrix())
                    # Choose the best threshold based on the highest F1 measure
                    f1 = np.multiply(2, np.divide(np.multiply(p, r), np.add(r, p)))
                    bestthr = t[np.where(f1 == max(f1))]

                    thrs.append(bestthr)
                    thisrow['bestthr'] = bestthr[0]

            except BaseException:
                print("can't calculate auc for " + str(column))

            if mode == "Threshold":
                Eval_df = Eval_df.append(thisrow, ignore_index=True)

            if mode == "test":
                TestEval_df = TestEval_df.append(thisrow, ignore_index=True)

        pred_df.to_csv("results/preds.csv", index=False)
        true_df.to_csv("results/True.csv", index=False)

        if mode == "Threshold":
            Eval_df.to_csv("results/Threshold.csv", index=False)

        if mode == "test":
            TestEval_df.to_csv("results/TestEval.csv", index=False)
            bi_pred_df.to_csv("results/bipred.csv", index=False)

    print("AUC ave:", TestEval_df['auc'].sum() / 14.0)

    print("done")

    return pred_df, Eval_df, bi_pred_df, TestEval_df  # , bi_pred_df , Eval_bi_df

if __name__=="__main__":
    val_df = pd.read_csv(val_df_path)
    test_df = pd.read_csv(test_df_path)

    CheckPointData = torch.load('results/checkpoint')
    model = CheckPointData['model']

    make_pred_multilabel(model, test_df, val_df, path_image, device)


from keras.layers import Input, Dense, Conv1D, MaxPooling1D, UpSampling1D
from keras.models import Model

import numpy as np
import h5py

#data_file = '/home/cchen/MS2-Autoencoder/big_data_conv1d.hdf5'
data_file = 'big_data_conv1d.hdf5'
f = h5py.File(data_file, 'r')
dataset_low = f['low_peaks']
dataset_high = f['high_peaks']
print(dataset_low.shape)
print(dataset_high.shape)

def generator(X_data, y_data, batch_size):
    print('generator initiated')
    steps_per_epoch = X_data.shape[0]
    number_of_batches = steps_per_epoch // batch_size
    i = 0

    while True:
        X_batch = dataset_low[i*batch_size:(i+1)*batch_size]
        y_batch = dataset_high[i*batch_size:(i+1)*batch_size]
        i += 1
        yield X_batch, y_batch
        print('\ngenerator yielded a batch %s' %i)

        if i >= number_of_batches:
            i = 0

input_size = 2000
input_scan = Input(shape=(input_size, 1))
print(input_scan.shape)
hidden_1 = Conv1D(1, (5, ), activation='relu', padding='same')(input_scan)
print(hidden_1.shape)
hidden_2 = MaxPooling1D()(hidden_1)
hidden_3 = Conv1D(1, (5, ), activation='relu', padding='same')(hidden_2)
print(hidden_3.shape)
hidden_4 = MaxPooling1D()(hidden_3)
hidden_5 = Conv1D(1, (5, ), activation='relu', padding='same')(hidden_4)
print(hidden_5.shape)
encoded = MaxPooling1D((5, ))(hidden_5)
print(encoded.shape)

hidden_6 = Conv1D(1, (5, ), activation='relu', padding='same')(encoded)
print(hidden_6.shape)
hidden_7 = UpSampling1D(5)(hidden_6)
hidden_8 = Conv1D(1, (5, ), activation='relu', padding='same')(hidden_7)
print(hidden_7.shape)
hidden_9 = UpSampling1D()(hidden_8)
hidden_10 = Conv1D(1, (5, ), activation='relu', padding='same')(hidden_9)
print(hidden_10.shape)
hidden_11 = UpSampling1D()(hidden_10)
decoded = Conv1D(1, (5, ), activation='relu', padding='same')(hidden_11)
print(decoded.shape)

autoencoder = Model(input_scan, decoded)
autoencoder.compile(optimizer='adadelta', loss='cosine_proximity', metrics=['accuracy'])

batch_size = 5000
autoencoder.fit_generator(generator=generator(dataset_low, dataset_high, batch_size),
                          max_queue_size=20,
                          steps_per_epoch=dataset_low.shape[0] // batch_size,
                          epochs=1)

#save Model architecture to json
json_model = autoencoder.to_json()
#json_file = open('/home/cchen/MS2-Autoencoder/models/conv1d.json', 'w')
json_file = open('conv1d.json', 'w')
json_file.write(json_model)
#saving model architecture to yaml
yaml_model = autoencoder.to_yaml()
#yaml_file = open('/home/cchen/MS2-Autoencoder/models/conv1d.yaml', 'w')
yaml_file = open('conv1d.yaml', 'w')
yaml_file.write(yaml_model)

#save architeture and weights to hdf5
#autoencoder.save('/home/cchen/MS2-Autoencoder/models/conv1d_model.h5')
autoencoder.save('conv1d_model.h5')
'''
#loading model
from keras.models import load_model
model1 = load_model('/home/cchen/MS2-Autoencoder/models/conv1d_model.h5')
'''


import os
os.environ["CUDA_VISIBLE_DEVICES"]='6'

from pytorch_grad_cam import GradCAM
from pytorch_grad_cam.utils.model_targets import ClassifierOutputTarget
from pytorch_grad_cam.utils.image import show_cam_on_image
from model import Net
import torch
import pandas as pd
from dataset import ImageFolder
from torch.utils.data import DataLoader
import cv2
import numpy as np

import json

exp = "exp_33"

f = open(os.path.join('configs', "{}.json".format(exp)))
default_configs = json.load(f)

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = Net("convnext_base_in22ft1k", 1)
model.to(device)
pretrained_dict = torch.load("../weights/exp_33/0/checkpoint_acc_best_ema.pt")
# print(pretrained_dict.keys())
model.load_state_dict(pretrained_dict)
model.eval()

target_layers = [model.model.norm_pre]

# Construct the CAM object once, and then re-use it on many images:
cam = GradCAM(model=model, target_layers=target_layers, use_cuda=True)

# You can also use it within a with statement, to make sure it is freed,
# In case you need to re-create it inside an outer loop:
# with GradCAM(model=model, target_layers=target_layers, use_cuda=args.use_cuda) as cam:
#   ...

# We have to specify the target we want to generate
# the Class Activation Maps for.
# If targets is None, the highest scoring category
# will be used for every image in the batch.
# Here we use ClassifierOutputTarget, but you can define your own custom targets
# That are, for example, combinations of categories, or specific outputs in a non standard model.
targets = None
# targets = [ClassifierOutputTarget(1)]

# You can also pass aug_smooth=True and eigen_smooth=True, to apply smoothing.
val_df =  pd.read_csv("data/grad_cam.csv")
DATA_PATH = "grad_cam"
test_data = ImageFolder(val_df, DATA_PATH, default_configs, None, "submission")
test_loader = DataLoader(test_data, batch_size=32, shuffle=False, pin_memory=False, num_workers=8)
predictions = []
img_path_list = []
k = 0
for batch_idx, (imgs, labels, img_paths) in enumerate(test_loader):
    imgs = imgs.to(device).float()
    eval_imgs = imgs[:,0:3,:,:]
    grayscale_cam = cam(input_tensor=eval_imgs, targets=targets)
    for i in range(imgs.shape[0]):
        img_path = os.path.join(img_paths[i], "frame_0.png")
        file_name = os.path.basename(img_paths[i])
        grayscale_cam_new = grayscale_cam[i, :]
        ori_rgb_img = cv2.imread(img_path, 1)
        ori_shape = ori_rgb_img.shape
        rgb_img = ori_rgb_img[:, :, ::-1]
        rgb_img = cv2.resize(rgb_img, (default_configs["image_size"], default_configs["image_size"]))
        # ori_rgb_img = cv2.resize(ori_rgb_img, (224, 224))
        rgb_img = np.float32(rgb_img) / 255
        cam_image = show_cam_on_image(rgb_img, grayscale_cam_new)
        cam_image = cv2.resize(cam_image, (ori_shape[1], ori_shape[0]))
        # print(ori_rgb_img.shape, cam_image.shape)
        cam_image = cv2.hconcat([ori_rgb_img, cam_image])
        print(labels[i].item())
        img_path = os.path.join('results', str(labels[i].item()))
        os.makedirs(img_path, exist_ok=True)
        img_path = os.path.join(img_path, 'grad_cam_{}_{}.jpg'.format(labels[i].item(), file_name))
        cv2.imwrite(img_path, cam_image)
        k += 1


from flask import Flask, request, redirect, url_for, Blueprint, render_template, flash, jsonify
from db.clubes.clubes import Club, nuevo_club
from db import db

clubes = Blueprint('clubes', __name__)

@clubes.route('/club', methods=['GET', 'POST', 'PUT', 'DELETE'])
def club():
    clubes = Club.query.all()
    if request.method == 'GET':
        if request.args:
            nombre = request.args.get('nombre', type=str)
            club = Club.query.filter_by(nombre=nombre).first()
            print(club.__asdict__())
            response = jsonify({
            'club': club.__asdict__(),
            })
            response.headers.add('Access-Control-Allow-Origin', '*')
            return response
        print([c.__asdict__() for c in clubes])
        response = jsonify({
            'clubes': [c.__asdict__() for c in clubes]
            })
        response.headers.add('Access-Control-Allow-Origin', '*')
        return response

    if request.method == 'POST':
        print(request.get_json())
        id = request.json[-1]['id']
        nombre = request.json[-1]['nombre']
        asociacion = request.json[-1]['asociacion']
        nombrecorto = request.json[-1]['nombrecorto']
        abreviatura = request.json[-1]['abreviatura']
        escudo = request.json[-1]['escudo']

        id_existe = Club.query.filter_by(id=id).first()
        nombre_existe = Club.query.filter_by(nombre=nombre).first()
        abreviatura_existe = Club.query.filter_by(abreviatura=abreviatura).first()

        if id_existe:
            print('id ya existe')
            return'id ya existe'
        if nombre_existe:
            print('club ya existe')
            return'club ya existe'
        if abreviatura_existe:
            print('abreviatura ya existe')
            return'abreviatura ya existe'
        else:
            nuevo_club(id, nombre, asociacion, nombrecorto, abreviatura, escudo)
            print(f'club {id} {nombre} {asociacion} {nombrecorto} {abreviatura} creado')
            response = jsonify({
            'clubes': [c.__asdict__() for c in clubes]
            })
            response.headers.add('Access-Control-Allow-Origin', '*')
            return response

    if request.method == 'PUT':
        print('PUT')
        valores = request.get_json()
        id = valores['id']
        print(valores)
        club = Club.query.filter_by(id=id).first()
        print(club.nombre, club.abreviatura, club.asociacion, club.nombrecorto)
        club.nombre = valores['nombre']
        club.asociacion = valores['asociacion']
        club.nombrecorto = valores['nombrecorto']
        club.abreviatura = valores['abreviatura']
        db.session.commit()
        print('Club ', id, ' editado')
        clubes = Club.query.all()
        print([c.__asdict__() for c in clubes])
        response = jsonify({
            'clubes': [c.__asdict__() for c in clubes],
            })
        response.headers.add('Access-Control-Allow-Origin', '*')
        return response

    if request.method == 'DELETE':
        print('delete')
        id = request.get_json()
        print(id)
        club = Club.query.filter_by(id=id)
        club.delete()
        db.session.commit()
        print('Club ', id, ' eliminado')
        clubes = Club.query.all()
        print([c.__asdict__() for c in clubes])
        response = jsonify({
            'clubes': [c.__asdict__() for c in clubes],
            })
        response.headers.add('Access-Control-Allow-Origin', '*')
        return response
    response = jsonify({
            'clubes': [c.__asdict__() for c in clubes]
            })
    response.headers.add('Access-Control-Allow-Origin', '*')
    return response


from tkinter import *
from tkinter import ttk

from typing import List
from ContactsIO import ContactsIO
from components.Table import Table
from utils.user_data_helpers import convert_data_to_array
from utils.gui_helpers import center_window, get_widget_width

class UI:
    def __init__(self) -> None:
        # Initialize contactsIO instance to talk to the contacts repository
        self.__contacts_delegator = ContactsIO('contacts.json')

        self.__master = Tk()
        self.__master.title("Contact Tracing App")
        self.__master.columnconfigure(0, weight=1)
        self.__master.rowconfigure(0, weight=1)
        self.__master.minsize(250, 250)

        self.__frame = ttk.Frame(self.__master)
        self.__frame.grid(row=0, column=0, sticky="N W E S")
        self.__frame.grid_columnconfigure(0, weight=1)
        self.__frame.grid_rowconfigure(0, weight=1)

        self.__frame.configure(borderwidth=5, relief="sunken")

        self.__canvas = []
        self.__display_user_data()

        add_contact_button = ttk.Button(self.__frame, text="Add Contact", command=self.show_add_contact_form)
        add_contact_button.grid(row=self.__frame.grid_size()[1], column=0, columnspan=2, sticky="W E")

        search_contact_button = ttk.Button(self.__frame, text="Search Contact", command=self.show_search_contact_form)
        search_contact_button.grid(row=self.__frame.grid_size()[1], column=0, columnspan=2, sticky="W E")

        # Center the window
        center_window(self.__master)

        # Rerender canvas every time new user is created
        self.__master.bind("<<NewUserCreate>>", lambda event: self.__display_user_data())

        self.__master.mainloop()

    def __display_user_data(self):
        '''
        Draws the user data on the UI.

        Parameters
        ----------
        data : List[dict]
            A list of dictionaries containing user data.
        '''
        # Clear canvas first
        if self.__canvas:
            self.__canvas.destroy()

        self.__contacts = self.__contacts_delegator.get_user_data()

        canvas = Canvas(self.__frame)
        canvas.grid(row=0, column=0, sticky="N W E S")

        self.__canvas = canvas

        scrollbar = Scrollbar(self.__frame, orient="vertical", command=canvas.yview)
        scrollbar.grid(row=0, column=1, sticky="N S E")
        canvas.configure(yscrollcommand=scrollbar.set)

        self.__master.geometry("")

        table_frame = ttk.Frame(canvas)
        table_frame.configure(borderwidth=5, relief="sunken")
        canvas.create_window((0, 0), window=table_frame, anchor="nw", tags="table_frame")
        Table(table_frame, self.__contacts.copy())

        # Get the width of the table frame
        width = get_widget_width(table_frame)

        canvas.configure(width=width)
        canvas.configure(scrollregion=canvas.bbox("all"))

        center_window(self.__master)

    def show_add_contact_form(self):
        '''
        Create a new window for the contact tracing form.
        '''
        from components.ContactsForm import ContactsForm
        contacts_form = ContactsForm(self.__master, self.__contacts_delegator)

        # Center this window
        center_window(contacts_form.get_window())

    def show_search_contact_form(self):
        '''
        Creates a new window for the search contact form.
        '''
        from components.SearchContactsForm import SearchContactsForm

        search_contacts_form = SearchContactsForm(self.__master, self.__contacts_delegator)

         # Center this window
        center_window(search_contacts_form.get_window())


import pickle
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = "3"
from os.path import dirname, realpath
import sys
sys.path.append(dirname(dirname(dirname(realpath(__file__)))))

from sybil.parsing import parse_args
from scripts.plcom2012.plcom2012 import PLCOm2012
from sybil.utils.helpers import get_dataset
import sybil.utils.loading as loaders

def main(args):
    # Load dataset and add dataset specific information to args
    print("\nLoading data...")
    test_data = loaders.get_eval_dataset_loader(
            args,
            get_dataset(args.dataset, 'test', args),
            False
            )

    model = PLCOm2012(args)

    print("\nParameters:")
    for attr, value in sorted(args.__dict__.items()):
        if attr not in ['optimizer_state', 'patient_to_partition_dict', 'path_to_hidden_dict', 'exam_to_year_dict', 'exam_to_device_dict', 'treatment_to_index','drug_to_y']:
            print("\t{}={}".format(attr.upper(), value))

    print("-------------\nTesting on PLCOm2012")
    model.save_prefix = 'test_'
    model.test(test_data)

    print("Saving args to {}".format(args.results_path))
    pickle.dump(vars(args), open(args.results_path,'wb'))

if __name__ == '__main__':
    __spec__ = "ModuleSpec(name='builtins', loader=<class '_frozen_importlib.BuiltinImporter'>)"
    args = parse_args()
    main(args)


# -*- coding: utf-8 -*-
"""
Created on Tue Dec 31 20:25:03 2019

@author: tejas
"""

pwd
import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

df=Computer_Datacsv

#Label Encoder for cd, multi,premium
from sklearn.preprocessing import LabelEncoder
le=LabelEncoder()

select_column=['cd','multi','premium']

le.fit(df[select_column].values.flatten())

df[select_column]= df[select_column].apply(le.fit_transform)

#corelation matrix
df.corr()
corelation_values=df.corr()

import seaborn as sns
sns.pairplot(df)
# scatter plot

#here colinearity is high between hd & ram but scatter plot shows no any linearity.

#Split the data into train and test .

from sklearn.model_selection import train_test_split

train_data,test_data=train_test_split(df)
#drop the column no. 1

train_data=train_data.reset_index()
test_data=test_data.reset_index()

train_data1=df.drop(["Unnamed: 0"], axis=1)
test_data1=df.drop(["Unnamed: 0"], axis=1)

import statsmodels.formula.api as sf

df.head(2)

#Building the regression model w.r.t. t training data.

m1=sf.ols("price~speed+hd+ram+screen+cd+multi+premium+ads+trend",data=train_data1).fit()

m1.summary()   #R-SQUARE=0.776
#Here r-square is less than 0.8 ,we need some transformations for r-square value more than 0.8.

#check with the vif value.
rsq=sf.ols("price~speed+hd+ram+screen+cd+multi+premium+ads+trend",data=train_data1).fit().rsquared

rsq_final=1/(1-rsq)
#vif value is less than 10.i.e 4.53

import statsmodels.api as sm

sm.graphics.influence_plot(m1)

sm.graphics.plot_partregress_grid(m1)

#Transformations for better value of r-squared.
#Take the sqrt for all input variables.
trans_m1=sf.ols("price~np.sqrt(speed)+np.sqrt(hd)+np.sqrt(ram)+np.sqrt(screen)+cd+multi+premium+np.sqrt(ads)+trend",data=train_data1).fit()
trans_m1.summary()  #r-squared=0.793

#providing the sqrt to output variable w.r.t. to output
trans_m2=sf.ols("np.sqrt(price)~np.sqrt(speed)+np.sqrt(hd)+np.sqrt(ram)+np.sqrt(screen)+cd+multi+premium+np.sqrt(ads)+trend",data=train_data1).fit()
trans_m2.summary()    #r-squared=0.807

#taking log
trans_m3=trans_m1=sf.ols("np.log(price)~np.log(speed)+np.log(hd)+np.log(ram)+np.log(screen)+cd+multi+premium+np.log(ads)+trend",data=train_data1).fit()
trans_m3.summary()     #r-squared=0.791

#taking log for price & sqrt for speed and hd
trans_m4=sf.ols("np.log(price)~np.sqrt(speed)+np.sqrt(hd)+ram+screen+cd+multi+premium+ads+trend",data=train_data1).fit()
trans_m4.summary()    #0.805

#Taking log to price,sqrt to speed,hd & qudratic to speed & hd
trans_m5=trans_m1=sf.ols("np.log(price)~np.sqrt(speed)+(speed*speed)+np.sqrt(hd)+(hd*hd)+(ram)+(screen)+cd+multi+premium+ads+trend",data=train_data1).fit()
trans_m5.summary()        #0.814

#taking th model5 because r squared is high i.e 0.815 with rmse value of train=244.3 & test rmse =249.3
trans_m5=sf.ols("np.log(price)~np.sqrt(speed)+(speed*speed)+np.sqrt(hd)+(hd*hd)+(ram)+(screen)+cd+multi+premium+ads+trend",data=train_data1).fit()
trans_m5.summary()                   #0.814

#train data
final_train_pred=trans_m5.predict(train_data1)
final_train_pred1=np.exp(final_train_pred)

#train residual
train_res=train_data1['price']-final_train_pred1
train_res

#train rmse
train_rsme=np.sqrt(np.mean(train_res*train_res))
train_rsme                    #244.60

#test pred
final_test_pred=trans_m5.predict(test_data1)
final_test_pred1=np.exp(final_test_pred)

#test residuals
final_test_res=test_data1['price']-final_test_pred1

#test rmse
final_test_rmse=np.sqrt(np.mean(final_test_res*final_test_res))

#testing the finalised model with original dataset

df1=df.drop(["Unnamed: 0"],axis=1)
final=sf.ols("np.log(price)~np.sqrt(speed)+(speed*speed)+np.sqrt(hd)+(hd*hd)+(ram)+(screen)+cd+multi+premium+ads+trend",data=df1).fit()
final.summary()                     #0.814

#prediction model
final_pred_log=final.predict(df1)
final_pred=np.exp(final_pred_log)

#checking the linearity with plotting the scatter plot
plt.scatter(df1['price'],final_pred);plt.xlabel("Actual Values");plt.ylabel("fitted values")

plt.scatter(final_pred,final.resid_pearson, c='r');plt.axhline(y=0,color='blue');plt.xlabel("Fitted values");plt.ylabel("Residuals")
#somehow homoscadasticity is present

#check for normality
plt.hist(final.resid_pearson)
#Data is normally distributed

import pylab
import scipy.stats as sc

#checking the final model it shows the data points are within the points.
sc.probplot(final.resid_pearson, dist="norm", plot=pylab)


import logging
import unittest

from tests.helper_func import create_post, load_fixture_config
from yatcobot.config import TwitterConfig
from yatcobot.post_queue import *

logging.disable(logging.ERROR)

class TestPostQueue(unittest.TestCase):

    def setUp(self):
        load_fixture_config()

    def test_sort_queue(self):
        posts = dict()
        for i in range(10):
            post = create_post()
            posts[post['id']] = post

        queue = PostQueue(posts)

        queue.sort()

        key, previous = queue.popitem(last=False)
        for post in queue.values():
            self.assertLessEqual(post['score'], previous['score'])

    def test_sort_queue_len_1(self):
        """If less than 2, raises StatisticsError('variance requires at least two data points')"""
        posts = dict()
        post = create_post()
        posts[post['id']] = post

        queue = PostQueue(posts)

        queue.sort()

        key, previous = queue.popitem(last=False)
        for post in queue.values():
            self.assertLessEqual(post['score'], previous['score'])

    def test_filter_queue(self):
        TwitterConfig.get()['search']['filter']['min_retweets']['enabled'] = True
        TwitterConfig.get()['search']['filter']['min_retweets']['number'] = 5

        posts = dict()
        for i in range(10):
            post = create_post(retweets=i)
            posts[post['id']] = post

        queue = PostQueue(posts)

        queue.filter()
        for post in queue.values():
            self.assertGreaterEqual(post['retweet_count'], 5)


from atlas_sdk import SkillClient, Intent, Slot, Env, Request
from atlas_sdk.utils import svgs_to_data_uri
import time
from dateutil.parser import parse as dateParse

b64_icons = svgs_to_data_uri('sunny.svg')

def get_forecasts(request):
  """
  :type request: Request

  """

  date = request.slot('date').first().value

  if not date:
    return request.ask('date', _('For when do you want the forecast?')) # pylint: disable=E0602

  location = request.slot('city').first().value

  if not location:
    return request.ask('city', _('For where do you want the forecast?')) # pylint: disable=E0602

  request.show(_("Well, I'm on it!")) # pylint: disable=E0602

  time.sleep(3) # Simulate fetching

  # Do something with the key
  api_key = request.env('WEATHER_API_KEY') # pylint: disable=W0612

  request.show(_("It's kinda sunny!"), # pylint: disable=E0602
    cards=[{
      "media": b64_icons['sunny'],
      "header": "24°C",
      "subhead": dateParse(date).strftime("%A %d %B"),
      "text": "Looks like it's sunny outside!"
    }], terminate=True)  # pylint: disable=E0602

if __name__ == '__main__':
  weather_skill = SkillClient(
    name='weather',
    version='1.0.0',
    author='Julien LEICHER',
    description='Gives some weather forecasts',
    intents=[
      Intent('weatherForecast', get_forecasts, [Slot('date'), Slot('city')])
    ],
    env=[Env('WEATHER_API_KEY')]
  )

  weather_skill.run()