"""
        PRACTICA 2 (PRPA)

Laura Cano Gómez

Solution to the one-way tunnel

"""
import time
import random
from multiprocessing import Lock, Condition, Process
from multiprocessing import Value
from multiprocessing import Manager

NORTH = 0
SOUTH = 1

NCARS = 5
NPED = 3     # Como los peatones si pueden pasar en ambos sentidos, no hace falta distinguir su sentido

TIME_CARS_NORTH = 0.5   # a new car enters each 0.5s
TIME_CARS_SOUTH = 0.5   # a new car enters each 0.5s
TIME_PED = 5            # a new pedestrian enters each 5s

TIME_IN_BRIDGE_CARS = (1, 0.5) # normal 1s, 0.5s
TIME_IN_BRIDGE_PEDESTRIAN = (30, 10) # normal 1s, 0.5s

class Monitor():
    def __init__(self):
        self.mutex = Lock()
        self.patata = Value('i',0)

        self.cNortePasando= Value('i', 0)       # Numero de coches del norte dentro del puente
        self.cSurPasando= Value('i', 0)         # Numero de coches del sur dentro del puente
        self.peatonesPasando= Value('i', 0)     # Numero de peatones dentro del puente

        self.permisoCoches= Condition(self.mutex)       # Variable condicion
        self.permisoPeatones= Condition(self.mutex)     # Variable condicion

    '''
    INVARIANTE: (demo en Desarrollo monitor.pdf)
        cNortePasando >= 0
        cSurPasando >= 0
        peatonesPasando >= 0
        cNortePasando > 0 => cSurPasando == 0 /\ peatonesPasando == 0
        cSurPasando > 0 => cNortePasando == 0 /\ peatonesPasando == 0
        peatonesPasando > 0 => cNortePasando == 0 /\ cSurPasando == 0

        Hay inanicion porque podrian estar pasando continuamente  2 de ellos sin que el otro pueda entrar. Ademas, no hoy justicia porque si no paran de llegar de un tipo, hasta que no acaben de salir los otros 2 se quedan bloqueados. Hay que poner alguna limitacion de paso -> turnos (PUENTE POR TURNOS.py)
    '''

    def puenteEstaVacio(self):
        return self.cNortePasando.value == 0 and self.cSurPasando == 0 and self.peatonesPasando == 0

    # Permiso para coches que vienen del norte
    def puedenPasarCN(self):
        # Pueden pasar si no hay coches en sentido contrario ni peatones pasando, o si hay coches en su mismo sentido
        puedenPasar= (self.cSurPasando.value == 0 and self.peatonesPasando.value == 0) or (self.cNortePasando.value>0)

        return  puedenPasar or self.puenteEstaVacio()

    # Permiso para coches que vienen del sur
    def puedenPasarCS(self):
        puedenPasar= (self.cNortePasando.value == 0 and self.peatonesPasando.value == 0) or (self.cSurPasando.value>0)

        return  puedenPasar or self.puenteEstaVacio()

    # Permiso para peatones
    def puedenPasarPeatones(self):
        puedePasar= (self.cNortePasando.value == 0 and self.cSurPasando.value == 0) or (self.peatonesPasando.value>0)
        return puedePasar or self.puenteEstaVacio()

    def wants_enter_car(self, direction: int) -> None:
        self.mutex.acquire()
        self.patata.value += 1
        #### código

        # Espera a tener permiso
        if direction==NORTH:
            self.permisoCoches.wait_for(self.puedenPasarCN)

        else:
            self.permisoCoches.wait_for(self.puedenPasarCS)

        # Entra al puente
        if direction == NORTH:
            self.cNortePasando.value += 1
        else:
            self.cSurPasando.value += 1

        # Sale y abre el mutex
        self.mutex.release()

    def leaves_car(self, direction: int) -> None:
        self.mutex.acquire()
        self.patata.value += 1
        #### código

        # Sale del puente
        if direction == NORTH:
            self.cNortePasando.value -= 1
        else:
            self.cSurPasando.value -= 1

        # Avisa a todos los demas coches y peatones de que ha salido, para que comprueben si pueden pasar
        self.permisoCoches.notify_all()
        self.permisoPeatones.notify_all()

        self.mutex.release()

    def wants_enter_pedestrian(self) -> None:
        self.mutex.acquire()
        self.patata.value += 1
        #### código

        # Espera a tener permiso y entra
        self.permisoPeatones.wait_for(self.puedenPasarPeatones)
        self.peatonesPasando.value += 1

        self.mutex.release()

    def leaves_pedestrian(self) -> None:
        self.mutex.acquire()
        self.patata.value += 1
        #### código

        # Sale del puente
        self.peatonesPasando.value -= 1

        # Avisa a todos los demas coches y peatones de que ha salido, para que comprueben si pueden pasar
        self.permisoCoches.notify_all()
        self.permisoPeatones.notify_all()

        self.mutex.release()

    def __repr__(self) -> str:
        #return f'Monitor: {self.patata.value}'
        return f'\n   Monitor-> Coches Norte: {self.cNortePasando.value}, Coches Sur: {self.cSurPasando.value}, Peatones :  {self.peatonesPasando.value}.\n\n'

# Funciones para simular el tiempo del paso por el puente
# Con normales
'''
def delay_car_north() -> None:
    time.sleep(random.normalvariate(1,0.5))

def delay_car_south() -> None:
    time.sleep(random.normalvariate(1,0.5))

def delay_pedestrian() -> None:
    time.sleep(random.normalvariate(30,10))
'''
# Sin normales
def delay_car_north(factor = 3) -> None:
    time.sleep(random.randint(1,4)/factor)

def delay_car_south(factor = 3) -> None:
    time.sleep(random.randint(1,4)/factor)

def delay_pedestrian(factor = 2) -> None:
    time.sleep(random.randint(3,6)/factor)

# Creación de peatones y coches
def car(cid: int, direction: int, monitor: Monitor)  -> None:
    print(f"Coche {cid} rumbo {direction} quiere entrar. {monitor}")

    monitor.wants_enter_car(direction)
    print(f"Coche {cid} rumbo {direction} entrando... {monitor}")
    if direction==NORTH :
        delay_car_north()
    else:
        delay_car_south()
    #print(f"Coche {cid} rumbo {direction} abandonando el puente. {monitor}")

    monitor.leaves_car(direction)
    print(f"El coche {cid} rumbo {direction} ha salido. {monitor}")

def pedestrian(pid: int, monitor: Monitor) -> None:
    print(f"Peatón {pid} quiere entrar. {monitor}")
    monitor.wants_enter_pedestrian()
    print(f"Peatón {pid} entrando... {monitor}")
    delay_pedestrian()

    #print(f"Peatón {pid} abandonando el puente. {monitor}")
    monitor.leaves_pedestrian()
    print(f"El peatón {pid} ha salido. {monitor}")

def gen_pedestrian(monitor: Monitor) -> None:
    pid = 0
    plst = []
    for _ in range(NPED):
        pid += 1
        p = Process(target=pedestrian, args=(pid, monitor))
        p.start()
        plst.append(p)
        time.sleep(random.expovariate(1/TIME_PED))

    for p in plst:
        p.join()

def gen_cars(direction: int, time_cars, monitor: Monitor) -> None:
    cid = 0
    plst = []
    for _ in range(NCARS):
        cid += 1
        p = Process(target=car, args=(cid, direction, monitor))
        p.start()
        plst.append(p)
        time.sleep(random.expovariate(1/time_cars))

    for p in plst:
        p.join()

def main():
    monitor = Monitor()

    gcars_north = Process(target=gen_cars, args=(NORTH, TIME_CARS_NORTH, monitor))
    gcars_south = Process(target=gen_cars, args=(SOUTH, TIME_CARS_SOUTH, monitor))
    gped = Process(target=gen_pedestrian, args=(monitor,))

    gcars_north.start()
    gcars_south.start()
    gped.start()

    gcars_north.join()
    gcars_south.join()
    gped.join()

if __name__ == '__main__':
    main()


import urllib.request
import urllib.parse
import json

# Base URL for the API endpoint
base_url = "http://py4e-data.dr-chuck.net/json?"

# Prompt for a location
location = "Kokshetau Institute of Economics and Management"

# Encode the location parameter
parameters = {"address": location}
encoded_params = urllib.parse.urlencode(parameters)

# Construct the full URL
url = base_url + encoded_params

try:
    # Call the API and retrieve the JSON data
    response = urllib.request.urlopen(url)
    json_data = response.read().decode()

    # Parse the JSON data
    data = json.loads(json_data)

    # Retrieve the first place_id from the JSON
    place_id = data["results"][0]["place_id"]

    # Print the place_id
    print("Place id:", place_id)

except Exception as e:
    print("An error occurred:", str(e))


#imporamos funciones necesaias
from tkinter import *
from tkinter import ttk
#from functools import partial
from pprint import pprint as pp
from ast import literal_eval

# Estos son modulos desarollados por mi
from src.load_ensemble_data import load_ensemble_data
from src.ui import *

def d_print(string):
    if verbose == True:
        print (string)

def evt_stru_select(evt):
    print (evt)

def create_new_protein_tab(tab_parent,uniprot_id):
    tabs_dict[uniprot_id] = ttk.Frame(tab_parent)
    tab_parent.add(tabs_dict[uniprot_id],text=uniprot_id)
    tabs_abiertas.append(uniprot_id)
    secuencia = ensemble_data[uniprot_id]["Sequence"]
    create_scrolable_aa_list(tabs_dict[uniprot_id],secuencia,xx=10,yy=10,alto=50,ancho=780)
    structure_list= literal_eval(ensemble_data[uniprot_id]["PDB_CHAIN_LIST"])

    container,scrollbar,listbox,listbox_dict = create_listbox(tabs_dict[uniprot_id],structure_list,xx=20,yy=300,alto=400,ancho=100)
    listbox.bind('<<ListboxSelect>>',evt_stru_select)
    return listbox

def create_table(root,lista,xx,yy):
    container = Frame(root)
    for i,lines in enumerate(lista):
        for j,item in enumerate(lines):
            Label(container,text=item,font=monospace).grid(row=i,column=j)
    container.place(x=xx,y=yy)
    return container

# MAIN

# create standar windown
verbose = True
window = Tk()
window.title("Visualizador de ensembles")
window.geometry("800x600")
tabs_abiertas= []

#un diccionario para acceder by uniprot_id
tabs_dict = dict()
tab_parent = ttk.Notebook(window)
tab_selector = ttk.Frame(tab_parent)
tab_parent.add(tab_selector,text="Select protein")
tab_parent.pack(expand=1,fill="both")

# Load load_ensemble_data

ensemble_data,protein_labels = load_ensemble_data()

# Carga un dicionario con laa info para el listbox.

protein_list = list(ensemble_data.keys())
container1,scrollbar1,listbox1,listbox_dict1 = create_listbox(tab_selector,protein_list,xx=10,yy=10,ancho=200,alto=580)

#Define el evento de selecionar
def event_protein_select(evt):
    selected_index = evt.widget.curselection()[0]
    uniprot_id = listbox_dict1[selected_index]
    pp(ensemble_data[uniprot_id])

listbox1.bind('<<ListboxSelect>>',event_protein_select)

def click_select_btn():
    selected_index = listbox1.curselection()[0]
    if not is_none(selected_index):
        uniprot_id = listbox_dict1[selected_index]
        if not uniprot_id in tabs_dict:
            create_new_protein_tab(tab_parent,uniprot_id)

button_select =  Button(tab_selector,text="Seleccionar",command=click_select_btn)
button_select.place (x=100,y=200)

tabla_p = [[x,"N/A"] for x in protein_labels]

protein_table = create_table(tab_selector,tabla_p,xx=220,yy=5)

window.mainloop()


import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
import ast

INF = 100000010
SIZE = 100000 + 1
distances = [INF] * SIZE
visited = [False] * SIZE
vertex = [[] for i in range(SIZE)]
road = [0] * SIZE

global G

def dijkstra(initialNode):
    global G

    distances[initialNode] = 0
    s = [(0,initialNode)]

    while len(s) is not 0:

        p = s.pop()

        x = p[1]
        w = p[0]

        if visited[x] is True:
            continue
        visited[x] = True

        for i in range(len(vertex[x])):
            edge = vertex[x][i][1]
            weight = vertex[x][i][0]

            if (distances[x] + weight) < distances[edge]:
                road[edge] = x

                distances[edge] = distances[x] + weight
                s.append((distances[edge], edge))

#############
def main(s, t):
    global G

    rf = open("copyLugares.txt", "r")
    cities = ast.literal_eval(rf.read())
    rf.close()

    rf = open("copyCoords.txt", "r")
    pos = ast.literal_eval(rf.read())
    rf.close()

    G = nx.Graph()
    rf = open("copyconnect.txt", "r")

    n, m = map(int, rf.readline().split())

    for i in range(m):
        a, b, peso = map(float, rf.readline().split())
        vertex[int(a)].append((peso, int(b)))
        vertex[int(b)].append((peso, int(a)))

    node = s  # De donde empieza
    destiny = t # Destino

    dijkstra(node)

    for i in range(0, n + 1):
        print('[ ', end='')
        print(distances[i], end=' ]')

    print()

    i = destiny
    while (i is not node):
        print(road[i], end=" ")
        formatted_weight = "{:.2f}".format(distances[i])
        G.add_edge(road[i], i, weight=formatted_weight)

        G[road[i]][i]['weight'] = formatted_weight
        i = road[i]

    img = plt.imread("MapaCarreteraBolivia.PNG")
    fig, ax = plt.subplots(figsize=(15, 15))

    ax.imshow(img, extent=[-150, 200, -150, 200], alpha=0.7, resample=False)

    list_of_nodes = list(G.nodes())

    new_dict = "{"
    new_pos = "{"

    for i in range(G.number_of_nodes()):
        new_dict += str(list_of_nodes[i]) + ':"' + str(cities.get(list_of_nodes[i])) + '",'
        new_pos += "\"" + str(cities.get(list_of_nodes[i])) + "\":" + str(pos.get(cities.get(list_of_nodes[i]))) + ','

    new_dict += "}"
    new_pos += '}'

    dicty = ast.literal_eval(new_dict)
    poss = ast.literal_eval(new_pos)

    nx.relabel_nodes(G, mapping=dicty, copy=False)

    labels = nx.get_edge_attributes(G, 'weight')

    # G.remove_node('None')

    nx.draw_networkx(G, poss, with_labels=True, node_color="cyan", node_size=80, width=1)

    labels = nx.get_edge_attributes(G, 'weight')
    nx.draw_networkx_edge_labels(G, poss, edge_labels=labels, font_size=7)

    plt.savefig("path_Dijkstra.png")

    #plt.show()

    rf.close()


"""Module for making a sting-answer from the data"""
from itertools import product
from process_flights import get_price

def sort_by_price(data):
    """Sorts list by the price of the tickets"""
    data[0].sort(key=lambda i: float(i.price.replace(',', '.')))
    return data

def make_to_string(data):
    """Makes a sting-answer from the data"""
    data = sort_by_price(data)
    sum_results = []
    for res in data:
        results = []
        for result in res:
            results.append('Date: {}. Departs in {}, Arrives in {}. '
                           'Duration of flight = {}, {}. '
                           'Price: {} in {}. Class: {}'.format(result.date,
                                                               result.depart_time,
                                                               result.arrive_time,
                                                               result.duration,
                                                               result.stops,
                                                               result.price,
                                                               result.value,
                                                               result.fl_class))
        sum_results.append(results)
    return sum_results

def combine_results(data):
    """Combines results to get all variants of round trip"""
    list_of_combinations = list(product(data[0], data[1]))
    return list_of_combinations

def get_total_price(combination):
    """Counts a total price of two flights in combination"""
    return float(get_price(combination[0]).replace(',', '.')) +\
           float(get_price(combination[1]).replace(',', '.'))


import numpy as np

from copy import copy, deepcopy

class Player:
    def __init__(self):
        self.bets = 1
        self.folded = False
        self.raised = False

    def __repr__(self):
        return f"B: {self.bets} F: {self.folded}"

    def __eq__(self, other):
        return self.bets == other.bets

    def __gt__(self, other):
        return self.bets > other.bets

    def __add__(self, other):
        return self.bets + other.bets

    def __radd__(self, other):
        return self.bets + other

class State:
    def __init__(self, cards, num_players, hand_eval):
        self.num_players = num_players
        self.num_rounds = 1
        self.eval = hand_eval
        self.cards = cards
        self.players = [Player() for _ in range(num_players)]
        self.history = [[] for _ in range(self.num_rounds)]
        self.round = 0
        self.turn = 0
        self.terminal = False

    def __repr__(self):
        return f"{self.history[:self.round+1]}"

    def __eq__(self, other):
        return self.history == other.history and self.cards == other.cards

    def __hash__(self):
        return hash(f'{self.history}, {self.cards}')

    def __copy__(self):
        new_state = State(self.cards, self.num_players, self.eval)
        new_state.players = deepcopy(self.players)
        new_state.history = deepcopy(self.history)
        new_state.turn = self.turn
        new_state.terminal = self.terminal
        new_state.round = self.round

        return new_state

    def info_set(self):
        hole_card = self.cards[self.turn]
        if len(self.cards) > len(self.players):
            board_card = self.cards[len(self.players)]
        else:
            board_card = None

        info_set = f"{hole_card} |{board_card if board_card is not None else ''}| {str(self)}"
        return info_set

    def take(self, action, deep=False):
        if self.terminal == True:
            raise ValueError("Already at a terminal state")

        if deep is True:
            new_state = copy(self)
        else:
            new_state = self

        new_state.history[self.round].append(action)

        curr_player = new_state.players[new_state.turn]
        if action == 'F':
            curr_player.folded = True
            curr_player.raised = False

        elif 'R' in action:
            bet_amount = int(action[:-1])
            call_size = max(self.players).bets - curr_player.bets
            curr_player.bets += bet_amount + call_size
            curr_player.raised = True

        else:
            call_size = max(self.players).bets - curr_player.bets
            curr_player.bets += call_size

        new_state.terminal = new_state.is_terminal()

        return new_state

    def is_terminal(self):
        num_folded = sum([p.folded for p in self.players])

        if num_folded == self.num_players - 1:
            return True

        num_actions = len(self.history[self.round])
        min_actions = self.num_players - num_folded

        max_bet = max([p for p in self.players if p.folded is False],
                        key=lambda k: k.bets)

        end_round = True
        for player in self.players:
            if not player.folded:
                if player < max_bet:
                   end_round = False

        if num_actions >= min_actions and end_round:
            if self.round == self.num_rounds - 1:
                return True
            else:
                self.round += 1
                self.turn = 0
                for p in self.players:
                    p.raised = False

                return False

        self.turn = (self.turn + 1) % self.num_players

        while self.players[self.turn].folded:
            self.turn = (self.turn + 1) % self.num_players

        return False

    def utility(self):
        if len(self.players) - sum([p.folded for p in self.players]) == 1:
            hand_scores = []
            winners = [i for i, _ in enumerate(self.players) if self.players[i].folded == False]

        else:
            board_cards = None if len(self.cards) <= self.num_players else [self.cards[self.num_players]]
            players_in = [i for i, p in enumerate(self.players) if p.folded == False]
            hand_scores = [self.eval(self.cards[i], board_cards) for i in players_in]
            winners = []
            high_score = -1
            for i, score in enumerate(hand_scores):
                if self.players[i].folded == False:
                    if len(winners) == 0 or score > high_score:
                        winners = [i]
                        high_score = score
                    elif score == high_score:
                        winners.append(i)

        pot = sum(self.players)
        payoff = pot / len(winners)
        payoffs = [-p.bets for p in self.players]

        for w in winners:
            payoffs[w] += payoff

        return np.array(payoffs)

    def valid_actions(self):
        any_raises = any([p.raised for p in self.players])
        if any_raises:
            return ['F', 'C']

        return ['F', 'C', '1R']

class Leduc(State):
    def __init__(self, cards, num_players, hand_eval):
        super().__init__(cards, num_players, hand_eval)
        self.num_rounds = 2
        self.players = [Player() for _ in range(num_players)]
        self.history = [[] for _ in range(self.num_rounds)]

    def __copy__(self):
        new_state = Leduc(self.cards, self.num_players, self.eval)
        new_state.players = deepcopy(self.players)
        new_state.history = deepcopy(self.history)
        new_state.turn = self.turn
        new_state.terminal = self.terminal
        new_state.round = self.round

        return new_state

    def valid_actions(self):
        num_raises_so_far = sum([p.raised for p in self.players])

        if num_raises_so_far == self.num_players:
            return ['F', 'C']
        else:
            if self.round == 0:
                return ['F', 'C', '2R']
            else:
                return ['F', 'C', '4R']


# one

def division(a1, a2):
    try:
        a1, a2 = int(a1), int(a2)
        c = a1 / a2
    except ZeroDivisionError:
        return 'На 0 делить нельзя!'
    except ValueError:
        return 'Это не число!'
    return c

print(division(input("Введите число a1 = "), input("Введите число a2 = ")))

# two

def data(name, surname, year, city, email, phone):
    return f'Имя - {name}, Фамалия - {surname}, Год рождения - {year}, Город - {city}, Почта - {email}, ' \
           f'Телефон - {phone}'

print(data(name='Мария', surname='Иванова', year='12.11.1989', city='СПб',
           email='mivanova@mail.ru', phone='8-985-454-31-74'))

# three
def my_func(a, b, c):
    return sum(sorted([a, b, c])[1:])

print(f'Сумма двух наибольших аргументов равна - {my_func(5454, 2444, 7452)}')

# four
def degree_func(x, y):
    try:
        x, y = float(x), int(y)
        res = x ** y
    except TypeError:
        return "Ведите действительное положительное число x и целое отрицательное число y."
    return res

print(degree_func(input('Введите дейтсивтельное положительное число x: '),
                  input('Введите целое отрицательное число y: ')))

def degree_func1(x1, y1):
    try:
        res = 1
        x1, y1 = float(x1), int(y1)
        if x1 <= 0 or y1 >= 0:
            return "Ошибка!"
        else:
            for i in range(abs(y1)):
                res /= x1
        return f"Результат возведения: {round(res,8)}"
    except ValueError:
        return "Вводите только числа!"

print(degree_func1(input('Введите дейтсивтельное положительное число x1: '),
                   input('Введите целое отрицательное число y1: ')))

# five
def summa():
    t = 0
    while True:
        number = input('Введите число, или символ "&" для выхода: ').split()
        for num in number:
            if num.lower() == "&":
                return t
            else:
                try:
                    t += int(num)
                except ValueError:
                    print('Для выхода, введите "&".')
            print(f"Сумма чисел = {t}")

print(summa())

# six-seven

def word_func():
    for word in input('Вводите слова через пробел на латинице: ').split():
        symbols = 0
        for symbol in word:
            if 97 <= ord(symbol) <= 122:
                symbols += 1
                if symbols != len(word):
                    break
                else:
                    print(f'Вводить только на английской раскладке!{word}')
        print(word.title())

print(word_func())


"""
Normalization functions such as batch norm
"""

from typing import Optional, Sequence, Union, Tuple
from .. import nn

def moments(x: nn.Tensor, axis: Union[nn.Dim, Sequence[nn.Dim]]) -> Tuple[nn.Tensor, nn.Tensor]:
    """
    :param x: input
    :param axis: the axis to be reduced, to calculate statistics over
    :return: mean, variance. it has the same shape as the input with the axis removed
    """
    mean = nn.reduce(x, mode="mean", axis=axis, name="mean")
    # stop_gradient does not change the gradient here
    variance = nn.reduce(nn.squared_difference(x, nn.stop_gradient(mean)), mode="mean", axis=axis, name="variance")
    return mean, variance

class LayerNorm(nn.Module):
    """
    `Layer normalization <https://arxiv.org/abs/1607.06450>`__.

    Note that we *just* normalize over the feature-dim axis here.
    This is consistent to the default behavior of :class:`tf.keras.layers.LayerNormalization`
    and also how it is commonly used in many models, including Transformer.

    However, there are cases where it would be common to normalize over all axes except batch-dim,
    or all axes except batch and time.
    For a more generic variant, see :func:`norm`.
    """

    def __init__(self, in_dim: Union[nn.Dim, Sequence[nn.Dim]], *, eps: float = 1e-6):
        super().__init__()
        self.in_dim = in_dim
        self.eps = eps
        self.scale = nn.Parameter([self.in_dim] if isinstance(self.in_dim, nn.Dim) else self.in_dim)
        self.scale.initial = 1.0
        self.bias = nn.Parameter(self.scale.dims)
        self.bias.initial = 0.0

    def __call__(self, x: nn.Tensor) -> nn.Tensor:
        mean = nn.reduce(x, axis=self.in_dim, mode="mean")
        variance = nn.reduce(nn.squared_difference(x, mean), axis=self.in_dim, mode="mean", name="variance")
        norm_x = (x - mean) * nn.rsqrt(variance + self.eps)
        return norm_x * self.scale + self.bias

class BatchNorm(nn.Module):
    """
    Batch normalization. https://arxiv.org/abs/1502.03167

    Note that the default arguments differ from corresponding batch norm in RETURNN.
    See here for discussion on defaults: https://github.com/rwth-i6/returnn/issues/522

    We calculate statistics over all axes except the given in_dim.
    I.e. all other axes are reduced for the statistics.

    To compensate the normalization, there are learnable parameters gamma and beta
    (optional, used when option `affine` is True).

    The usual behavior depends on whether this is used in training or evaluation,
    although this often configurable in other frameworks.
    The usual behavior, in training::

        # Using statistics from current batch.
        mean_cur_batch, variance_cur_batch = moments(source, reduce_dims)
        y = (x - mean_cur_batch) / sqrt(variance_cur_batch + epsilon)
        y = gamma * y + beta

        # Updating running statistics for later use.
        mean = (1 - momentum) * mean + momentum * mean_cur_batch
        variance = (1 - momentum) * variance + momentum * variance_cur_batch

    The usual behavior, not in training (i.e. in evaluation)::

        # Using collected statistics. Not using statistics from current batch.
        y = (x - mean) / sqrt(variance + epsilon)
        y = gamma * y + beta

    """

    def __init__(
        self,
        in_dim: nn.Dim,
        *,
        affine: bool = True,
        momentum: float = 0.1,
        epsilon: float = 1e-3,
        use_mask: Optional[bool] = None,
    ):
        """
        :param in_dim: the feature dimension of the input
        :param affine: whether to use learnable parameters gamma and beta
        :param momentum: momentum for the running mean and variance
        :param epsilon: epsilon for the variance
        :param use_mask: whether to use a mask for dynamic spatial dims.
          This must be specified if the input has dynamic spatial dims.
          True would use the correct masking then. However, that is inconsistent to all other frameworks
            which ignore the masking, and also slower, and the fused op would not be used.
          False would be consistent to all other frameworks,
            and potentially allows for the use of an efficient fused op internally.
        """
        super().__init__()
        assert isinstance(in_dim, nn.Dim)
        self.in_dim = in_dim
        self.use_mask = use_mask
        self.momentum = momentum
        self.epsilon = epsilon
        self.running_mean = nn.Parameter([in_dim], auxiliary=True)
        self.running_mean.initial = 0.0
        self.running_variance = nn.Parameter([in_dim], auxiliary=True)
        self.running_variance.initial = 1.0
        self.affine = affine
        self.gamma = None  # type: Optional[nn.Parameter]
        self.beta = None  # type: Optional[nn.Parameter]
        if self.affine:
            self.gamma = nn.Parameter([in_dim])
            self.gamma.initial = 1.0
            self.beta = nn.Parameter([in_dim])
            self.beta.initial = 0.0

    def __call__(self, source: nn.Tensor) -> nn.Tensor:
        # We wrap the RETURNN layer because we want efficient handling if possible,
        # which is potentially the use of a fused op,
        # and maybe reordering of dims.
        # https://github.com/rwth-i6/returnn_common/issues/89
        spatial_dims = source.dims_set - {nn.batch_dim, self.in_dim}
        assert len(spatial_dims) == len(source.dims_set) - 2
        if any(d.dimension is None for d in spatial_dims):  # any dynamic spatial dim
            if self.use_mask is None:
                raise ValueError(
                    f"{self}: use_mask must be specified if the input {source} has any dynamic spatial dims"
                )
            use_mask = self.use_mask
        else:
            use_mask = False  # not needed. False because this potentially enables an efficient fused op.
        reuse_params = {
            "batch_norm/v2_mean": self.running_mean,
            "batch_norm/v2_variance": self.running_variance,
        }
        if self.affine:
            reuse_params["batch_norm/v2_gamma"] = self.gamma
            reuse_params["batch_norm/v2_beta"] = self.beta
        reuse_params = {"map": {k: {"layer_output": v} for k, v in reuse_params.items()}}
        return nn.make_layer(
            {
                "class": "batch_norm",
                "from": source,
                "in_dim": self.in_dim,
                "use_std": self.affine,
                "use_shift": self.affine,
                "param_version": 2,
                "reuse_params": reuse_params,
                "momentum": self.momentum,
                "epsilon": self.epsilon,
                "masked_time": use_mask,
            },
            name="batch_norm",
        )

def normalize(a: nn.Tensor, *, axis: Union[nn.Dim, Sequence[nn.Dim]], epsilon: float = 1e-6) -> nn.Tensor:
    """
    Mean- and variance-normalize some input in the given input dimension(s),
    such that the resulting tensor has mean 0 and variance 1.

    If you want that this can be shifted and scaled again,
    you need additional parameters, cf. :class:`Normalize`.

    :param a: input
    :param axis: axis over which the mean and variance are computed
    :param epsilon: epsilon for numerical stability
    :return: (a - mean) / sqrt(variance + epsilon)
    """

    mean, variance = nn.moments(a, axis=axis)
    return (a - mean) * nn.rsqrt(variance + epsilon)

class Normalize(nn.Module):
    """
    :func:`normalize` with additional scale and bias
    """

    def __init__(
        self,
        *,
        param_shape: Union[nn.Dim, Sequence[nn.Dim]],
        epsilon: float = 1e-6,
        scale: bool = True,
        bias: bool = True,
    ):
        """
        :param param_shape: shape of the scale and bias parameters
        :param epsilon: epsilon for numerical stability
        :param scale: whether to include a trainable scale
        :param bias: whether to include a trainable bias
        """
        super(Normalize, self).__init__()
        self.epsilon = epsilon
        if isinstance(param_shape, nn.Dim):
            param_shape = [param_shape]
        self.scale = None
        if scale:
            self.scale = nn.Parameter(shape=param_shape)
            self.scale.initial = 1.0
        self.bias = nn.Parameter(shape=param_shape) if bias else None

    def __call__(self, a: nn.Tensor, *, axis: Union[nn.Dim, Sequence[nn.Dim]]):
        norm = normalize(a, axis=axis, epsilon=self.epsilon)
        if self.scale is not None:
            norm = self.scale * norm
        if self.bias is not None:
            norm = norm + self.bias
        return norm


#!/usr/bin/python3
import sys, os

## Ask for input
user = input("What is the username to add? ")
key = input("What is Public SSH for new user? ")
comment = input("Type UID/Comment for user: ")

## Create function to add user
def createuser():
    ## Create User Account
    os.system("useradd -m " + user + " -p " + key + " -c " + comment)
    ## Input Public SSH Key
    os.system("mkdir -p /home/" + user + "/.ssh && echo " + key + " >> /home/" + user + "/.ssh/id_rsa.pub")

## Execute Add User Function
createuser()


"""changed user.id to type string

Revision ID: 712f2c5f8c2c
Revises:
Create Date: 2023-10-28 21:10:20.093259

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '712f2c5f8c2c'
down_revision = None
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    with op.batch_alter_table('user', schema=None) as batch_op:
        batch_op.alter_column('id',
               existing_type=sa.INTEGER(),
               type_=sa.String(length=11),
               existing_nullable=False)
        batch_op.create_unique_constraint('unique_user_id', ['id'])

    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    with op.batch_alter_table('user', schema=None) as batch_op:
        batch_op.drop_constraint('unique_user_id', type_='unique')
        batch_op.alter_column('id',
               existing_type=sa.String(length=11),
               type_=sa.INTEGER(),
               existing_nullable=False)

    # ### end Alembic commands ###


import logging
import requests

from typing import List
from concurrent.futures import ThreadPoolExecutor

from v2.scrapping_books.pages.books_page import BooksPage
from v2.scrapping_books.parsers.book import BookParser

logging.basicConfig(
    format="%(asctime)s %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s",
    datefmt="%d-%m-%Y %H:%M:%S",
    level=logging.INFO,
    filename="logs.txt",
)

logger = logging.getLogger("scraping")

class BookManager:
    URL = "https://books.toscrape.com/"

    def __init__(self):
        # self.books = self.retrieve_books()
        self.books = self.retrieve_books_mul()
        self.books_gen = (book for book in self.books)

    def fetch_url(self, url) -> str:
        response_content = requests.get(url).content
        print(f"reading page {url}")
        return response_content

    def retrieve_books(self) -> List[BookParser]:
        """retrieve all books sequentially"""
        # Fetch the first page to determine the total number of pages
        first_page_content = self.fetch_url(self.URL + "catalogue/page-1.html")
        first_page = BooksPage(first_page_content)
        total_pages = first_page.page_count

        # Initialize the books list with books from the first page
        _books = first_page.books

        # Fetch books from the remaining pages
        for page in range(2, total_pages + 1):
            url = self.URL + f"catalogue/page-{page}.html"
            page_content = self.fetch_url(url)
            page = BooksPage(page_content)
            _books.extend(page.books)

        return _books

    def retrieve_books_mul(self) -> List[BookParser]:
        """retrieve all books concurrently"""
        first_page_content = self.fetch_url(self.URL + "catalogue/page-1.html")
        first_page = BooksPage(first_page_content)
        total_pages = first_page.page_count

        _books = first_page.books
        URLs = [
            self.URL + f"catalogue/page-{i}.html" for i in range(2, total_pages + 1)
        ]

        with ThreadPoolExecutor() as executor:
            contents = list(executor.map(self.fetch_url, URLs))
            for content in contents:
                page = BooksPage(content)
                _books.extend(page.books)

        return _books

    def look_top_books(self):
        top_books = [book for book in self.books if book.stars == 5][:20]
        for book in top_books:
            print(book)

    def look_cheapest_books(self):
        cheapest_books = sorted(self.books, key=lambda x: x.price)[:20]
        for book in cheapest_books:
            print(book)

    # show 10 books sorted by starts (desc) and price (asc)
    # @dev: first sorts by starts, then sorts by price
    # best_cheapest_books = sorted(books, key=lambda x: (x.stars * -1, x.price))[:10]
    # for book in best_cheapest_books:
    #     print(book)

    def get_next_available_book(self):
        print(next(self.books_gen))

    @property
    def get_user_choice(self) -> str:
        return f"""Enter one of the following:
            - 'b' to look at 5-star books
            - 'c' to look at the cheapest books
            - 'n' to just get the next available book on the catalogue
            - 'q' to exit
        """

    def menu(self):
        user_options = {
            "b": self.look_top_books,
            "c": self.look_cheapest_books,
            "n": self.get_next_available_book,
        }
        user_input = input(self.get_user_choice)
        while user_input != "q":
            if user_input in user_options:
                selected_function = user_options[user_input]
                selected_function()
            else:
                print("Unknown command. Please try again.")
            user_input = input(self.get_user_choice)

def test():
    logger.info("Loading books list...")
    manager = BookManager()
    manager.menu()

    # print('ALL BOOKS')
    # for book in books:
    #     print(book)
    # print('-------- TOP 10 best books --------')
    # print_best_books(books)
    # print('-------- TOP 10 cheapest books --------')
    # print_cheapest_books(books)
    # print('-------- TOP 10 best cheapest books --------')
    # print_best_cheapest_books(books)


#-----------------------------------------------------
# Mimas: conference submission and review system
# (c) Allan Kelly 2016-2020 http://www.allankelly.net
# Licensed under MIT License, see LICENSE file
# -----------------------------------------------------

# System imports

# Google imports

from google.appengine.ext import ndb

# Local imports
from scaffold import tags
import basehandler

class EditTagsPage(basehandler.BaseHandler):
    def get(self):
        speaker = None
        talk = None
        tag_list = []

        if self.request.params.has_key("spk"):
            tag_type = "Speaker"
            speaker = ndb.Key(urlsafe=self.request.get("spk")).get()
            tags_list = tags.TagList(speaker.key).pretty_tag_list([tag_type])
            parent_key = speaker.key.urlsafe()

        if self.request.params.has_key("talk"):
            tag_type="Talk"
            talk = ndb.Key(urlsafe=self.request.get("talk")).get()
            tags_list = tags.TagList(talk.key).pretty_tag_list([tag_type])
            parent_key = talk.key.urlsafe()

        template_values = {
            "speaker":      speaker,
            "talk":         talk,
            "parent_key":   parent_key,
            "tags":         tags_list,
            "tag_type":     tag_type,
            "all_tags":     tags.retrieve_all_unique_tags(),
        }

        self.write_page("scaffold/edittags.html", template_values)

    def post(self):
        parent_key = ndb.Key(urlsafe=self.request.get("parent_key"))
        if self.request.get("remove_tag"):
            tags.TagList(parent_key).remove_tag(self.request.get("newtag"), [self.request.get("tag_type")])

        if self.request.get("tag_type") == "Speaker":
            self.redirect("/edittags?spk=" + parent_key.urlsafe())
        else:
            self.redirect("/edittags?talk=" + parent_key.urlsafe())

class AddTagPost(basehandler.BaseHandler):
    def post(self):
        k = ndb.Key(urlsafe=self.request.get("key"))
        tags.TagList(k).add_tag(self.request.get("tag"), self.request.get("tag_type"))


'''
Created on May 20, 2018

@author: hlv_trinh
'''

from __future__ import print_function
from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools
from googleapiclient.http import MediaFileUpload
import resource

ROOT_BACKUP_FOLDER = "server-backup"
MAX_RETRY = 10
CHUNK_SIZE = 5 * 1024 * 1024 #5MB

MAX_MEMORY = 256 * 1024 * 1024

soft, hard = resource.getrlimit(resource.RLIMIT_AS)
resource.setrlimit(resource.RLIMIT_AS, (MAX_MEMORY, hard))
print("Current limit: %s, %s | New: %s" %(soft, hard, MAX_MEMORY))

def FindAndCreateIfNotExist(service, parentFolderId, folderName):
    if parentFolderId == None:
        query = ("name='%s'" % folderName)
    else:
        query = ("name='%s' and '%s' in parents" % (folderName, parentFolderId))

    response = service.files().list(
        q=query,
        spaces='drive',
        fields='nextPageToken, files(id, name)',
        pageToken=None).execute()
    backupDir = response.get('files', [])
    if len(backupDir) > 0:
        backupFile = backupDir[0]
    else:
        print("Not found root folder, trying to create: %s" % folderName)
        if parentFolderId == None:
            body = {'name':folderName,
                    'mimeType':'application/vnd.google-apps.folder'}
        else:
            body = {'name':folderName,
                    'mimeType':'application/vnd.google-apps.folder',
                    'parents': [parentFolderId]}
        backupFile = service.files().create(
            body=body,
            fields='id, name').execute()
    if (backupFile.get('id') != ''):
        print('Backup Root Folder: %s (%s)' % (backupFile.get('name'), backupFile.get('id')))

    return backupFile

def uploadBackupFile(service, parentFolderId, filePath):
    print(filePath)
    import os.path
    fileSize = os.path.getsize(filePath)
    if fileSize <= CHUNK_SIZE:
        media_body = MediaFileUpload(filePath, mimetype='application/octet-stream', resumable=True)
    else:
        media_body = MediaFileUpload(filePath, mimetype='application/octet-stream', chunksize=CHUNK_SIZE, resumable=True)
    fileName = os.path.basename(filePath)
    body = {
        'name': fileName,
        'description': fileName,
        'mimeType': 'application/octet-stream',
        'parents': [parentFolderId]
    }

    retries = 0
    request = service.files().create(body=body, media_body=media_body)
    response = None
    from apiclient import errors
    success = True
    while response is None:
        try:
            status, response = request.next_chunk()
            if status:
                print("Uploaded %.2f%%" % (status.progress() * 100))
                retries = 0
        except errors.HttpError as e:
                if e.resp.status == 404:
                    print("Error 404! Aborting.")
                    success = False
                    break
                else:
                    if retries > MAX_RETRY:
                        print("Retries limit exceeded! Aborting.")
                        success = False
                        break
                    else:
                        retries += 1
                        import time
                        time.sleep(2**retries)
                        print("Error (%d)... retrying." % e.resp.status)
                        continue
    if success:
        print("Upload Complete!")
        os.remove(filePath)

def main():
    """
    Shows basic usage of the Drive v3 API.

    Creates a Drive v3 API service and prints the names and ids of the last 10 files
    the user has access to.
    """

    import sys
    if len(sys.argv) < 1:
        print('Invalid input folder')
        exit(1)

    # Setup the Drive v3 API
    SCOPES = 'https://www.googleapis.com/auth/drive.file'
    store = file.Storage('credentials.json')
    creds = store.get()
    if not creds or creds.invalid:
        flow = client.flow_from_clientsecrets('client_secret.json', SCOPES)
        creds = tools.run_flow(flow, store)

    http = Http()
    http.redirect_codes = http.redirect_codes - {308}
    service = build('drive', 'v3', http=creds.authorize(http))

    # Find the backup root folder or else, create it
    backupFile = FindAndCreateIfNotExist(service, None, ROOT_BACKUP_FOLDER)

    import socket
    hostname = socket.gethostname()
    if hostname.strip() == "":
        hostname = "Unknown"

    backupFile = FindAndCreateIfNotExist(service, backupFile.get('id'), hostname)

    import time
    timestr = time.strftime("%Y%m%d-%H%M%S")
    backupFile = FindAndCreateIfNotExist(service, backupFile.get('id'), timestr)

    parentFolderId = backupFile.get('id')
    filePath = sys.argv[1]

    import os
    if os.path.isfile(filePath):
        uploadBackupFile(service, parentFolderId, filePath)
    else:
        for f in os.listdir(filePath):
            uploadBackupFile(service, parentFolderId, os.path.join(filePath,f))

    #service.close()

if __name__ == '__main__':
    main()


from django.contrib.sessions.backends.db import SessionStore as DBStore
from django.utils.functional import cached_property
from django.conf import settings
from account.middleware import get_current_request

class SessionStore(DBStore):

    @classmethod
    def get_model_class(cls):
        from account.models import CustomSession
        return CustomSession

    def create_model_instance(self, data):

        request = get_current_request()
        print('request: %s' % request)
        # print('ip: %s' % ip)
        # print('request.user.username: %s' % request.user.username)
        print('hello')

        custom_session_instance = self._get_session_from_db()
        print(custom_session_instance)

        email = None
        name = None
        if not custom_session_instance:
            date_created = None
            ip = request.META.get('REMOTE_ADDR')
            print('new_ip: %s' % ip)

        else:
            date_created = custom_session_instance.created_at
            ip = request.META.get('REMOTE_ADDR')
            stored_ip = custom_session_instance.ip
            if request.user.is_authenticated:
                name = request.user.username
                email = request.user.email
            if stored_ip == ip:
                print('stored_ip')
                ip = ip
            else: print('ip is changed')

        return self.model(
            session_key=self._get_or_create_session_key(),
            session_data=self.encode(data),
            expire_date=self.get_expiry_date(),
            created_at = date_created,
            ip = ip,
            name =name,
            email = email,

       )


#!/usr/bin/python3
import sys
import os

class bcolors:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'

if (len(sys.argv) < 2):
    print("Usage: ./grouper.py <shell.txt in \\xFF format>")
    exit()

readfile = sys.argv[1]

with open(os.path.splitext(readfile)[0] + '_grouped.txt', 'w') as outfile, open(readfile, 'r', encoding='utf-8') as infile:
    shellcode = infile.read()
    print(bcolors.OKGREEN + "[+] Loaded shellcode is: " + bcolors.ENDC + shellcode)

    stripped_shellcode = shellcode.replace('\\x', '')
    byteShellcode = bytearray.fromhex(stripped_shellcode)
    info = [byteShellcode[i:i+4] for i in range(0, len(byteShellcode), 4)]
    finalByteArray = bytearray()
    for subarray in reversed(info):
        if (len(subarray) < 4):
            subarray +=  bytearray(4 - len(subarray))

        finalByteArray += subarray[-1: -len(subarray)-1: -1]

    out = ''.join('%02x'%i for i in finalByteArray).upper()
    print(bcolors.OKGREEN + "[+] Grouped shellcode is: " + bcolors.ENDC + out)
    outfile.write(out + '\n')


from hydra import compose, initialize
import numpy as np
import torch
import torch.nn as nn
from torch.utils.data import DataLoader
import lightning.pytorch as L
import pickle
import sys
import os
sys.path.append("../")
from models.lightning_modules import CNN_mel, CNN_modgd, CNN_pitch, ListDataset

# global initialization
initialize(version_base=None, config_path="../../configs")
cfg = compose(config_name="config")

#device config
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

def calculate_acc(y1, y2):
    ret = 0
    for i, _ in enumerate(y1):
        ret += int(y1[i] == y2[i])
    ret /= len(y1)
    return ret

def calculate_f1(y1, y2):
    tp = 0
    fp = 0
    fn = 0
    for i, _ in enumerate(y1):
        if y1[i] == 1 and y2[i] == 1:
            tp += 1
        elif y1[i] == 1 and y2[i] == 0:
            fp += 1
        elif y1[i] == 0 and y2[i] == 1:
            fn += 1
    f1 = (2 * tp) / (2 * tp + fp + fn)
    return f1

# constants
lr = cfg.training.learning_rate
num_classes = cfg.constants.num_classes
num_workers = os.cpu_count()

# paths
models_dir = cfg.paths.models_folder

# label map
label_map = cfg.label_map

# methods
aggregation_method = cfg.aggregation.method
fusion_method = cfg.fusion.method

# fusion
theta_step = cfg.fusion.theta_step
theta_step_new = cfg.fusion.theta_step_new
theta_max = cfg.fusion.theta_max
version = cfg.fusion.version
optimization_metric = cfg.fusion.optimization_metric

models = []
model_names = []

for root, dirs, files in os.walk(models_dir):
    files.sort()
    for file in files:
        if (file == 'cnn_mel.ckpt'):
            print('success')
            model = CNN_mel.load_from_checkpoint(os.path.join(models_dir, file), lr=lr, num_labels=num_classes, map_location=device)
            model_names.append(file)
            models.append(model)
        elif (file == 'cnn_modgd.ckpt'):
            model = CNN_modgd.load_from_checkpoint(os.path.join(models_dir, file), lr=lr, num_labels=num_classes, map_location=device)
            model_names.append(file)
            models.append(model)
        elif (file == 'cnn_pitch.ckpt'):
            model = CNN_pitch.load_from_checkpoint(os.path.join(models_dir, file), lr=lr, num_labels=num_classes, map_location=device)
            model_names.append(file)
            models.append(model)
num_models = len(models)
print(model_names)

print("Load X_test and y_test")
f = open("../../data/processed/X_test_mel.pkl", "rb")
X_test_mel = pickle.load(f)
f.close()
print("Mel data loaded!")

f = open("../../data/processed/X_test_modgd.pkl", "rb")
X_test_modgd = pickle.load(f)
f.close()
print("Modgd data loaded!")

f = open("../../data/processed/X_test_pitch.pkl", "rb")
X_test_pitch = pickle.load(f)
f.close()
print("Pitch data loaded!")

f = open("../../data/processed/y_test.pkl", "rb")
y_test = pickle.load(f)
f.close()

X_test = [X_test_mel, X_test_modgd, X_test_pitch]

a = y_test
y_test = torch.zeros((len(a), num_classes))
for i in range(len(a)):
    y_test[i] = a[i][0]

print("Loaded!")

print("Computing probabilities")
probabilities = []

for i in range(num_models):
    keys = list(X_test[i].keys())
    vals = list(X_test[i].values())
    dataset = ListDataset(keys, vals)
    predict_loader = DataLoader(dataset, batch_size=1, num_workers=num_workers, shuffle=False)

    model = models[i]
    trainer = L.Trainer()
    trainer.predict(model, dataloaders=predict_loader)

    model_predictions = model.model_predictions
    model_predictions = torch.stack(model_predictions)
    probabilities.append(model_predictions)

probabilities = torch.stack(probabilities)
probabilities = probabilities.detach().cpu().numpy()

print("Probabilities computed!")
print(probabilities.shape)
y_pred = np.zeros((probabilities.shape[1], probabilities.shape[2]))
mul_probabilities = np.zeros((probabilities.shape[1], probabilities.shape[2]))
fusion = np.zeros((num_classes, num_models))
thetas = np.arange(0, theta_max, theta_step)

final_accuracy = 0.0

print("Calculating fusion thresholds!")

if fusion_method == 1:

    thetas_mel = thetas
    if "mel" not in version:
        thetas_mel = [-1]
    thetas_modgd = thetas
    if "modgd" not in version:
        thetas_modgd = [-1]
    thetas_pitch = thetas
    if "pitch" not in version:
        thetas_pitch = [-1]

    for k in range(num_classes):
        best_acc = 0.0
        best_f1 = 0.0
        print(k)
        for theta1 in thetas_mel:
            for theta2 in thetas_modgd:
                for theta3 in thetas_pitch:
                    fusion_thetas = [theta1, theta2, theta3]
                    pred = [(np.array(probabilities[id, :, k]) - theta) for id, theta in enumerate(fusion_thetas)]

                    for i, _ in enumerate(pred):
                        pred[i][pred[i] > 0] = 1
                        pred[i][pred[i] <= 0] = 0

                    for i, _ in enumerate(fusion_thetas):
                        if fusion_thetas[i] == -1:
                            pred[i] = np.ones(pred[i].shape)

                    pred = np.multiply(np.multiply(pred[0], pred[1]), pred[2])

                    if optimization_metric == "acc":
                        acc = calculate_acc(pred, y_test[:, k])
                        if acc > best_acc:
                            best_acc = acc
                            y_pred[:, k] = pred
                            fusion[k, :] = fusion_thetas

                    elif optimization_metric == "f1":
                        f1 = calculate_f1(pred, y_test[:, k])
                        if f1 > best_f1:
                            best_f1 = f1
                            y_pred[:, k] = pred
                            fusion[k, :] = fusion_thetas

        thetas_mel_new = np.arange(fusion[k][0] - 0.05, fusion[k][0] + 0.05, theta_step_new)
        if "mel" not in version:
            thetas_mel_new = [-1]
        thetas_modgd_new = np.arange(fusion[k][1] - 0.05, fusion[k][1] + 0.05, theta_step_new)
        if "modgd" not in version:
            thetas_modgd_new = [-1]
        thetas_pitch_new = np.arange(fusion[k][2] - 0.05, fusion[k][2] + 0.05, theta_step_new)
        if "pitch" not in version:
            thetas_pitch_new = [-1]

        for theta1 in thetas_mel_new:
            for theta2 in thetas_modgd_new:
                for theta3 in thetas_pitch_new:
                    fusion_thetas = [theta1, theta2, theta3]
                    pred = [(np.array(probabilities[id, :, k]) - theta) for id, theta in enumerate(fusion_thetas)]

                    for i, _ in enumerate(pred):
                        pred[i][pred[i] > 0] = 1
                        pred[i][pred[i] <= 0] = 0

                    for i, _ in enumerate(fusion_thetas):
                        if fusion_thetas[i] == -1:
                            pred[i] = np.ones(pred[i].shape)

                    pred = np.multiply(np.multiply(pred[0], pred[1]), pred[2])

                    if optimization_metric == "acc":
                        acc = calculate_acc(pred, y_test[:, k])
                        if acc > best_acc:
                            best_acc = acc
                            y_pred[:, k] = pred
                            fusion[k, :] = fusion_thetas

                    elif optimization_metric == "f1":
                        f1 = calculate_f1(pred, y_test[:, k])
                        if f1 > best_f1:
                            best_f1 = f1
                            y_pred[:, k] = pred
                            fusion[k, :] = fusion_thetas

        final_accuracy += calculate_acc(y_pred[:, k], y_test[:, k])

final_accuracy = final_accuracy / num_classes

print("Final accuracy:", final_accuracy)

# Save fusion thresholds
save_str = "fusion_thresholds_"
for model_name in version:
    save_str += model_name
    save_str += "_"
save_str += optimization_metric
save_str += ".npy"
np.save(save_str, fusion)


"""Common utility functions for emotion detection."""
import cv2
import numpy as np

class_indices = {0: 'angry',
                 1: 'confused',
                 2: 'crosseyed',
                 3: 'happy',
                 4: 'neutral',
                 5: 'sad'}

def preprocess_image(image):
    """Scale, reshape etc."""
    image = cv2.resize(image, (480, 360))
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    image = image / 255.
    image = np.expand_dims(image, axis=0)
    return image

def overlay_text(img, emotion, state, recording, bottomLeftCornerOfText,
                 font, fontScale, fontColor, lineType, row_dy):
    """Overlay status text on image."""
    if state == 'recording' and recording:
        img = cv2.circle(img, (30, 30), 10, (0, 0, 255), -1)
    elif state == 'recording' and not recording:
        img = cv2.circle(img, (30, 30), 10, (255, 255, 0), -1)

    x = bottomLeftCornerOfText[0]
    y = bottomLeftCornerOfText[1]
    rows = emotion.split('\n')
    y_pos = [y - i*row_dy for i in range(len(rows))]
    y_pos.reverse()

    for i, line in enumerate(rows):
        y = y_pos[i]
        textpos = (x, y)
        cv2.putText(
            img,
            line,
            textpos,
            font,
            fontScale,
            fontColor,
            lineType
        )
    return img

def get_top_classes(network_output, n=2):
    """Convert array to n human readable classes and scores."""
    idx = (-network_output[0, :]).argsort()[:n]
    scores = []
    for i in range(n):
        score = network_output[0, idx[i]]
        emotion = class_indices[idx[i]]
        scores.append({'emotion': emotion, 'score': score})
    # emo1 = str(round(score1*100, 2)) + '% ' + class_indices[idx[0]]
    # score2 = network_output[0, idx[1]]
    # emo2 = str(round(score2*100, 2)) + '% ' + class_indices[idx[1]]
    return scores


import webbrowser
import cv2
import pyautogui as pag
import tensorflow.keras
from PIL import Image, ImageOps
import numpy as np
np.set_printoptions(suppress=True)
# pre loading Model
model = tensorflow.keras.models.load_model('D:\Device-Control-Using-OpenCV-and-ML\Device-Control-Using-OpenCV-and-ML\opencv\model\keras_model.h5')
data = np.ndarray(shape=(1, 224, 224, 3), dtype=np.float32)
pred=[]
def image_prediction(imageOpenCv):
    # Disable scientific notation for clarity
    #np.set_printoptions(suppress=True)
    #nonlocal model
    # Load the model
    #model = tensorflow.keras.models.load_model('D:\Device-Control-Using-OpenCV-and-ML\Device-Control-Using-OpenCV-and-ML\opencv\model\keras_model.h5')

    # Create the array of the right shape to feed into the keras model
    # The 'length' or number of images you can put into the array is
    # determined by the first position in the shape tuple, in this case 1.
    # data = np.ndarray(shape=(1, 224, 224, 3), dtype=np.float32)

    # Replace this with the path to your image
    image = Image.open('D:\Device-Control-Using-OpenCV-and-ML\Device-Control-Using-OpenCV-and-ML\obc.jpg ')

    # resize the image to a 224x224 with the same strategy as in TM2:
    # resizing the image to be at least 224x224 and then cropping from the center
    size = (224, 224)
    image = ImageOps.fit(image, size, Image.ANTIALIAS)

    # turn the image into a numpy array
    image_array = np.asarray(image)
    # display the resized image
    #image.show()
    # Normalize the image
    normalized_image_array = (image_array.astype(np.float32) / 127.0) - 1

    # Load the image into the array
    data[0] = normalized_image_array

    # run the inference
    prediction = model.predict(data)
    print("output")
    print(prediction)
    dito = {0: "5", 1: "2", 2: "3", 3: "4", 4: "1", 5: "fist"}
    l = -1
    indexfind = max(prediction[0])
    for i in  prediction[0]:
        l=l+1
        if indexfind == i:
            break
    pred.append(dito[l])
    print("output is :=> ", dito[l])
c=10
f=0
img=cv2.VideoCapture(0)
hand_roi=-1
hand_xml=cv2.CascadeClassifier('D:/Device-Control-Using-OpenCV-and-ML/Device-Control-Using-OpenCV-and-ML/opencv/full_hand_gesture.xml')
while True:
    rt,frame=img.read()
    cv2.imwrite("obc.jpg",frame)
    image_prediction("obc.jpg")
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    palm = hand_xml.detectMultiScale(gray, 1.1, 4)
    #frame=cv2.cvtColor(frame,cv2.COLOR_RGBA2GRAY) #cv2.COLOR_RGB2BGR working well
    for (x,y,w,h) in palm:
        cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
        roi_gray=gray[y:y+h,x:x+w]
        roi_color=frame[y:y+w,x:x+w]
        hand_palm= hand_xml.detectMultiScale(roi_gray)
        if len(hand_palm)==0:
            #c=3
            print("No hand detected")
        else:
            for (ex,ey,ew,eh) in hand_palm:
                hand_roi=roi_color[ey:ey+eh,ex:ex+ew]# gray,frame
                # #c=3
                # #if c==5:
                #     #pag.hotkey('win','1') # pyautogui test
                #  #   print("chrome command executed")
                #    # chromedir= 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s'
                #     #webbrowser.get(chromedir).open("https://github.com/DR-NEGATIVE")
                # if c%3==0:
                #     #c=10
                #     c=1
                #     print("Second command execution")
                #     #pag.hotkey('win','down','down','down','down')
                #     #pag.press('right')  # for ppt
                #     #pag.press('space')

    cv2.imshow("Gesture Detection ",frame)# gray,frame
    cv2.imshow("crop_part",hand_roi)
    if cv2.waitKey(25) & 0xFF == ord('q') or len(pred)>6:

        break

#img.realese()
cv2.destroyAllWindows()
one=0
two=0
five=0
for i in pred:
    if i==1:
        one+=1
    elif i==2:
        two+=1
    else:
        five+=1
if one>two and one>five:
    from opencv.Aircanvas import paintcv
    paintcv.Aircanva()
elif two>one and two>five:
    pass
else:
    from opencv.BrowserOption import controller
    controller.browser_control()


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

#
# # Week 3: Exploring Overfitting in NLP
#
# Welcome to this assignment! During this week you saw different ways to handle sequence-like data. You saw how some Keras' layers such as `GRU`, `Conv` and `LSTM` can be used to tackle problems in this space. Now you will put this knowledge into practice by creating a model architecture that does not overfit.
#
# For this assignment you will be using a variation of the [Sentiment140 dataset](http://help.sentiment140.com/home), which contains 1.6 million tweets alongside their respective sentiment (0 for negative and 4 for positive).
#
# You will also need to create the helper functions very similar to the ones you coded in previous assignments pre-process data and to tokenize sentences. However the objective of the assignment is to find a model architecture that will not overfit.
#
# Let's get started!

# In[1]:

import csv
import random
import pickle
import numpy as np
import tensorflow as tf
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
import matplotlib.pyplot as plt
from scipy.stats import linregress

# ## Defining some useful global variables
#
# Next you will define some global variables that will be used throughout the assignment.
#
# - `EMBEDDING_DIM`: Dimension of the dense embedding, will be used in the embedding layer of the model. Defaults to 100.
#
#
# - `MAXLEN`: Maximum length of all sequences. Defaults to 16.
#
#
# - `TRUNCATING`: Truncating strategy (truncate either before or after each sequence.). Defaults to 'post'.
#
#
# - `PADDING`: Padding strategy (pad either before or after each sequence.). Defaults to 'post'.
#
#
# - `OOV_TOKEN`: Token to replace out-of-vocabulary words during text_to_sequence calls. Defaults to \"\\<OOV>\".
#
#
# - `MAX_EXAMPLES`: Max number of examples to use. Defaults to 160000 (10% of the original number of examples)
#
#
# - `TRAINING_SPLIT`: Proportion of data used for training. Defaults to 0.9
#
#
# **For now leave them unchanged but after submitting your assignment for grading you are encouraged to come back here and play with these parameters to see the impact they have in the classification process.**

# In[2]:

EMBEDDING_DIM = 100
MAXLEN = 16
TRUNCATING = 'post'
PADDING = 'post'
OOV_TOKEN = "<OOV>"
MAX_EXAMPLES = 160000
TRAINING_SPLIT = 0.9

# ## Explore the dataset
#
# The dataset is provided in a csv file.
#
# Each row of this file contains the following values separated by commas:
#
# - target: the polarity of the tweet (0 = negative, 4 = positive)
#
# - ids: The id of the tweet
#
# - date: the date of the tweet
#
# - flag: The query. If there is no query, then this value is NO_QUERY.
#
# - user: the user that tweeted
#
# - text: the text of the tweet
#
#
# Take a look at the first two examples:

# In[3]:

SENTIMENT_CSV = "./data/training_cleaned.csv"

with open(SENTIMENT_CSV, 'r') as csvfile:
    print(f"First data point looks like this:\n\n{csvfile.readline()}")
    print(f"Second data point looks like this:\n\n{csvfile.readline()}")

# **Notice that this file does not have a header so you won't need to skip the first row when parsing the file.**
#
# For the task at hand you will only need the information of the target and the text, which are the first and last element of each row.

# ## Parsing the raw data
#
# Now you need to read the data from the csv file. To do so, complete the `parse_data_from_file` function.
#
# A couple of things to note:
#
# - You should NOT omit the first line as the file does not contain headers.
# - There is no need to save the data points as numpy arrays, regular lists is fine.
# - To read from csv files use `csv.reader` by passing the appropriate arguments.
# - `csv.reader` returns an iterable that returns each row in every iteration. So the label can be accessed via `row[0]` and the text via `row[5]`.
# - The labels are originally encoded as strings ('0' representing negative and '4' representing positive). **You need to change this so that the labels are integers and 0 is used for representing negative, while 1 should represent positive.**
#

# In[4]:

def parse_data_from_file(filename):
    """
    Extracts sentences and labels from a CSV file

    Args:
        filename (string): path to the CSV file

    Returns:
        sentences, labels (list of string, list of string): tuple containing lists of sentences and labels
    """

    sentences = []
    labels = []

    with open(filename, 'r') as csvfile:
        ### START CODE HERE
        reader = csv.reader(csvfile, delimiter=',')

        for row in reader:
            sentences.append(row[5])

            this_label= row[0] #mynote1: define new this_lable to classify label='0' or '4'
            if this_label=='0':
                labels.append(0)
            else:
                labels.append(1)

        ### END CODE HERE

    return sentences, labels

# In[5]:

# Test your function
sentences, labels = parse_data_from_file(SENTIMENT_CSV)

print(f"dataset contains {len(sentences)} examples\n")

print(f"Text of second example should look like this:\n{sentences[1]}\n")
print(f"Text of fourth example should look like this:\n{sentences[3]}")

print(f"\nLabels of last 5 examples should look like this:\n{labels[-5:]}")

# ***Expected Output:***
#
# ```
# dataset contains 1600000 examples
#
# Text of second example should look like this:
# is upset that he can't update his Facebook by texting it... and might cry as a result  School today also. Blah!
#
# Text of fourth example should look like this:
# my whole body feels itchy and like its on fire
#
# Labels of last 5 examples should look like this:
# [1, 1, 1, 1, 1]
#
# ```

# You might have noticed that this dataset contains a lot of examples. In order to keep a low execution time of this assignment you will be using only 10% of the original data. The next cell does this while also randomnizing the datapoints that will be used:

# In[6]:

# Bundle the two lists into a single one
sentences_and_labels = list(zip(sentences, labels))

# Perform random sampling
random.seed(42)
sentences_and_labels = random.sample(sentences_and_labels, MAX_EXAMPLES)

# Unpack back into separate lists
sentences, labels = zip(*sentences_and_labels)

print(f"There are {len(sentences)} sentences and {len(labels)} labels after random sampling\n")

# ***Expected Output:***
#
# ```
# There are 160000 sentences and 160000 labels after random sampling
#
# ```

# ## Training - Validation Split
#
# Now you will code the `train_val_split`, which given the list of sentences, the list of labels and the proportion of data for the training set, should return the training and validation sentences and labels:

# In[7]:

def train_val_split(sentences, labels, training_split):
    """
    Splits the dataset into training and validation sets

    Args:
        sentences (list of string): lower-cased sentences without stopwords
        labels (list of string): list of labels
        training split (float): proportion of the dataset to convert to include in the train set

    Returns:
        train_sentences, validation_sentences, train_labels, validation_labels - lists containing the data splits
    """
    ### START CODE HERE

    # Compute the number of sentences that will be used for training (should be an integer)
    train_size = int(training_split*len(sentences))

    # Split the sentences and labels into train/validation splits
    train_sentences = sentences[0:train_size]
    train_labels = labels[0:train_size]

    validation_sentences = sentences[train_size:]
    validation_labels = labels[train_size:]

    ### END CODE HERE

    return train_sentences, validation_sentences, train_labels, validation_labels

# In[8]:

# Test your function
train_sentences, val_sentences, train_labels, val_labels = train_val_split(sentences, labels, TRAINING_SPLIT)

print(f"There are {len(train_sentences)} sentences for training.\n")
print(f"There are {len(train_labels)} labels for training.\n")
print(f"There are {len(val_sentences)} sentences for validation.\n")
print(f"There are {len(val_labels)} labels for validation.")

# ***Expected Output:***
#
# ```
# There are 144000 sentences for training.
#
# There are 144000 labels for training.
#
# There are 16000 sentences for validation.
#
# There are 16000 labels for validation.
#
# ```

# ## Tokenization - Sequences, truncating and padding
#
# Now that you have sets for training and validation it is time for you to begin the tokenization process.
#
# Begin by completing the `fit_tokenizer` function below. This function should return a [Tokenizer](https://www.tensorflow.org/api_docs/python/tf/keras/preprocessing/text/Tokenizer) that has been fitted to the training sentences.

# In[9]:

def fit_tokenizer(train_sentences, oov_token):
    """
    Instantiates the Tokenizer class on the training sentences

    Args:
        train_sentences (list of string): lower-cased sentences without stopwords to be used for training
        oov_token (string) - symbol for the out-of-vocabulary token

    Returns:
        tokenizer (object): an instance of the Tokenizer class containing the word-index dictionary
    """
    ### START CODE HERE

    # Instantiate the Tokenizer class, passing in the correct value for oov_token
    tokenizer = Tokenizer(oov_token=OOV_TOKEN)

    # Fit the tokenizer to the training sentences
    tokenizer.fit_on_texts(train_sentences)

    ### END CODE HERE

    return tokenizer

# In[10]:

# Test your function
tokenizer = fit_tokenizer(train_sentences, OOV_TOKEN)

word_index = tokenizer.word_index
VOCAB_SIZE = len(word_index)

print(f"Vocabulary contains {VOCAB_SIZE} words\n")
print("<OOV> token included in vocabulary" if "<OOV>" in word_index else "<OOV> token NOT included in vocabulary")
print(f"\nindex of word 'i' should be {word_index['i']}")

# ***Expected Output:***
#
# ```
# Vocabulary contains 128293 words
#
# <OOV> token included in vocabulary
#
# index of word 'i' should be 2
#
# ```

# In[11]:

def seq_pad_and_trunc(sentences, tokenizer, padding, truncating, maxlen):
    """
    Generates an array of token sequences and pads them to the same length

    Args:
        sentences (list of string): list of sentences to tokenize and pad
        tokenizer (object): Tokenizer instance containing the word-index dictionary
        padding (string): type of padding to use
        truncating (string): type of truncating to use
        maxlen (int): maximum length of the token sequence

    Returns:
        pad_trunc_sequences (array of int): tokenized sentences padded to the same length
    """
    ### START CODE HERE

    # Convert sentences to sequences
    sequences = tokenizer.texts_to_sequences(sentences)

    # Pad the sequences using the correct padding, truncating and maxlen
    pad_trunc_sequences = pad_sequences(sequences, padding = PADDING, truncating = TRUNCATING, maxlen = MAXLEN)

    ### END CODE HERE

    return pad_trunc_sequences

# In[12]:

# Test your function
train_pad_trunc_seq = seq_pad_and_trunc(train_sentences, tokenizer, PADDING, TRUNCATING, MAXLEN)
val_pad_trunc_seq = seq_pad_and_trunc(val_sentences, tokenizer, PADDING, TRUNCATING, MAXLEN)

print(f"Padded and truncated training sequences have shape: {train_pad_trunc_seq.shape}\n")
print(f"Padded and truncated validation sequences have shape: {val_pad_trunc_seq.shape}")

# ***Expected Output:***
#
# ```
# Padded and truncated training sequences have shape: (144000, 16)
#
# Padded and truncated validation sequences have shape: (16000, 16)
#
# ```

# Remember that the `pad_sequences` function returns numpy arrays, so your training and validation sequences are already in this format.
#
# However the labels are still Python lists. Before going forward you should convert them numpy arrays as well. You can do this by running the following cell:

# In[13]:

train_labels = np.array(train_labels)
val_labels = np.array(val_labels)

# # Using pre-defined Embeddings
#
# This time you will not be learning embeddings from your data but you will be using pre-trained word vectors.
#
# In particular you will be using the 100 dimension version of [GloVe](https://nlp.stanford.edu/projects/glove/) from Stanford.

# In[14]:

# Define path to file containing the embeddings
GLOVE_FILE = './data/glove.6B.100d.txt'

# Initialize an empty embeddings index dictionary
GLOVE_EMBEDDINGS = {}

# Read file and fill GLOVE_EMBEDDINGS with its contents
with open(GLOVE_FILE) as f:
    for line in f:
        values = line.split()
        word = values[0]
        coefs = np.asarray(values[1:], dtype='float32')
        GLOVE_EMBEDDINGS[word] = coefs

# Now you have access to GloVe's pre-trained word vectors. Isn't that cool?
#
# Let's take a look at the vector for the word **dog**:

# In[15]:

test_word = 'dog'

test_vector = GLOVE_EMBEDDINGS[test_word]

print(f"Vector representation of word {test_word} looks like this:\n\n{test_vector}")

# Feel free to change the `test_word` to see the vector representation of any word you can think of.
#
# Also, notice that the dimension of each vector is 100. You can easily double check this by running the following cell:

# In[16]:

print(f"Each word vector has shape: {test_vector.shape}")

# ## Represent the words in your vocabulary using the embeddings
#
# Save the vector representation of each word in the vocabulary in a numpy array.
#
# A couple of things to notice:
# - If a word in your vocabulary is not present in `GLOVE_EMBEDDINGS` the representation for that word is left as a column of zeros.
# - `word_index` starts counting at 1, because of this you will need to add an extra column at the left-most side of the `EMBEDDINGS_MATRIX` array. This is the reason why you add 1 to `VOCAB_SIZE` in the cell below:

# In[17]:

# Initialize an empty numpy array with the appropriate size
EMBEDDINGS_MATRIX = np.zeros((VOCAB_SIZE+1, EMBEDDING_DIM))

# Iterate all of the words in the vocabulary and if the vector representation for
# each word exists within GloVe's representations, save it in the EMBEDDINGS_MATRIX array
for word, i in word_index.items():
    embedding_vector = GLOVE_EMBEDDINGS.get(word)
    if embedding_vector is not None:
        EMBEDDINGS_MATRIX[i] = embedding_vector

# Now you have the pre-trained embeddings ready to use!

# ## Define a model that does not overfit
#
# Now you need to define a model that will handle the problem at hand while not overfitting.
#
# A couple of things to note / hints:
#
# - The first layer is provided so you can see how the Embedding layer is configured when using pre-trained embeddings
#
#
# - You can try different combinations of layers covered in previous ungraded labs such as:
#     - `Conv1D`
#     - `Dropout`
#     - `GlobalMaxPooling1D`
#     - `MaxPooling1D`
#     - `LSTM`
#     - `Bidirectional(LSTM)`
#
#
# - The last two layers should be `Dense` layers.
#
#
# - There multiple ways of solving this problem. So try an architecture that you think will not overfit.
#
#
# - Try simpler architectures first to avoid long training times. Architectures that are able to solve this problem usually have around 3-4 layers (excluding the last two `Dense` ones)
#
#
# - Include at least one `Dropout` layer to mitigate overfitting.

# In[18]:

# GRADED FUNCTION: create_model
def create_model(vocab_size, embedding_dim, maxlen, embeddings_matrix):
    """
    Creates a binary sentiment classifier model

    Args:
        vocab_size (int): size of the vocabulary for the Embedding layer input
        embedding_dim (int): dimensionality of the Embedding layer output
        maxlen (int): length of the input sequences
        embeddings_matrix (array): predefined weights of the embeddings

    Returns:
        model (tf.keras Model): the sentiment classifier model
    """
    ### START CODE HERE

    model = tf.keras.Sequential([
        # This is how you need to set the Embedding layer when using pre-trained embeddings
        tf.keras.layers.Embedding(vocab_size+1, embedding_dim, input_length=maxlen, weights=[embeddings_matrix], trainable=False),
        tf.keras.layers.Dropout(0.2),
        tf.keras.layers.Conv1D(64, 5, activation = 'relu'),
        tf.keras.layers.MaxPooling1D(pool_size = 4),
        tf.keras.layers.LSTM(64),
        tf.keras.layers.Dense(1, activation = 'sigmoid')
    ])

    model.compile(loss='binary_crossentropy',
                  optimizer='adam',
                  metrics=['accuracy'])

    ### END CODE HERE

    return model

# In[19]:

# Create your untrained model
model = create_model(VOCAB_SIZE, EMBEDDING_DIM, MAXLEN, EMBEDDINGS_MATRIX)

# Train the model and save the training history
history = model.fit(train_pad_trunc_seq, train_labels, epochs=20, validation_data=(val_pad_trunc_seq, val_labels))

# **To pass this assignment your `val_loss` (validation loss) should either be flat or decreasing.**
#
# Although a flat `val_loss` and a lowering `train_loss` (or just `loss`) also indicate some overfitting what you really want to avoid is having a lowering `train_loss` and an increasing `val_loss`.
#
# With this in mind, the following three curves will be acceptable solutions:

#

# While the following would not be able to pass the grading:

#

# Run the following cell to check your loss curves:

# In[20]:

#-----------------------------------------------------------
# Retrieve a list of list results on training and test data
# sets for each training epoch
#-----------------------------------------------------------
loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = [*range(20)]

#------------------------------------------------
# Plot training and validation loss per epoch
#------------------------------------------------
plt.plot(epochs, loss, 'r')
plt.plot(epochs, val_loss, 'b')
plt.title('Training and validation loss')
plt.xlabel("Epochs")
plt.ylabel("Loss")
plt.legend(["Loss", "Validation Loss"])
plt.show()

# If you wish so, you can also check the training and validation accuracies of your model:

# In[21]:

acc = history.history['accuracy']
val_acc = history.history['val_accuracy']

#------------------------------------------------
# Plot training and validation accuracy per epoch
#------------------------------------------------
plt.plot(epochs, acc, 'r')
plt.plot(epochs, val_acc, 'b')
plt.title('Training and validation accuracy')
plt.xlabel("Epochs")
plt.ylabel("Accuracy")
plt.legend(["Accuracy", "Validation Accuracy"])
plt.show()

# A more rigorous way of setting the passing threshold of this assignment is to use the slope of your `val_loss` curve.
#
# **To pass this assignment the slope of your `val_loss` curve should be 0.0005 at maximum.**

# In[22]:

# Test the slope of your val_loss curve
slope, *_ = linregress(epochs, val_loss)
print(f"The slope of your validation loss curve is {slope:.5f}")

# **If your model generated a validation loss curve that meets the criteria above, run the following cell and then submit your assignment for grading. Otherwise, try with a different architecture.**

# In[23]:

with open('history.pkl', 'wb') as f:
    pickle.dump(history.history, f)

# **Congratulations on finishing this week's assignment!**
#
# You have successfully implemented a neural network capable of classifying sentiment in text data while doing a fairly good job of not overfitting! Nice job!
#
# **Keep it up!**


# -*- coding: utf-8 -*-
"""
Created on Wed Sep 25 23:54:23 2019
@author: themr
"""
# import math
# import os
# import numpy as np
# import talib as tl
# import json
# from datetime import datetime
# import matplotlib.pyplot as plt
# import csv
# import traceback
# import datetime as dt
# import matplotlib.dates as mdates
import pandas as pd
#import pandas_datareader as web
#from mpl_finance import candlestick_ohlc

result=pd.DataFrame([["1","2","3","4"]], columns=["prezzo acquisto", "prezzo vendita", "data acquisto", "data vendita"])
row={"prezzo acquisto":"123",  "prezzo vendita":"245",  "data acquisto":"ieri", "data vendita":"oggi"}
result=result.append(row, ignore_index=True)
print(result)

result.to_csv("result.csv")

capital=1000   #euro
amount=capital*0.1
risk=0.02
target=5        #%
stop=3          #%
maker_fee=0.13  #%
taker_fee=0.26  #%

def openFile(file):
    filename=file
    trade_file=pd.read_csv(filename, sep=",", header=1, names=["timestamp", "price", "volume"])
    trade_file.head(n=5)
    rows_n=len(trade_file.index)
    print(rows_n)

def makerLimits(amount, price, risk, maker_fee):
    target_risk=risk+0.01
    target_price=price*(1+target_risk-maker_fee)
    stop_price=price-(price*risk-taker_fee)

    result=pd.DataFrame(columns=["prezzo acquisto", "prezzo vendita", "data acquisto", "data vendita"])
    result=result.append("123", "245", "ieri", "oggi")
    result.to_csv("result.csv")

    return target_price, stop_price


"Watch the image processing container, once it is done move the data back to swift storage"

from kubernetes import client, config, watch
from put_data import put_data_back
import os

# Keep track of PR https://github.com/kubernetes-client/python-base/pull/36
# it is implementing watching forever and reconnecting if the connection is lost
# If the PR doesn't get in soon enough, need to figure out how to do that here

def main():
    kubecfg_path = os.environ.get('KUBECFG_PATH')
    if kubecfg_path is None:
        config.load_kube_config()
    else:
        config.load_kube_config(config_file=kubecfg_path)
    v1_client = client.CoreV1Api()
    resrc_version = None
    namespace = os.getenv("OPENSHIFTMGR_PROJECT", "myproject")
    w = watch.Watch()

    while True:
        if resrc_version is None:
            stream = w.stream(v1_client.list_namespaced_pod, namespace)
        else:
            stream = w.stream(v1_client.list_namespaced_pod, namespace, resource_version=resrc_version)
        for event in stream:
            resrc_version = event['raw_object']['metadata']['resourceVersion']
            if 'containerStatuses' in event['raw_object']['status']:
                for status in event['raw_object']['status']['containerStatuses']:
                    if status['name'] != 'publish' and 'terminated' in status['state']:
                        w.stop()
                        # It is possible for the image processing container to error out
                        # when that happens, the reason will be "Error" and this will return false
                        return status['state']['terminated']['reason'] == 'Completed'

if __name__ == '__main__':
    if main():
        put_data_back()
    else:
        print("Image processing container failed to complete")


import staticjinja
import os
import json
import yaml
import sys
from slugify import slugify
from dateutil.parser import parse

# We define constants for the deployment.
cwd = os.getcwd()
searchpath  = os.path.join(cwd, "templates")
outputpath  = os.path.join(cwd, "site")

# We load the data we want to use in the templates.
#BADGES    = yaml.load(open('data/badges.yaml'))

SECTOR_MAPPING = { 'Industry Professional': 'com',
	'Graduate Student': 'grad',
	'High School Student': 'highschool',
	'Undergraduate Student': 'undergrad',}

def getSector(str):
	if str in SECTOR_MAPPING:
		return SECTOR_MAPPING[str]
	else:
		return ''

import csv

BADGES = []
with open('/Users/sahuguet/Downloads/WiTNY Build-a-Thon Participants.csv', 'rb') as csvfile:
	reader = csv.reader(csvfile)
	for row in reader:
		print(len(row))
		(timestamp, fname,	lname,	category, email, grade_level,
		xp_python, xp_APIs, xp_JavaScript, xp_nodejs, xp_HTML, xp_CPP, xp_pitching, xp_project_m, xp_engineering,
		extra_info, skip, focus, employer, laptop,
		ugrad_vs_grad, which_cuny, major, ct_program, tshirt_size, dietary_restrictions, school, cs) = row
		#(ts, fname, lname, category,
		#email, school, grade_level, cs_class, undergrad_vs_grad,
		#which_cuny, cuny_major, ct_programm, professional_focus, company,
		#python_expertise, javascript_expertise, html_expertise, cpp_expertise, nodejs_expertise, api,
		#ability_pitch, ability_project_management, ability_eng,
		#will_bring_laptop, diet, t_shirt, extra_experience, one_more) = row
		BADGES.append( { 'fname': fname,
			'lname': lname,
			'org': employer,
			'cuny': which_cuny,
			'employer': employer + school + which_cuny,
			'job': '',
			'title': 'no title',
			'sector': getSector(category),})

BADGES = sorted(BADGES, key=lambda x:x['lname'])

def loadAcademyData():
	return { 'badges': BADGES,
			 'resources': None }

site = staticjinja.make_site(
	searchpath=searchpath,
	outpath=outputpath,
	staticpaths=['static', '../data'],
	contexts=[(r'.*.html', loadAcademyData),]
	)
site.render(use_reloader=True)


import torch
import torch.nn as nn
import torch.nn.init as init

class MaskedMultiHeadAttention(nn.Module):
    def __init__(self, hidden_size, n_ctx, config):
        super(MaskedMultiHeadAttention, self).__init__()
        self.n_head = config.n_head
        assert hidden_size % self.n_head == 0

        self.query = nn.Linear(hidden_size, hidden_size)
        self.key = nn.Linear(hidden_size, hidden_size)
        self.value = nn.Linear(hidden_size, hidden_size)
        self.linear = nn.Linear(hidden_size, hidden_size)

        self.attn_dropout = nn.Dropout(config.attn_pdrop)
        self.resid_dropout = nn.Dropout(config.resid_pdrop)

        # (1, 1, 1024, 1024)
        self.masked = torch.tril(torch.ones(n_ctx, n_ctx).view(1, 1, n_ctx, n_ctx))
        self.masked_bias = torch.tensor(-1e4)

    def split_heads(self, x, k=False):
        # size is (batch_size, seq_len, num_head, head_features)
        new_x_shape = x.size()[:-1] + (self.n_head, x.size(-1) // self.n_head)
        x = x.view(*new_x_shape)

        # key is transpose
        if k:
            # (batch_size, num_head, head_features, seq_len)
            return x.permute(0, 2, 3, 1)
        else:
            # (batch_size, num_head, seq_len, head_features)
            return x.permute(0, 2, 1, 3)

    @staticmethod
    def merge_heads(x):
        x = x.permute(0, 2, 1, 3).contiguous()
        new_x_shape = x.size()[:-2] + (x.size(-2) * x.size(-1),)
        return x.view(*new_x_shape)

    def forward(self, hidden_states, layer_past=None, attention_mask=None):
        query = self.query(hidden_states)
        key = self.key(hidden_states)
        value = self.value(hidden_states)

        query = self.split_heads(query)
        key = self.split_heads(key, k=True)
        value = self.split_heads(value)

        if layer_past is not None:
            past_key, past_value = layer_past[0].transpose(-2, -1), layer_past[1]
            # (batch_size, num_head, head_features, sql_len+1)
            key = torch.cat((past_key, key), dim=-1)
            # (batch_size, num_head, sql_len+1, head_features)
            value = torch.cat((past_value, value), dim=-2)
        present = torch.stack((key.transpose(-2, -1), value))

        '''
        for first iteration: the query、key、value seq_len is seq_len

        for second or others iteration: the query、key、value seq_len is 1
        # query: (batch_size, num_head, 1, head_features)
        # key: (batch_size, num_head, head_features, sql_len+1)
        # value: (batch_size, num_head, sql_len+1, head_features)
        # w: (batch_size, num_head, 1, sql_len+1)
        '''
        w = torch.matmul(query, key)
        w = w / (float(value.size(-1)) ** 0.5)

        # masked
        nd, ns = w.size(-2), w.size(-1)
        mask = self.masked[:, :, ns - nd: ns, :ns]
        w = torch.where(mask.bool(), w, self.masked_bias.to(w.dtype))

        # process attention mask
        if attention_mask is not None:
            w = w + attention_mask

        w = nn.Softmax(dim=-1)(w)
        w = self.attn_dropout(w)

        # attention_output: (batch_size, num_head, sql_len, head_features)
        attention_output = torch.matmul(w, value)
        attention_output = self.merge_heads(attention_output)
        attention_output = self.linear(attention_output)
        attention_output = self.resid_dropout(attention_output)

        return attention_output, present

class MLP(nn.Module):
    def __init__(self, inner_dim, config):
        super(MLP, self).__init__()
        self.linear_1 = nn.Linear(config.n_embd, inner_dim)
        self.linear_2 = nn.Linear(inner_dim, config.n_embd)
        self.gelu = nn.GELU()

        nn.init.normal_(self.linear_1.weight, std=0.02)
        nn.init.normal_(self.linear_2.weight, std=0.02)

    def forward(self, inputs):
        outputs = self.gelu(self.linear_1(inputs))
        outputs = self.linear_2(outputs)
        return outputs

class Block(nn.Module):
    def __init__(self, n_ctx, config):
        super(Block, self).__init__()
        hidden_size = config.n_embd
        inner_dim = config.n_inner if config.n_inner is not None else 4 * hidden_size

        self.layer_norm_1 = nn.LayerNorm(hidden_size, config.layer_norm_epsilon)
        self.attention = MaskedMultiHeadAttention(hidden_size, n_ctx, config)
        self.layer_norm_2 = nn.LayerNorm(hidden_size, config.layer_norm_epsilon)
        self.mlp = MLP(inner_dim, config)

    def forward(self, hidden_states, layer_past=None, attention_mask=None):
        # first: Masked Multi Head Self Attention
        hidden_states = self.layer_norm_1(hidden_states)
        attention_output, present = self.attention(hidden_states,
                                                   layer_past=layer_past,
                                                   attention_mask=attention_mask)
        hidden_states = hidden_states + attention_output

        # second: MLP layer
        hidden_states = self.layer_norm_2(hidden_states)
        mlp_out = self.mlp(hidden_states)
        hidden_states = hidden_states + mlp_out

        return hidden_states, present

class GPT2Model(nn.Module):
    def __init__(self, config):
        super(GPT2Model, self).__init__()
        # initialize word embedding and position embedding
        self.word_embedding = nn.Embedding(config.vocab_size, config.n_embd)
        init.normal_(self.word_embedding.weight, std=0.02)
        self.position_embedding = nn.Embedding(config.n_positions, config.n_embd)
        init.normal_(self.position_embedding.weight, std=0.01)
        self.drop_out = nn.Dropout(config.embd_pdrop)

        # transformer decoder block
        self.blocks = nn.ModuleList([Block(config.n_ctx, config) for _ in range(config.n_layer)])
        self.layer_norm = nn.LayerNorm(config.n_embd, eps=config.layer_norm_epsilon)

    def forward(self, input_ids, attention_mask=None, position_ids=None, past_key_values=None):
        if input_ids is not None:
            input_shape = input_ids.size()
            input_ids = input_ids.view(-1, input_shape[-1])
            batch_size = input_ids.shape[0]
        else:
            raise ValueError("input_ids is None")

        if past_key_values is None:
            past_length = 0
            past_key_values = [None] * len(self.blocks)
        else:
            past_length = past_key_values[0][0].size(-2)

        if position_ids is None:
            device = input_ids.device
            position_ids = torch.arange(past_length, input_shape[-1] + past_length, dtype=torch.long, device=device)
            position_ids = position_ids.unsqueeze(0).view(-1, input_shape[-1])

        if attention_mask is not None:
            assert batch_size > 0, "batch_size has to be defined and > 0"
            attention_mask = attention_mask.view(batch_size, -1)
            attention_mask = attention_mask[:, None, None, :]
            attention_mask = (1.0 - attention_mask) * -10000.0

        # embedding layer
        word_embeds = self.word_embedding(input_ids)
        position_embeds = self.position_embedding(position_ids)
        hidden_states = word_embeds + position_embeds
        hidden_states = self.drop_out(hidden_states)

        # transformer block layer
        presents = []
        for i, (block, layer_past) in enumerate(zip(self.blocks, past_key_values)):
            hidden_states, present = block(
                hidden_states,
                layer_past=layer_past,
                attention_mask=attention_mask
            )
            presents.append(present)

        hidden_states = self.layer_norm(hidden_states)
        output_shape = input_shape + (hidden_states.size(-1),)
        return {
            'hidden_states': hidden_states.view(*output_shape),
            'past_key_values': presents
        }

class GPT2LMHeadModel(nn.Module):
    def __init__(self, config):
        super(GPT2LMHeadModel, self).__init__()
        self.gpt = GPT2Model(config)
        self.lm_head = nn.Linear(config.n_embd, config.vocab_size, bias=False)

    def forward(self,
                input_ids,
                attention_mask=None,
                position_ids=None,
                past_key_values=None,
                lm_labels=None):
        hidden_states, presents = self.gpt(
            input_ids,
            attention_mask=attention_mask,
            position_ids=position_ids,
            past_key_values=past_key_values)

        lm_logits = self.lm_head(hidden_states)

        if lm_labels is not None:
            shift_logits = lm_logits[..., :-1, :].contiguous()
            shift_labels = lm_labels[..., 1:].contiguous()
            loss_fct = nn.CrossEntropyLoss()
            loss = loss_fct(shift_logits.view(-1, shift_logits.size(-1)), shift_labels.view(-1))
            return loss, lm_logits, presents
        return {
            'logits': lm_logits,
            'past_key_values': presents
        }


import time as tt
t0=tt.time()
dats=[['google','amazon',],['amazon','google','python','cse'],['cse','google'],['amazon','python'],
      ['cse','amazon','python','google'],['amazon','google','cse','data',]]
sf=[]
from itertools import combinations
import pandas as pd
def pruned(it,k,l):
    subs=combinations(sorted(it),k)
    for itm in subs:
        if itm not in l:
            return False
    return True
def apriori_gen(c,data,minsp,k,l):
    C=[]
    for i in range(0,len(c)):
        itm=[]
        for j in range(i+1,len(c)):
            if c[i][0:(k-1)]==c[j][0:(k-1)]:
                if type(c[i][0:(k-1)])!=tuple:
                    itm=(c[i][0:(k-1)])+(c[i][(k-1)])+(c[j][(k-1)])
                else:
                    itm=c[i][0:(k-1)]+(c[i][(k-1)],)+(c[j][(k-1)],)
                itm=tuple(sorted(itm))
            if pruned(itm,k,l)!=False and itm not in C:
                C.append(itm)

    return C
def apriori(data,minsp):
    global sf
    kdc={}
    fi,sfi=[],[]
    for dat in data:
        for i in range(0,len(dat)):
            if dat[i] not in kdc:
                kdc[dat[i]]=1
            elif dat[i] in dat[0:i]:
                continue
            else:
                kdc[dat[i]]+=1
    for k,v in kdc.items():
                if v>=minsp:
                    fi.append((k,v))
                    sfi.append(k)
    sfi=sorted(sfi)
    sf=fi
    for i in range(len(data)):
        data[i]=tuple(set(sfi).intersection(set(data[i])))
    k=2
    l=[]
    c=[]
    c=combinations(sfi,2)
    for it in c:
        l.append(it)
    c=l
    dic={}
    while len(l)!=0:
        if k>2:
            c=apriori_gen(l,dats,minsp,k-1,l)
        for it in data:
            sub=combinations(it,k)
            subs=[]
            for itms in sub:
                subs.append(tuple(sorted(itms)))
            for itm in c:
                itm=tuple(sorted(itm))
                if itm in subs:
                    #print(itm,"----",subs)
                    if itm not in dic:
                        dic[itm]=1
                    else:
                        dic[itm]+=1
        l=[]
        for key,v in dic.items():
            if v>=minsp:
                fi.append((key,v))
                l.append(key)
        dic={}
        k=k+1
    freq=fi
    data=pd.DataFrame(columns=["items","support"])
    its=[]
    sps=[]
    for i in range(0,len(freq)):
        its.append(str(freq[i][0]))
        sps.append(freq[i][1])
    data["items"]=its
    data["support"]=sps
    return data
import requests as rq
res=rq.get(r"https://raw.githubusercontent.com/stedy/Machine-Learning-with-R-datasets/master/groceries.csv")
datass=[]
for it in res.iter_lines(1000000):
    li=[]
    for itm in it.split():
        li.append(itm)
    datass.append(li)
dii=datass[0:100]
print(apriori(dats,2).sort_values(ascending=False,by="support"))


# https://atcoder.jp/contests/abc027/tasks/abc027_a

l = list(map(int, input().split()))
if l[0] == l[1]:
    ans = l[2]
elif l[1] == l[2]:
    ans = l[0]
elif l[2] == l[0]:
    ans = l[1]
print(ans)