import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
from highlight_text import ax_text

def get_rolling_data(team, window, data):

    df_team = data[data['Team'] == team]
    df_team_for = df_team.groupby('Round_ID')['Score', 'xScore'].sum().rename(columns={'Score':"For",
                                                                                "xScore":"xFor"})
    df_opp = data[((data['Home_Team'] == team) | (data['Away_Team'] == team)) & (data['Team'] != team)]
    df_team_agg = df_opp.groupby('Round_ID')['Score', 'xScore'].sum().rename(columns={'Score':"Against",
                                                                                "xScore":"xAgainst"})

    df_rolling = pd.merge(df_team_for, df_team_agg, left_index=True, right_index=True)
    df_rolling['rollingFor'] = df_rolling['For'].rolling(window=window, min_periods=0).mean()
    df_rolling['rollingxFor'] = df_rolling['xFor'].rolling(window=window, min_periods=0).mean()
    df_rolling['rollingAgainst'] = df_rolling['Against'].rolling(window=window, min_periods=0).mean()
    df_rolling['rollingxAgainst'] = df_rolling['xAgainst'].rolling(window=window, min_periods=0).mean()

    df_rolling['rollingDiff'] = df_rolling['rollingFor'] - df_rolling['rollingAgainst']
    df_rolling['rollingxDiff'] = df_rolling['rollingxFor'] - df_rolling['rollingxAgainst']

    # Filling in missing Finals games with previous round (no change)
    finals_2021 = ['2021F1', '2021F2', '2021F3', '2021F4']
    finals_2021_prev = ['202123', '2021F1', '2021F2', '2021F3' ]
    finals_2022 = ['2022F1', '2022F2', '2022F3', '2022F4']
    finals_2022_prev = ['202223', '2022F1', '2022F2', '2022F3']
    for index in range(len(finals_2021)):
        if finals_2021[index] not in df_rolling.index:
            # print(finals_2021[index])
            df_rolling.loc[finals_2021[index]] = df_rolling.loc[finals_2021_prev[index]]

    for index in range(len(finals_2022)):
        if finals_2022[index] not in df_rolling.index:
            # print(finals_2022[index])
            df_rolling.loc[finals_2022[index]] = df_rolling.loc[finals_2022_prev[index]]

    # Filling in 202101 if necessary
    if '202101' not in df_rolling.index:
        df_rolling.loc['202101'] = df_rolling.loc['202102']

    # Relative performance compared to Expected
    df_rolling['rollingForRelative'] = df_rolling['rollingFor'] - df_rolling['rollingxFor']
    df_rolling['rollingAgainstRelative'] = df_rolling['rollingAgainst'] - df_rolling['rollingxAgainst']
    df_rolling['rollingDiffRelative'] = df_rolling['rollingDiff'] - df_rolling['rollingxDiff']

    df_rolling = df_rolling.sort_index()

    return df_rolling

def plot_rolling_average(ax, data, positive_line, negative_line, color_for, color_against):

    x = data.index
    y_for = data[positive_line]
    y_against = data[negative_line]

    ax.set_facecolor("#121212")
    ax.spines[['top', 'right']].set_visible(False)
    ax.spines[["left", "bottom"]].set_color("white")

    line_for = ax.plot(x, y_for, label = positive_line, color = color_for, lw=1.5)
    line_against = ax.plot(x, y_against, label = negative_line, color= color_against, lw=1.5)
    ax.set_ylim(0, 125)
    ax.plot([22, 22], [ax.get_ylim()[0], ax.get_ylim()[1]], ls=":", lw=1.25, color="white", zorder=2)
    ax.plot([25, 25], [ax.get_ylim()[0], ax.get_ylim()[1]], ls=":", lw=1.25, color="white", zorder=2)
    plt.axvspan(22, 25, color=line_for[0].get_color(), alpha=0.3)

    ax.plot([48, 48], [ax.get_ylim()[0], ax.get_ylim()[1]], ls=":", lw=1.25, color="white", zorder=2)
    ax.plot([51, 51], [ax.get_ylim()[0], ax.get_ylim()[1]], ls=":", lw=1.25, color="white", zorder=2)
    plt.axvspan(48, 51, color=line_for[0].get_color(), alpha=0.3)

    ax.fill_between(x, y_against, y_for, where = y_for > y_against, interpolate=True, alpha=0.85, zorder=3, color=line_for[0].get_color())
    ax.fill_between(x, y_against, y_for, where = y_against >= y_for, interpolate=True, alpha=0.85, zorder=3, color=line_against[0].get_color())

    ax.tick_params(color="white", length=5, which="major", labelsize=6, labelcolor="white")
    ax.xaxis.set_major_locator(ticker.MultipleLocator(10))
    ax.yaxis.set_major_locator(ticker.MultipleLocator(10))

    plt.axvspan(0, 10, color="grey", alpha=0.3)

    ax_text(
        x=7, y=20,
        s = "2021",
        color="white"
    )
    ax_text(
        x=35, y=20,
        s = "2022",
        color="white"
    )

    return ax

## Expected Score
def get_expected_rolling_plot(ax, team, data, window=10, color_for="#0057B8", color_against = "#989898"):

    df_rolling = get_rolling_data(team=team, window=window, data = data)

    ax = plot_rolling_average(ax, data=df_rolling, positive_line="rollingxFor", negative_line="rollingxAgainst", color_for = color_for, color_against = color_against)

    for_number = df_rolling['rollingxFor'].iloc[-1]
    against_number = df_rolling['rollingxAgainst'].iloc[-1]
    text_colour_for = "white"
    text_colour_against = "white"
    if color_for == "white":
        text_colour_for = "black"
    if color_against == "white":
        text_colour_against = "black"

    ax_text(
        x=0, y=140,
        s=f'<{team}>\n<xS for: {for_number:.1f}>  <xS against: {against_number:.1f}>',
        highlight_textprops=[
            {'color':'white', 'weight':'bold', 'font':'DM Sans'},
            {'size':'10', 'bbox':{'edgecolor':color_for, 'facecolor':color_for, 'pad':1}, 'color':text_colour_for},
            {'size':'10', 'bbox':{'edgecolor':color_against, 'facecolor':color_against, 'pad':1}, 'color':text_colour_against},
        ],
        font="Karla",
        ha="left",
        size=14,
    )

    return ax

## Actual Scores
def get_actual_rolling_plot(ax, team, data, window=10, color_for="#0057B8", color_against = "#989898"):

    df_rolling = get_rolling_data(team=team, window=window, data = data)

    ax = plot_rolling_average(ax, data=df_rolling, positive_line="rollingFor", negative_line="rollingAgainst", color_for = color_for, color_against = color_against)

    for_number = df_rolling['rollingFor'].iloc[-1]
    against_number = df_rolling['rollingAgainst'].iloc[-1]
    text_colour_for = "white"
    text_colour_against = "white"
    if color_for == "white":
        text_colour_for = "black"
    if color_against == "white":
        text_colour_against = "black"

    ax_text(
        x=0, y=140,
        s=f'<{team}>\n<For: {for_number:.1f}>  <Against: {against_number:.1f}>',
        highlight_textprops=[
            {'color':'white', 'weight':'bold', 'font':'DM Sans'},
            {'size':'10', 'bbox':{'edgecolor':color_for, 'facecolor':color_for, 'pad':1}, 'color':text_colour_for},
            {'size':'10', 'bbox':{'edgecolor':color_against, 'facecolor':color_against, 'pad':1}, 'color':text_colour_against},
        ],
        font="Karla",
        ha="left",
        size=14,
    )

    return ax

# Expected Score Differences
def plot_rolling_difference(ax, data, difference_line, color_for, color_against, reverse=False):

    x = data.index
    y_diff = data[difference_line]
    y_neutral = [0]*len(x)

    ax.set_facecolor("#121212")
    ax.spines[['top', 'right']].set_visible(False)
    ax.spines[["left", "bottom"]].set_color("white")

    line_diff = ax.plot(x, y_diff, label = difference_line, color = color_for, lw=1.5)
    line_neutral = ax.plot(x, y_neutral, color= "white", lw=1.5)
    ax.set_ylim(-20, 20)
    ax.plot([22, 22], [ax.get_ylim()[0], ax.get_ylim()[1]], ls=":", lw=1.25, color="white", zorder=2)
    ax.plot([25, 25], [ax.get_ylim()[0], ax.get_ylim()[1]], ls=":", lw=1.25, color="white", zorder=2)
    plt.axvspan(22, 25, color=line_diff[0].get_color(), alpha=0.3)

    ax.plot([48, 48], [ax.get_ylim()[0], ax.get_ylim()[1]], ls=":", lw=1.25, color="white", zorder=2)
    ax.plot([51, 51], [ax.get_ylim()[0], ax.get_ylim()[1]], ls=":", lw=1.25, color="white", zorder=2)
    plt.axvspan(48, 51, color=line_diff[0].get_color(), alpha=0.3)

    positive_colour = color_for
    negative_colour = "grey"
    if reverse:
        positive_colour = "grey"
        negative_colour = color_for
    ax.fill_between(x, y_neutral, y_diff, where = y_diff > y_neutral, interpolate=True, alpha=0.85, zorder=3, color=positive_colour)
    ax.fill_between(x, y_neutral, y_diff, where = y_neutral >= y_diff, interpolate=True, alpha=0.85, zorder=3, color=negative_colour)

    ax.tick_params(color="white", length=5, which="major", labelsize=6, labelcolor="white")
    ax.xaxis.set_major_locator(ticker.MultipleLocator(10))
    ax.yaxis.set_major_locator(ticker.MultipleLocator(10))

    plt.axvspan(0, 10, color="grey", alpha=0.3)

    ax_text(
        x=7, y=-15,
        s = "2021",
        color="white"
    )
    ax_text(
        x=35, y=-15,
        s = "2022",
        color="white"
    )

def get_difference_rolling_plot(ax, team, data, window=10, color_for="#0057B8", color_against = "#989898", reverse=False):

    df_rolling = get_rolling_data(team=team, window=window, data = data)

    ax = plot_rolling_difference(ax, data=df_rolling, difference_line="rollingDiffRelative", color_for = color_for, color_against = color_against, reverse=reverse)

    diff_number = df_rolling['rollingDiffRelative'].mean()
    text_colour_for = "white"
    # text_colour_against = "white"
    if color_for == "white":
        text_colour_for = "black"
    # if color_against == "white":
        # text_colour_against = "black"

    ax_text(
        x=0, y=23,
        s=f'<{team}>\n<Score Difference Relative to Expected: {diff_number:.1f}>',
        highlight_textprops=[
            {'color':'white', 'weight':'bold', 'font':'DM Sans'},
            {'size':'10', 'bbox':{'edgecolor':color_for, 'facecolor':color_for, 'pad':1}, 'color':text_colour_for},
            # {'size':'10', 'bbox':{'edgecolor':color_against, 'facecolor':color_against, 'pad':1}, 'color':text_colour_against},
        ],
        font="Karla",
        ha="left",
        size=14,
    )

    return ax

def get_for_difference_rolling_plot(ax, team, data, window=10, color_for="#0057B8", color_against = "#989898"):

    df_rolling = get_rolling_data(team=team, window=window, data = data)

    ax = plot_rolling_difference(ax, data=df_rolling, difference_line="rollingForRelative", color_for = color_for, color_against = color_against)

    diff_number = df_rolling['rollingForRelative'].mean()
    text_colour_for = "white"
    # text_colour_against = "white"
    if color_for == "white":
        text_colour_for = "black"
    # if color_against == "white":
        # text_colour_against = "black"

    ax_text(
        x=0, y=23,
        s=f'<{team}>\n<Score For Relative to Expected: {diff_number:.1f}>',
        highlight_textprops=[
            {'color':'white', 'weight':'bold', 'font':'DM Sans'},
            {'size':'10', 'bbox':{'edgecolor':color_for, 'facecolor':color_for, 'pad':1}, 'color':text_colour_for},
            # {'size':'10', 'bbox':{'edgecolor':color_against, 'facecolor':color_against, 'pad':1}, 'color':text_colour_against},
        ],
        font="Karla",
        ha="left",
        size=14,
    )

    return ax

def get_against_difference_rolling_plot(ax, team, data, window=10, color_for="#0057B8", color_against = "#989898"):

    df_rolling = get_rolling_data(team=team, window=window, data = data)

    ax = plot_rolling_difference(ax, data=df_rolling, difference_line="rollingAgainstRelative", color_for = color_for, color_against = color_against, reverse=True)

    diff_number = df_rolling['rollingAgainstRelative'].mean()
    text_colour_for = "white"
    # text_colour_against = "white"
    if color_for == "white":
        text_colour_for = "black"
    # if color_against == "white":
        # text_colour_against = "black"

    ax_text(
        x=0, y=23,
        s=f'<{team}>\n<Score Against Relative to Expected: {diff_number:.1f}>',
        highlight_textprops=[
            {'color':'white', 'weight':'bold', 'font':'DM Sans'},
            {'size':'10', 'bbox':{'edgecolor':color_for, 'facecolor':color_for, 'pad':1}, 'color':text_colour_for},
            # {'size':'10', 'bbox':{'edgecolor':color_against, 'facecolor':color_against, 'pad':1}, 'color':text_colour_against},
        ],
        font="Karla",
        ha="left",
        size=14,
    )

    return ax


import argparse
import tensorflow as tf
import numpy as np
from models.model_builder import ModelBuilder
import cv2
import timeit
import pathlib

parser = argparse.ArgumentParser()
parser.add_argument("--batch_size",     type=int,
                    help="Evaluation batch size", default=1)
parser.add_argument("--num_classes",     type=int,
                    help="Model num classes", default=2)
parser.add_argument("--image_size",     type=tuple,
                    help="Model image size (input resolution)", default=(640, 360))
parser.add_argument("--checkpoint_dir", type=str,
                    help="Setting the model storage directory", default='./checkpoints/')
parser.add_argument("--weight_name", type=str,
                    help="Saved model weights directory", default='/0919/_0919_test_human_seg_640x360_pidnet_best_loss.h5')

args = parser.parse_args()

if __name__ == '__main__':
    # model = ModelBuilder(image_size=args.image_size, num_classes=args.num_classes).build_model()
    from models.model_zoo.PIDNet import PIDNet

    model = PIDNet(input_shape=(*args.image_size, 3), m=2, n=3, num_classes=args.num_classes,
                planes=32, ppm_planes=96, head_planes=128, augment=False).build()
    # model.load_weights(args.checkpoint_dir + args.model_weights, by_name=True)

    model.load_weights(args.checkpoint_dir + args.weight_name)
    model.summary()

    tflite_models_dir = pathlib.Path(args.checkpoint_dir + "quant_models/")
    tflite_models_dir.mkdir(exist_ok=True, parents=True)

    converter = tf.lite.TFLiteConverter.from_keras_model(model)
    converter.optimizations = [tf.lite.Optimize.DEFAULT]
    converter.target_spec.supported_types = [tf.float16]
    tflite_model = converter.convert()
    tflite_model_fp16_file = tflite_models_dir/"quant_test.tflite"
    tflite_model_fp16_file.write_bytes(tflite_model)

    # interpreter_fp16 = tf.lite.Interpreter(tflite_model)
    # interpreter_fp16.allocate_tensors()

    #  # Camera
    # frame_width = 1280
    # frame_height = 720
    # capture = cv2.VideoCapture(0)
    # capture.set(cv2.CAP_PROP_FRAME_WIDTH, frame_width)
    # capture.set(cv2.CAP_PROP_FRAME_HEIGHT, frame_height)

    # while cv2.waitKey(33) < 0:
    #     ret, frame = capture.read()

    #     start_t = timeit.default_timer()

    #     frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    #     img = tf.image.resize(frame, size=args.image_size,
    #             method=tf.image.ResizeMethod.BILINEAR)
    #     img = tf.cast(img, tf.float32)
    #     img = tf.keras.applications.imagenet_utils.preprocess_input(x=img, mode='torch')

    #     img = tf.expand_dims(img, axis=0)

    #     output = model.predict(img)

    #     semantic_output = tf.math.argmax(output, axis=-1)

    #     output = semantic_output[0].numpy().astype(np.uint8) * 50

    #     terminate_t = timeit.default_timer()

    #     FPS = int(1./(terminate_t - start_t ))

    #     cv2.putText(output, str(FPS),(50, 70), cv2.FONT_HERSHEY_SIMPLEX, 1.2,
    #                     (200, 50, 0), 3, cv2.LINE_AA)
    #     cv2.imshow("VideoFrame", output)

    #     print(FPS)
    # capture.release()
    # cv2.destroyAllWindows()


import os
import pandas as pd
import numpy as np

def read_dataset(data_name):
    '''
    =====KDD======
    '''
    if data_name == 'kdd':
        data_dir = './dataset/kdd/'
        class_name = ['normal.', 'neptune.', 'smurf.', 'back.']
        if not os.path.exists(data_dir + 'pro_data.csv'):
            p = pd.read_csv(data_dir + 'kddcup.data_10_percent', error_bad_lines=False, header=None)
            p_part = pd.DataFrame()
            for i1 in class_name:
                p_part = pd.concat([p_part, p[p[41]==i1]], axis = 0)
            for i2 in [1, 2, 3]:
                key_ls = list((p_part[i2].value_counts()).keys())
                for i3 in key_ls:
                    p_part[i2][p_part[i2]==i3] = key_ls.index(i3)
            for i4 in class_name:
                p_part[41][p_part[41]==i4] = class_name.index(i4)
            p_part.to_csv(data_dir + 'pro_data.csv', index=False)
        data = pd.read_csv(data_dir + 'pro_data.csv')
        return data.values[:,:-1], data.values[:,-1]


#!/usr/bin/env python

# Diallo Ibrahima & Thiam Moustapha
# Projet: Resolution automatique d'un puzzle
# 11/01/2016

import numpy as np
import copy as cp

def Read_Data(my_puzzle):
    with open(my_puzzle, 'r') as file_in:
        contents= file_in.readlines()
        n=0
        m=0
        for i, line in enumerate(contents):
            if i==0:
                  k=0
                  height=str()
                  width=str()
                  while line[k]!=' ':
                     height+=line[k]
                     k+=1
                  if k!=0 and line[k]==' ' :
                      while k < len(list(line))-1 :
                         width+= line[k]
                         k+=1
                  n=int(height)
                  m=int(width)
                  size=n*m
                  degres= [0]*size
                  degres=np.array(degres)
                  degres.resize(n,m)
            else :
                 j=0
                 for j in xrange(m):
                      if line[j] != '.' :
                         degres[i-1][j]= int(line[j])
                      else :
                         degres[i-1][j]=0
                      j+=1
    return degres

def News_Neighbors(degres):
        Degres_Neighbors = list()
        Index_Neighbors = list()
        n,m=np.shape(degres)
        for i in xrange(n):
           for j in xrange(m):
                deg_neighbors=list()
                idx_neighbors=list()
                if j < m-1 : #right neighbour
                   u=degres[i][j+1:]
                   idx=np.nonzero(u)
                   if idx[0].tolist() !=[] :
                     idx=idx[0][0]+j+1
                     idx_neighbors.append(i*m+idx)
                     deg_neighbors.append(degres[i][idx])
                if j > 0 :#left neighbour
                   u=degres[i][:j]
                   idx=np.nonzero(u)
                   if idx[0].tolist() !=[] :
                     idx=idx[0][-1]
                     idx_neighbors.append(i*m+idx)
                     deg_neighbors.append(degres[i][idx])
                if i < n-1 : #bottom neighbour
                   u=degres[:,j][i+1:]
                   idx=np.nonzero(u)
                   if idx[0].tolist() !=[] :
                     idx=i+1+idx[0][0]
                     idx_neighbors.append(idx*m+j)
                     deg_neighbors.append(degres[idx][j])
                if i > 0 : #top neighbour
                   u=degres[:,j][i-1::-1]
                   idx=np.nonzero(u)
                   if idx[0].tolist() !=[] :
                     idx= i-1-idx[0][0]
                     idx_neighbors.append(idx*m+j)
                     deg_neighbors.append(degres[idx][j])
                Degres_Neighbors.append(deg_neighbors)
                Index_Neighbors.append(idx_neighbors)
        return Degres_Neighbors, Index_Neighbors

def Combination(old_A,coef):
    new_A = [ cp.deepcopy(old_A), cp.deepcopy(old_A), cp.deepcopy(old_A)  ]
    for i in xrange(coef):
      for j in xrange(len(old_A)):
          new_A[i][j] = str(i)+str(new_A[i][j])

    res = cp.deepcopy(new_A[0])
    for i in xrange(coef-1):
        res += new_A[i+1]
    return res

def Possibilities(Nmax):
    n=len(Nmax)
    res = n*[[]]
    if Nmax[-1] == 2:
       res[0]=['0','1']
    if Nmax[-1] == 3:
        res[0] =['0','1', '2']
    for i in xrange(n-1):
        res[i+1]= Combination(res[i],Nmax[-i-2])

    for elt in list(res):
        for ch in list(elt):
            if ch[0] =='0':
                elt.remove(ch)
    return res

# for connexity
def find_Edges(k, idx_Vk, Edges):
    l=str(k)
    for idx in idx_Vk:
        if k>idx:
            a=[idx,k]
        else:
            a=[k,idx]
        if a in Edges and str(idx) not in l:
           l+=str(idx)
    return l

def computeEdges(my_puzzle):
        degres = Read_Data(my_puzzle)
        deg_1D = degres.flatten()
        Degres_Neighbors, Index_Neighbors = News_Neighbors(degres)
        k=0
        Edges=list()
        n,m=np.shape(degres)
        size=n*m
        for i in xrange(size):
          Edges.append([])

        Iter=0
        Essay=np.zeros(size,np.int)
        Nbmax_Essay=np.zeros(size,np.int)
        Passage=np.zeros(size,np.int)
        count=99*np.ones(size,np.int)
        p=0
        j=0
        c=0
        possibilities=list()
        idx_essays=([-1],)
        nb_vertex_essay=0
        bounds=list()
        comeback=0
        last=0
        while k < size and Iter < 1000:
           deg = deg_1D[k]
           if deg !=0:
             idrow_vr = -1
             idcol_vr  = -1
             idrow_vb = -1
             idcol_vb  = -1
             idl=-1
             idh=-1
             idr=-1
             idb=-1
             vr=0
             vb=0
             for q in Index_Neighbors[k]:
                if abs(q-k) < m  and q < k :
                      idl = q
                if abs(q-k) >= m and q < k :
                      idh = q
                if abs(q-k) < m  and q > k :
                      idr = q
                      vr=deg_1D[idr]
                      idrow_vr = q/m
                      idcol_vr = q%m
                if abs(q-k) >= m and q > k :
                      idb = q
                      vb=deg_1D[idb]
                      idrow_vb = q/m
                      idcol_vb = q%m

             nb_edges_left=0  #number of edges build between idl and k
             if k>0 and idl >=0:
               for o in Edges[idl]:
                  if k in o:
                     nb_edges_left+=1

             nb_edges_high=0  #number of edges build between idh and k
             if k>=m and idh >=0:
               for o in Edges[idh]:
                  if k in o:
                     nb_edges_high+=1

             nb_remaining_edges = deg-nb_edges_left-nb_edges_high

             count[k] = 0 # nb Edges en trop ou en moins
             if nb_remaining_edges == 4:
                 if vr > 1 and vb > 1:
                     Edges[k] = [[k,idr], [k,idr], [k,idb], [k,idb]]
                 else : # we have not been able to place the edges for the index k
                     count[k] = nb_remaining_edges
             elif nb_remaining_edges == 3:
                 if (vr == 8 and vb > 0) or (vb == 1 and vr > 1):
                     Edges[k] = [[k,idr], [k,idr], [k,idb]]
                 elif (vb == 8 and vr > 0) or (vr == 1 and vb > 1) :
                     Edges[k] = [[k,idr], [k,idb], [k,idb]]
                 elif idcol_vr == m-1 and vr == 6 and vb > 0:
                     Edges[k] = [[k,idr], [k,idr], [k,idb]]
                 elif idrow_vr == 0 and vr == 6 and vb > 0:
                     Edges[k] = [[k,idr], [k,idb], [k,idb]]
                 elif idcol_vr == m-1 and idrow_vr == 0 and vr == 4 and vb > 0:
                     Edges[k] = [[k,idr], [k,idr], [k,idb]]
                 elif idcol_vb == 0 and idrow_vb == n-1 and vb == 4 and vr > 0:
                     Edges[k] = [[k,idr], [k,idb], [k,idb]]
                 else:
                     Nbmax_Essay[k]=2 # Maximum number of possible essays on k
                     if vr > 0 and vb > 0:
                         if Essay[k] == 0: #--> we did a first essai
                             Edges[k] = [[k,idr], [k,idr], [k,idb]]
                             Passage[k]=1  #--> means we did a esay on the index k
                         else: #--> we did a second essai
                             Edges[k] = [[k,idr], [k,idb], [k,idb]]
                     else : # we have not been able to place the edges for the index k
                            count[k] = nb_remaining_edges
             elif nb_remaining_edges == 2:
                 if vr == 8 or (vb == 0 and vr > 1) :
                     Edges[k] = [[k,idr], [k,idr]]
                 elif vb == 8 or (vr == 0 and vb > 1):
                     Edges[k] = [[k,idb], [k,idb]]
                 elif (idrow_vr == 0 or idrow_vr == n-1 or idcol_vr == m-1) and vr == 6 :
                     Edges[k] = [[k,idr], [k,idr]]
                 elif (idcol_vb == 0 or idcol_vb == m-1 or idrow_vb == n-1) and vb == 6 :
                     Edges[k] = [[k,idb], [k,idb]]
                 elif (idcol_vr == m-1 and idrow_vr == 0) and vr == 4 :
                     Edges[k] = [[k,idr], [k,idr]]
                 elif (idcol_vb == 0 and idrow_vb == n-1) and vb == 4 :
                     Edges[k] = [[k,idb], [k,idb]]
                 elif (idcol_vr == m-1 and idrow_vr == n-1) and vr == 4 :
                     Edges[k] = [[k,idr], [k,idr]]
                 elif (idcol_vb == m-1 and idrow_vb == n-1) and vb == 4 :
                     Edges[k] = [[k,idb], [k,idb]]
                 else :
                     Nbmax_Essay[k] = 3 # Maximum number of possible essays on k
                     if vr > 0 and vb > 0:
                         if Essay[k] ==0: #--> we did a first essai
                             Edges[k] = [[k,idr], [k,idb]]
                             Passage[k]=1 #--> means we did a esay on the index k
                         elif vr > 1 and Essay[k] == 1: #--> we did a second essai
                             Edges[k] = [[k,idr], [k,idr]]
                             Passage[k]=1
                         elif vb > 1 :   #--> we did a third essai
                             Edges[k] = [[k,idb], [k,idb]]
                     else : # we have not been able to place the edges for the index k
                            count[k] = nb_remaining_edges
             elif nb_remaining_edges == 1:
                 if (deg == 1 and vr == 7) or (vb == 0 and vr > 0):
                     Edges[k] = [[k,idr]]
                 elif (deg == 1 and vb == 7) or (vr == 0 and vb > 0):
                     Edges[k] = [[k,idb]]
                 elif deg == 1 and vr == 3 and idrow_vr == 0 and idcol_vr == m-1 :
                     Edges[k] = [[k,idr]]
                 elif deg == 1 and vr == 3 and idrow_vr == n-1 and idcol_vr == m-1 :
                     Edges[k] = [[k,idr]]
                 elif deg == 1 and vb == 3 and idrow_vb == n-1 and idcol_vb == 0 :
                     Edges[k] = [[k,idb]]
                 elif deg == 1 and vb == 3 and idrow_vb == n-1 and idcol_vb == m-1 :
                     Edges[k] = [[k,idb]]
                 else :
                     Nbmax_Essay[k] = 2  # Maximum number of possible essays on k
                     if vr > 0 and Essay[k] == 0:  #--> we did a first essai
                         Edges[k] = [[k,idr]]
                         Passage[k]=1 #--> means we did a esay on the index k
                     elif vb > 0 and Essay[k] == 1: #--> we did a second essai
                         Edges[k] = [[k,idb]]
                     else : # we have not been able to place the edges for the index k
                           count[k] = nb_remaining_edges
             else: # we have not been able to place the edges for the index k
                 count[k] = nb_remaining_edges

             if count[k] == 1 or count[k] == 2 or count[k] == 3 or count[k]==4 or count[k]<0:
                if idh >= 0 and Passage[idh] == 1 :
                    if idh not in idx_essays[0]:
                        k = idh-1
                        Essay[idh]+=1
                    else:
                        comeback=1
                elif idl >= 0 and Passage[idl] == 1 :
                    if idl not in idx_essays[0]:
                        k = idl-1
                        Essay[idl]+=1
                    else:
                        comeback=1
                else: # recover the last index essay
                    last = np.nonzero(Passage[:k])[0][-1]
                    while Essay[last] == Nbmax_Essay[last]-1 and last >=0:
                        last = np.nonzero(Passage[:last])[0][-1]
                    Essay[last:]=0
                    Essay[last]+=1
                    k=last-1
                for i in xrange(size-k-1):
                     Edges[k+i+1]=list()

             if (count[k] > 4 and count[k]<9) or comeback==1:
                 comeback=0
                 if p==0:
                     idx_essays = np.nonzero(Passage[:k])
                     nb_vertex_essay= len(idx_essays[0])
                     Nmax= nb_vertex_essay*[3]
                     possibilities= Possibilities(Nmax)
                     bounds= np.ones(nb_vertex_essay)
                     j= 0
                     c= 0
                     bounds[0]= len(possibilities[0])
                     for i in xrange(nb_vertex_essay-1):
                        bounds[i+1]=len(possibilities[i+1])+bounds[i]

                 bound =bounds[j]
                 p+=1
                 if bounds!=list() and p < bounds[-1]:
                    ch=possibilities[j][c]
                    Essay[idx_essays[0]]=nb_vertex_essay*[0]
                    for i in xrange(j+1):
                         Essay[idx_essays[0][-i-1]]=int(ch[-i-1])

                 k= idx_essays[0][-j-1]-1
                 for i in xrange(size-k-1):
                    Edges[k+i+1]=list()

                 if p==bound:
                        j+=1
                        c=0
                 else:
                        c+=1

           k+=1
           Iter+=1

        if Edges!=[]:
          N=0
          N_vides=Edges.count([])
          while N < N_vides:
             Edges.remove([])
             N+=1

          res=Edges[0]
          if len(Edges)>1:
             for i in xrange(len(Edges)-1):
               res+=Edges[i+1]

          return res


play = True
started = False
while play:
    action = input(">").lower()
    if action == 'help':
        print(" start - to start the car \n stop - to stop the car \n quit - to exit")
    elif action == 'start':
        if started:
            print("Car is already started, WHAT ARE YOU DOING???")
        else:
            started = True
            print("Car started, ready to go")
    elif action == 'stop':
        if not started:
            print("Car is already stopped, WHAT ARE YOU DOING")
        else:
            started = False
            print("Car Stopped")
    elif action == 'quit':
        print("Thank you for playing")
        break
    else:
        print("I don't understand that")


from LinkedList import *

def evenAfterOdd(head):
    if head is None:
        return head
    oddHead = None
    evenHead = None

    evenTail = None
    oddTail = None

    while head is not None:
        if head.data % 2 == 0:
            if evenHead == None:
                evenHead = head
                evenTail = head
            else:
                evenTail.next = head
                evenTail = evenTail.next
        elif head.data%2 == 1:
            if oddHead == None:
                oddHead = head
                oddTail = head
            else:
                oddTail.next = head
                oddTail = oddTail.next
        head = head.next

    if oddHead is None:
        return evenHead
    else:
        oddTail.next = evenHead
    if evenTail is not None:
        evenTail.next = None

    return oddHead

head = takeInput()
printLinkedList(evenAfterOdd(head))


with open('source', 'r+') as file:
    file = file.read().splitlines()
    calories = [int(calorie) if calorie else 0 for calorie in file]

def first_puzzle():
    max_cal = current_cal = 0

    for calorie in calories:
        if calorie:
            current_cal += calorie
        else:
            if current_cal > max_cal:
                max_cal = current_cal
            current_cal = 0
    print(max_cal)

def second_puzzle():
    sum_calories = []

    elf_calorie = 0
    for calorie in calories:
        if calorie:
            elf_calorie += calorie
        else:
            sum_calories.append(elf_calorie)
            elf_calorie = 0

    print(sum(sorted(sum_calories)[-3::]))

first_puzzle()
second_puzzle()


import cv2
import numpy as np

import torch

class Compose(object):
    """Composes several video_transforms together.

    Args:
        transforms (List[Transform]): list of transforms to compose.

    Example:
        >>> video_transforms.Compose([
        >>>     video_transforms.CenterCrop(10),
        >>>     video_transforms.ToTensor(),
        >>> ])
    """
    def __init__(self, transforms, aug_seed=0):
        self.transforms = transforms
        for i, t in enumerate(self.transforms):
            t.set_random_state(seed=(aug_seed+i))

    def __call__(self, data):
        for t in self.transforms:
            data = t(data)
        return data

class Transform(object):
    """basse class for all transformation"""
    def set_random_state(self, seed=None):
        self.rng = np.random.RandomState(seed)

class Normalize(Transform):
    """Given mean: (R, G, B) and std: (R, G, B),
    will normalize each channel of the torch.*Tensor, i.e.
    channel = (channel - mean) / std
    """
    def __init__(self, mean, std, group=False):
        self.mean = mean
        self.std = std
        self.group = group

    def __call__(self, tensor):
        if self.group is False:
            norm_tensor = self._process(tensor)
        else:
            norm_tensor=torch.Tensor([])
            for t in tensor:
                norm_t = self._process(t)
                norm_tensor = torch.cat((norm_tensor, norm_t.unsqueeze(0)), dim=0)
        return norm_tensor

    def _process(self, tensor):
        for t, m, s in zip(tensor, self.mean, self.std):
            t.sub_(m).div_(s)
        return tensor

class Resize(Transform):
    """ Rescales the input numpy array to the given 'size'.
    'size' will be the size of the smaller edge.
    For example, if height > width, then image will be
    rescaled to (size * height / width, size)
    size: size of the smaller edge
    interpolation: Default: cv2.INTER_LINEAR
    """
    def __init__(self, size, interpolation=cv2.INTER_LINEAR, group=False):
        self.size = size # [w, h]
        self.interpolation = interpolation
        self.group = group

    def __call__(self, data):

        if self.group is False:
            scaled_data = self._process(data)
        else:
            scaled_data=[]
            for d in data:
                scaled_d = self._process(d)
                scaled_data.append(scaled_d)
            scaled_data = np.asarray(scaled_data)
        return scaled_data

    def _process(self, data):
        h, w, c = data.shape

        if isinstance(self.size, int):
            slen = self.size
            if min(w, h) == slen:
                return data
            if w < h:
                new_w = self.size
                new_h = int(self.size * h / w)
            else:
                new_w = int(self.size * w / h)
                new_h = self.size
        else:
            new_w = self.size[0]
            new_h = self.size[1]

        if (h != new_h) or (w != new_w):
            scaled_data = cv2.resize(data, (new_w, new_h), self.interpolation)
        else:
            scaled_data = data

        return scaled_data

class CenterCrop(Transform):
    """Crops the given numpy array at the center to have a region of
    the given size. size can be a tuple (target_height, target_width)
    or an integer, in which case the target will be of a square shape (size, size)
    """
    def __init__(self, size, group=False):
        if isinstance(size, int):
            self.size = (size, size)
        else:
            self.size = size
        self.group = group

    def __call__(self, data):

        if self.group is False:
            cropped_data = self._process(data)
        else:
            cropped_data=[]
            for d in data:
                cropped_d = self._process(d)
                cropped_data.append(cropped_d)
            cropped_data = np.asarray(cropped_data)

        return cropped_data

    def _process(self, data):

        h, w, c = data.shape
        th, tw = self.size
        x1 = int(round((w - tw) / 2.))
        y1 = int(round((h - th) / 2.))
        cropped_data = data[y1:(y1+th), x1:(x1+tw), :]

        return cropped_data

class ToTensor(Transform):
    """Converts a numpy.ndarray (H x W x C) in the range
    [0, 255] to a torch.FloatTensor of shape (C x H x W) in the range [0.0, 1.0].
    """
    def __init__(self, dim=3, group=False):
        self.dim = dim
        self.group = group

    def __call__(self, image):

        if self.group is False:
            tensor_data = self._process(image)
        else:
            tensor_data=torch.Tensor([])
            for i in image:
                tensor_d = self._process(i)
                tensor_data = torch.cat((tensor_data, tensor_d.unsqueeze(0)), dim=0)

        return tensor_data

    def _process(self, image):
        if isinstance(image, np.ndarray):
            # H, W, C = image.shape
            # handle numpy array
            image = torch.from_numpy(image.transpose((2, 0, 1)))
            # backward compatibility
            return image.float() / 255.0

class RandomHorizontalFlip(Transform):
    """Randomly horizontally flips the given numpy array with a probability of 0.5
    """
    def __init__(self, group=False):
        self.rng = np.random.RandomState(0)
        self.group = group

    def __call__(self, data):

        if self.rng.rand() < 0.5:
            if self.group is False:
                fliped_data = self._process(data)
            else:
                fliped_data=[]
                for d in data:
                    fliped_d = self._process(d)
                    fliped_data.append(fliped_d)
                fliped_data = np.asarray(fliped_data)
        else:
            fliped_data = data

        return fliped_data

    def _process(self, data):
        data = np.fliplr(data)
        data = np.ascontiguousarray(data)
        return data

class RandomHLS(Transform):
    def __init__(self, vars=[15, 35, 25], group=False):
        self.vars = vars
        self.rng = np.random.RandomState(0)
        self.group = group

    def __call__(self, data):

        if self.group is False:
            augmented_data = self._process(data)
        else:
            augmented_data=[]
            for d in data:
                augmented_d = self._process(d)
                augmented_data.append(augmented_d)
            augmented_data = np.asarray(augmented_data)

        return augmented_data

    def _process(self, data):
        h, w, c = data.shape
        assert c%3 == 0, "input channel = %d, illegal"%c

        random_vars = [int(round(self.rng.uniform(-x, x))) for x in self.vars]

        base = len(random_vars)
        augmented_data = np.zeros(data.shape, )

        for i_im in range(0, int(c/3)):
            augmented_data[:,:,3*i_im:(3*i_im+3)] = \
                    cv2.cvtColor(data[:,:,3*i_im:(3*i_im+3)], cv2.COLOR_RGB2HLS)

        hls_limits = [180, 255, 255]
        for ic in range(0, c):
            var = random_vars[ic%base]
            limit = hls_limits[ic%base]
            augmented_data[:,:,ic] = np.minimum(np.maximum(augmented_data[:,:,ic] + var, 0), limit)

        for i_im in range(0, int(c/3)):
            augmented_data[:,:,3*i_im:(3*i_im+3)] = \
                    cv2.cvtColor(augmented_data[:,:,3*i_im:(3*i_im+3)].astype(np.uint8), \
                        cv2.COLOR_HLS2RGB)

        return augmented_data

class GroupMultiScaleCrop(Transform):

    def __init__(self, input_size, scales=None, max_distort=1, fix_crop=True, more_fix_crop=True):
        self.scales = scales if scales is not None else [1, .875, .75, .66]
        self.max_distort = max_distort
        self.fix_crop = fix_crop
        self.more_fix_crop = more_fix_crop
        self.input_size = input_size if not isinstance(input_size, int) else [input_size, input_size]

    def __call__(self, img_group):

        height, width, _ = img_group[0].shape
        crop_w, crop_h, offset_w, offset_h = self._sample_crop_size(width, height)

        resize_fn = Resize((self.input_size[0], self.input_size[1]))
        crop_img_group = [img[offset_h:offset_h+crop_h, offset_w:offset_w+crop_w] for img in img_group]
        ret_img_group = [resize_fn(img) for img in crop_img_group]
        ret_img_group = np.asarray(ret_img_group)
        return ret_img_group

    def _sample_crop_size(self, image_w, image_h):
        # find a crop size

        base_size = min(image_w, image_h)
        crop_sizes = [int(base_size * x) for x in self.scales]
        crop_h = [self.input_size[1] if abs(x - self.input_size[1]) < 3 else x for x in crop_sizes]
        crop_w = [self.input_size[0] if abs(x - self.input_size[0]) < 3 else x for x in crop_sizes]

        pairs = []
        for i, h in enumerate(crop_h):
            for j, w in enumerate(crop_w):
                if abs(i - j) <= self.max_distort:
                    pairs.append((w, h))

        sind = np.random.randint(0,len(pairs))
        crop_pair = pairs[sind]
        if not self.fix_crop:
            w_offset = np.random.randint(0, image_w - crop_pair[0])
            h_offset = np.random.randint(0, image_h - crop_pair[1])
        else:
            w_offset, h_offset = self._sample_fix_offset(image_w, image_h, crop_pair[0], crop_pair[1])

        return crop_pair[0], crop_pair[1], w_offset, h_offset

    def _sample_fix_offset(self, image_w, image_h, crop_w, crop_h):
        offsets = self.fill_fix_offset(self.more_fix_crop, image_w, image_h, crop_w, crop_h)
        sind = np.random.randint(0,len(offsets))
        return offsets[sind]

    @staticmethod
    def fill_fix_offset(more_fix_crop, image_w, image_h, crop_w, crop_h):
        w_step = (image_w - crop_w) // 4
        h_step = (image_h - crop_h) // 4

        ret = list()
        ret.append((0, 0))  # upper left
        ret.append((4 * w_step, 0))  # upper right
        ret.append((0, 4 * h_step))  # lower left
        ret.append((4 * w_step, 4 * h_step))  # lower right
        ret.append((2 * w_step, 2 * h_step))  # center

        if more_fix_crop:
            ret.append((0, 2 * h_step))  # center left
            ret.append((4 * w_step, 2 * h_step))  # center right
            ret.append((2 * w_step, 4 * h_step))  # lower center
            ret.append((2 * w_step, 0 * h_step))  # upper center

            ret.append((1 * w_step, 1 * h_step))  # upper left quarter
            ret.append((3 * w_step, 1 * h_step))  # upper right quarter
            ret.append((1 * w_step, 3 * h_step))  # lower left quarter
            ret.append((3 * w_step, 3 * h_step))  # lower righ quarter

        return ret


from opentrons import robot, containers, instruments

robot.head_speed(x=18000, y=18000, z=5000, a=400, b=400)

class Vector(object):
    def tolist(self):
        return list(self.input_list)

    def astype(self, input_type):
        if input_type == int:
            return Vector([int(float(x)) for x in self.input_list])
        return Vector([input_type(x) for x in self.input_list])

    def __init__(self, input_list):
        self.input_list = input_list

class DataFrame(object):
    def __len__(self):
        return self.length

    def __getitem__(self, value):
        return Vector(self.dict_input[value])

    def __init__(self, dict_input, length):
        self.dict_input = dict_input
        self.length = length

# Function that reads a csv file correctly without having to import anything (issues with molport). Uses 2 classes, Vector and DataFrame
def read_csv(input_file):
    lines = open(input_file).readlines()
    header = lines[0].rstrip().split(",")
    out_d = {}
    for head in header:
        out_d[head] = []
    for line in lines[1:]:
        spl_line = line.rstrip().split(",")
        for i, head in enumerate(header):
            out_d[head].append(spl_line[i])
    df = DataFrame(out_d, len(lines[1:]))
    return df

# CSV file data
reaction_conditions_df = read_csv(
    r"C:\Users\opentrons\protocols\GitHub_repos\OT1-coding\coupling_sequence_phip - Try2\csv\forMeIAddition\reaction_conditions.csv")

def reactants_transfer(reactants):
    # Deck setup

    tiprack_1000 = containers.load("tiprack-1000ul-H", "B3")
    tiprack_1000_2 = containers.load("tiprack-1000ul-H", "D3")
    #tiprack_1000_3 = containers.load("tiprack-1000ul-H", "B1")
    storage_rack = containers.load("FluidX_24_2ml", "D1")
    destination_rack1 = containers.load("StarLab_96_tall", "A1")
    trash = containers.load("point", "C3")

    # Pipettes SetUp
    p1000 = instruments.Pipette(
        name='eppendorf1000_no_min',
        axis='b',
        trash_container=trash,
        tip_racks=[tiprack_1000, tiprack_1000_2],
        max_volume=1000,
        min_volume=0,
        channels=1,
    )
    id_header = "reaction"
    reaction_to_start = "Coupling_sequence"
    split_volume_header = "volume amine to add"
    transfer_number_header = "number of transfer per vial"

    for index, value in enumerate(reaction_conditions_df[id_header].tolist()):
        if value == reaction_to_start:
            volume_per_reaction = float(reaction_conditions_df[split_volume_header].tolist()[index])
            transfer_number = int(reaction_conditions_df[transfer_number_header].tolist()[index])
            source_location_1 = [storage_rack.wells(0).bottom()]
            source_location_2 = [storage_rack.wells(1).bottom()]
            source_location_3 = [storage_rack.wells(2).bottom()]

            destination_1 = [x.top(-10) for x in destination_rack1.wells(0, to=transfer_number-1)]
            destination_2 = [x.top(-10) for x in destination_rack1.wells(transfer_number, to=transfer_number*2-1)]
            destination_3 = [x.top(-10) for x in destination_rack1.wells(transfer_number*2, to=transfer_number*3-1)]

            p1000.distribute(volume_per_reaction, source_location_1,destination_1, air_gap=10)
            p1000.distribute(volume_per_reaction, source_location_2,destination_2, air_gap=10)
            p1000.distribute(volume_per_reaction, source_location_3,destination_3, air_gap=10)
reactants_transfer(reaction_conditions_df)


import os

BASE_DIR = os.path.dirname(os.path.dirname(__file__))

SECRET_KEY = 'ONLY-USED-FOR-TESTING'

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

ASSETBANK_AUTH_ENABLED = True
ASSETBANK_AUTH_TOKEN_KEY = ''
ASSETBANK_URL = 'http://localhost:8080/asset-bank'
ASSETBANK_LOG_OUT_AFTER_AUTH = False


f = open('fetched_tweets_output.json')
ff = open('INPUT_FILE.json','a')
while True:
	a = f.readline()
	print(a)
	if a == '\n' or len(a)<60:
		continue
	else:
		ff.write(a)
f.close()
ff.close()


from src.models.product import Product
from typing import Union
from src.models.user import User
from http import HTTPStatus
from .. import jwt
from flask import request

class UserService:
    allowed_coins = [100, 50, 20, 10, 5]

    @staticmethod
    def get_users():
        try:
            return User.get_all()
        except:
            return {"messsage": "Something went wrong"}, HTTPStatus.FORBIDDEN

    @staticmethod
    def get_user_by_username(username: str) -> Union[User, None]:
        return User.query.filter_by(username=username).first()

    @staticmethod
    def check_if_user_exists(username):
        return User.query.filter_by(username=username).first() is not None

    @staticmethod
    def create_user(login_request):
        try:
            if UserService.check_if_user_exists(login_request["username"]):
                return {"messsage": "Username already exists"}, HTTPStatus.CONFLICT

            user = User(**login_request)
            user.save()
            return user.generate_access_token(), HTTPStatus.CREATED
        except:
            return {"message": "Something went wrong"}, HTTPStatus.FORBIDDEN

    @staticmethod
    def deposit(deposit_request):
        try:
            payload = jwt.decode(request.headers["Authorization"])
            user_id = payload.user_id
            user = User.query.filter_by(id=user_id).first()
            if user is None:
                return {"message": f"User with id: {user_id} doesn't exist"}, HTTPStatus.NOT_FOUND

            if not deposit_request["deposit"] in UserService.allowed_coins:
                return {"message": f"Only {', '.join([str(coin) for coin in UserService.allowed_coins])} coins allowed"}, HTTPStatus.CONFLICT

            user.deposit =  user.deposit + deposit_request["deposit"]
            user.save()
            return {"message":"User deposit set successfully"}, HTTPStatus.OK

        except:
            return {"message": "Something went wrong"}, HTTPStatus.FORBIDDEN

    @staticmethod
    def buy_product(buy_request):
        try:
            payload = jwt.decode(request.headers["Authorization"])
            product_id = buy_request["product_id"]
            product = Product.query.filter_by(id=product_id).first()
            if product is None:
                return {"message": f"Product with id:{product_id} doesn't exist"}, HTTPStatus.NOT_FOUND

            user = User.query.filter_by(id=payload.user_id).first()
            if user is None:
                return{"message":"User was not found"}, HTTPStatus.NOT_FOUND

            amount = buy_request["amount"]

            if product.amount_available < amount:
                return {"message" : f"There is less than {amount} products available"}, HTTPStatus.CONFLICT

            total_cost = product.cost * buy_request["amount"]
            if total_cost > user.deposit:
                return {"message" : "You don't have enough money in deposit to buy a product"}, HTTPStatus.CONFLICT

            user.deposit = user.deposit - total_cost
            user.save()
            product.amount_available = product.amount_available - amount
            product.save()

            return {
                "money_spent": total_cost,
                "product_id": product.id,
                "message":"You  bought a product successfully",
                "money_left": user.deposit,
                "amount_bought" : amount,
                "change": UserService.calculate_change(user.deposit)}, HTTPStatus.OK,
        except:
            return {"message": "Something went wrong. Please try again"}, HTTPStatus.FORBIDDEN

    @staticmethod
    def get_user(user_id):
        try:
            user = User.get_by_id(user_id)
            return user, HTTPStatus.OK
        except:
            return {"message":" Something went wrong. Try again"}, HTTPStatus.FORBIDDEN

    @staticmethod
    def update_user(user_id, request_data):
        try:
            user = User.query.filter_by(id=user_id).first()

            username = request_data["username"]
            duplicate_user = User.query.filter_by(username=username).first()
            if user.username != username and duplicate_user:
                return {"message":"Username already taken"}, HTTPStatus.CONFLICT
            user.update(**request_data)

            return user, HTTPStatus.OK
        except:
            return {"message":" Something went wrong. Try again"}, HTTPStatus.FORBIDDEN

    @staticmethod
    def delete_user(user_id):
        try:
            user = User.get_by_id(user_id)
            user.delete()
            return {"message": "User was deleted successfully"}, HTTPStatus.OK
        except:
            return {"message":" Something went wrong. Try again"}, HTTPStatus.FORBIDDEN

    @staticmethod
    def reset_deposit(user_id):
        try:
            user = User.get_by_id(user_id)
            if user is None:
                return {"message": f"User with id:{user_id} doesn't exist"}, HTTPStatus.NOT_FOUND
            user.deposit = 0
            user.save()
            return {"message": "User deposit was reset successfully"}, HTTPStatus.OK
        except:
            return {"message":" Something went wrong. Try again"}, HTTPStatus.FORBIDDEN

    def calculate_change(total_amount):
        change = []
        for coin in UserService.allowed_coins:
            amount = (total_amount // coin)
            total_amount -= (total_amount // coin) * coin
            change.append({"amount": amount, "coin": coin})
        return change


import argparse
import yaml
import os
import os.path as osp
from sklearn.model_selection import ParameterGrid
import shutil

class MyDumper(yaml.Dumper):
    def increase_indent(self, flow=False, indentless=False):
        return super(MyDumper, self).increase_indent(flow, False)

def parse_args():
    """Parses the arguments."""
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--config',
        dest='config',
        help='the base configuration file used for edit',
        default=None,
        type=str
    )
    parser.add_argument(
        '--grid',
        dest='grid',
        help='configuration file for grid search',
        required=True,
        type=str
    )
    parser.add_argument(
        '--out-dir',
        dest='out_dir',
        help='output directory for generated config files',
        default='configs',
        type=str
    )
    return parser.parse_args()

def generate_grid_configs(config, grid, out_dir):
    """Generate grid configs."""
    shutil.rmtree(out_dir, ignore_errors=True)
    os.makedirs(out_dir, exist_ok=True)
    keys = list(grid.keys())
    alias = {k: grid[k]['alias'] for k in keys}
    param_grid = {key: grid[key]['range'] for key in keys}
    grid_space = list(ParameterGrid(param_grid))
    for i, params in enumerate(grid_space):
        new_config = config.copy()
        title = ""
        for key in keys:
            key_path = key.split('.')
            d = new_config
            for k in key_path[:-1]:
                d = d[k]
            d[key_path[-1]] = params[key]
            title += '{}={}'.format(alias[key], params[key])
        new_config['title'] = '{}_{}'.format(config['title'], title)
        with open(osp.join(out_dir, f'{title}.yml'), 'w') as f:
            yaml.dump(new_config, f, Dumper=MyDumper, default_flow_style=False)

if __name__ == '__main__':
    args = parse_args()
    with open(args.config, 'r') as f:
        config = yaml.load(f, Loader=yaml.FullLoader)
    with open(args.grid, 'r') as f:
        grid = yaml.load(f, Loader=yaml.FullLoader)
    out_dir = os.path.join(args.out_dir, config['title'] + '_grid')
    generate_grid_configs(config, grid, out_dir)


import random
#Created by Wolf

print("Hello ! Let's play a game =) \nType numbers 0 - 9 and try to find the treasure.")

def main():
    finePartita = False
    Campo = list(range(0, 10))
    posizionedeltesoro = random.randint(0, 9)
    tentativi = 3

    while finePartita == False:
        print(*Campo)
        userInput = int(input("Your Guess ? : "))

        if Campo[userInput] == '_':
            print("You already tried this field")
            continue
        elif userInput != posizionedeltesoro:
            Campo[userInput] = '_'
            tentativi = tentativi - 1
            if tentativi == 0:
                print("You lost beacause you don't have any more attempts")
                finePartita = True
            else:
                print("You suck ! Try again !!")
            continue
        else:
            Campo[userInput] = '*'
            print("Congratulations, you won !")
            finePartita = True
            break
main()


import math
import random

class Dataset:

    def __init__(self, samples, batch_size, multim=False, audiovid=False, audiotext=False, textvid=False, exp3=False,
                 decision_level=False):
        self.samples = samples
        self.batch_size = batch_size
        self.num_batches = math.ceil(len(self.samples) / batch_size)
        self.speaker_to_idx = {'M': 0, 'F': 1}
        self.multim = multim
        self.size = 100 if exp3 else 100 if decision_level else 712 if multim else 200 if audiotext else 612 if textvid else 612 if audiovid else 100
        self.audiovid = audiovid
        self.audiotext = audiotext
        self.textvid = textvid
        self.exp3 = exp3
        self.decision_level = decision_level

    def __len__(self):
        return self.num_batches

    def __getitem__(self, index):
        batch = self.raw_batch(index)
        return self.padding(batch)

    def raw_batch(self, index):
        assert index < self.num_batches, "batch_idx %d > %d" % (index, self.num_batches)
        batch = self.samples[index * self.batch_size: (index + 1) * self.batch_size]

        return batch

    def padding(self, samples):
        batch_size = len(samples)
        text_len_tensor = torch.tensor([len(s.text) for s in samples]).long()
        mx = torch.max(text_len_tensor).item()
        text_tensor = torch.zeros((batch_size, mx, self.size))
        a_tensor = torch.zeros((batch_size, mx, 100))
        v_tensor = torch.zeros((batch_size, mx, 512))
        audiovid_tensor = torch.zeros((batch_size, mx, 100)) if self.audiotext else torch.zeros(
            (batch_size, mx, 512)) if self.textvid else torch.zeros((batch_size, mx, 612))

        speaker_tensor = torch.zeros((batch_size, mx)).long()
        labels = []
        n_utterances = 0
        for i, s in enumerate(samples):
            cur_len = len(s.text)
            n_utterances += cur_len
            tmp = [torch.from_numpy(t).float() for t in s.text]
            tmp_vid = [torch.from_numpy(t).float() for t in s.visual]
            tmp_aud = [torch.from_numpy(t).float() for t in s.audio]
            tmp = torch.stack(tmp)
            tmp_vid = torch.stack(tmp_vid)
            tmp_aud = torch.stack(tmp_aud)
            if i == 0:
                video_tensor = tmp_vid
                audio_tensor = tmp_aud
            else:
                video_tensor = torch.cat((video_tensor, tmp_vid), 0)
                audio_tensor = torch.cat((audio_tensor, tmp_aud), 0)

            if self.multim:
                aud = torch.tensor(s.audio)
                vid = torch.tensor(s.visual)
                tmp = torch.cat((tmp, vid, aud), 1)
            elif self.audiovid and not self.exp3 and not self.decision_level:
                aud = torch.tensor(s.audio)
                vid = torch.tensor(s.visual)
                tmp = torch.cat((vid, aud), 1)
            elif self.audiotext and not self.exp3 and not self.decision_level:
                aud = torch.tensor(s.audio)
                tmp = torch.cat((tmp, aud), 1)
            elif self.textvid and not self.exp3 and not self.decision_level:
                vid = torch.tensor(s.visual)
                tmp = torch.cat((tmp, vid), 1)

            audvid = torch.cat((tmp_vid, tmp_aud), 1)
            if self.textvid:
                audiovid_tensor[i, :cur_len, :] = tmp_vid
            elif self.audiotext:
                audiovid_tensor[i, :cur_len, :] = tmp_aud
            else:
                audiovid_tensor[i, :cur_len, :] = audvid
            text_tensor[i, :cur_len, :] = tmp
            a_tensor[i, :cur_len, :] = tmp_aud
            v_tensor[i, :cur_len, :] = tmp_vid
            speaker_tensor[i, :cur_len] = torch.tensor([self.speaker_to_idx[c] for c in s.speaker])
            labels.extend(s.label)
        # video_tensor = torch.zeros((n_utterances, 512)) #added <- should be size(num_utterances in batch, vec_dim)
        # audio_tensor = torch.zeros((n_utterances, 100)) #added <- same as above

        label_tensor = torch.tensor(labels).long()
        data = {
            "text_len_tensor": text_len_tensor,
            "text_tensor": text_tensor,
            "speaker_tensor": speaker_tensor,
            "label_tensor": label_tensor,
            "video_tensor": video_tensor,
            "audio_tensor": audio_tensor,
            "audiovid_tensor": audiovid_tensor,
            "audio": a_tensor,
            "video": v_tensor

        }

        return data

    def shuffle(self):
        random.shuffle(self.samples)

import numpy as np
import torch

import utils

log = utils.get_logger()

def batch_graphify(features, lengths, speaker_tensor, wp, wf, edge_type_to_idx, att_model, device):
    node_features, edge_index, edge_norm, edge_type = [], [], [], []
    batch_size = features.size(0)
    length_sum = 0
    edge_ind = []
    edge_index_lengths = []

    for j in range(batch_size):
        edge_ind.append(edge_perms(lengths[j].cpu().item(), wp, wf))

    edge_weights = att_model(features, lengths, edge_ind)

    for j in range(batch_size):
        cur_len = lengths[j].item()
        node_features.append(features[j, :cur_len, :])
        perms = edge_perms(cur_len, wp, wf)
        perms_rec = [(item[0] + length_sum, item[1] + length_sum) for item in perms]
        length_sum += cur_len
        edge_index_lengths.append(len(perms))

        for item, item_rec in zip(perms, perms_rec):
            edge_index.append(torch.tensor([item_rec[0], item_rec[1]]))
            edge_norm.append(edge_weights[j][item[0], item[1]])
            # edge_norm.append(edge_weights[j, item[0], item[1]])

            speaker1 = speaker_tensor[j, item[0]].item()
            speaker2 = speaker_tensor[j, item[1]].item()
            if item[0] < item[1]:
                c = '0'
            else:
                c = '1'
            edge_type.append(edge_type_to_idx[str(speaker1) + str(speaker2) + c])

    node_features = torch.cat(node_features, dim=0).to(device)  # [E, D_g]
    edge_index = torch.stack(edge_index).t().contiguous().to(device)  # [2, E]
    edge_norm = torch.stack(edge_norm).to(device)  # [E]
    edge_type = torch.tensor(edge_type).long().to(device)  # [E]
    edge_index_lengths = torch.tensor(edge_index_lengths).long().to(device)  # [B]

    return node_features, edge_index, edge_norm, edge_type, edge_index_lengths

def edge_perms(length, window_past, window_future):
    """
    Method to construct the edges of a graph (a utterance) considering the past and future window.
    return: list of tuples. tuple -> (vertice(int), neighbor(int))
    """

    all_perms = set()
    array = np.arange(length)
    for j in range(length):
        perms = set()

        if window_past == -1 and window_future == -1:
            eff_array = array
        elif window_past == -1:  # use all past context
            eff_array = array[:min(length, j + window_future + 1)]
        elif window_future == -1:  # use all future context
            eff_array = array[max(0, j - window_past):]
        else:
            eff_array = array[max(0, j - window_past):min(length, j + window_future + 1)]

        for item in eff_array:
            perms.add((j, item))
        all_perms = all_perms.union(perms)
    return list(all_perms)


from sdv.model import Service

from sdv_model.proto.seats_pb2 import (
    CurrentPositionRequest,
    MoveComponentRequest,
    MoveRequest,
    Seat,
    SeatComponent,
    SeatLocation,
)
from sdv_model.proto.seats_pb2_grpc import SeatsStub

class SeatService(Service):
    """
    Seats service for getting and controlling the positions of the seats
    and their components in the vehicle.
    This definition corresponds to the COVESA Vehicle Service Catalog (VSC)
    comfort seats service definition
    (https://github.com/COVESA/vehicle_service_catalog)

    ...

    Methods
    ----------
    Move(seat=Seat)
        Set the desired seat position

    MoveComponent(seatLocation=SeatLocation, component=SeatComponent, position=int)
        Set a seat component position

    CurrentPosition(row=int, index=int)
        Get the current position of the addressed seat

    """

    def __init__(self):
        super().__init__()
        self._stub = SeatsStub(self.channel)

    async def Move(self, seat: Seat):
        """
        Summary
        -------
            Set the desired seat position

        Parameters
        ----------
        seat : Seat
            The seat which needs to be moved

        Returns
        -------
            * OK - Seat movement started
            * OUT_OF_RANGE - The addressed seat is not present in this vehicle
            * INVALID_ARGUMENT - At least one of the requested component positions is invalid
            * INTERNAL - A seat service internal error happened - see error message for details
        """
        response = await self._stub.Move(MoveRequest(seat=seat), metadata=self.metadata)
        return response

    async def MoveComponent(
        self,
        seatLocation: SeatLocation,
        component: SeatComponent,
        position: int,
    ):
        """
        Parameters
        ----------
        seatLocation : SeatLocation
            The location of the seat in which the component is present
        component : SeatComponent
            The component of the seat which needs to be moved
        position : int
            The units by which the component has to move

        Returns
        -------
            * OK - Seat movement started
            * OUT_OF_RANGE - The addressed seat is not present in this vehicle
            * NOT_FOUND - The addressed seat component is not supported by this seat/vehicle
            * INVALID_ARGUMENT - At least one of the requested component positions is invalid
            * INTERNAL - A seat service internal error happened - see error message for details

        """
        response = await self._stub.MoveComponent(
            MoveComponentRequest(
                seat=seatLocation,
                component=component,  # type: ignore
                position=position,
            ),
            metadata=self.metadata,
        )
        return response

    async def CurrentPosition(self, row: int, index: int):
        """
        Parameters
        ----------
        row : int
            The row of the seat
        index : int
            The index of the seat

        Returns
        -------
            * OK - Seat positions returned
            * OUT_OF_RANGE - The addressed seat is not present in this vehicle
        """
        response = await self._stub.CurrentPosition(
            CurrentPositionRequest(row=row, index=index),
            metadata=self.metadata,
        )
        return response


import math

import overpy.exception
import holoviews
import datashader.geo
import sonar.lowrance_log_parser

import logging
logger = logging.getLogger('sonar_map')

def AdjustToIncludeNearestLandmark(lon_min, lon_max, lat_min, lat_max):
    orig_lon_min = lon_min
    orig_lon_max = lon_max

    orig_lat_min = lat_min
    orig_lat_max = lat_max

    lon_dist = orig_lon_max - orig_lon_min
    lat_dist = orig_lat_max - orig_lat_min

    # Find the nearest suburb to the middle of the bounding box
    middle_lon = orig_lon_min + lon_dist / 2.0
    middle_lat = orig_lat_min + lat_dist / 2.0

    # Overpass seems to take degrees not web mercator metres, so convert the middle to use in overpass
    middle_lon_degrees, middle_lat_degrees = sonar.lowrance_log_parser.meters_to_lnglat(middle_lon, middle_lat)

    api = overpy.Overpass()
    radius = 100.0

    # Permit path area to be as small as 1/10 of overall map to provide context
    # So if we travel 10km, will look upto 100km
    max_radius = 10 * max((orig_lat_max - orig_lat_min), (orig_lon_max - orig_lon_min))

    # If only travell 1 cm, still permit the graph to search context up to 5km
    max_radius = max(max_radius, 5000)

    # @todo Add the nearest landmark to the cache meta-data and use it if already exists
    nearest_landmark_debug = ''
    node = None
    node_lon = None
    node_lat = None
    while node is None and radius <= max_radius:
        logger.debug('Trying radius: %s', radius)

        query = '<query type="node"><has-kv k="place" /><around lon="%s" lat="%s" radius="%s"/></query><print/>' % (middle_lon_degrees, middle_lat_degrees, radius)
        logger.debug('Query: %s', query)

        try: result = api.query(query)
        except overpy.exception.OverpassTooManyRequests as e:
            logger.warning('Failed to query nearby suburb: %s', e)
            break
        except overpy.exception.OverpassGatewayTimeout as e:
            logger.warning('Failed to query nearby suburb: %s', e)
            break
        logger.debug('Looking at result: %s nodes:%s ways:%s relations:%s areas:%s',
            result,
            result.get_node_ids(),
            result.get_way_ids(),
            result.get_relation_ids(),
            result.get_area_ids())

        radius *= 5

        min_dist_index = None
        distances = []
        for i in range(0, len(result.nodes)):
            logger.debug('Looking at result node: %s of %s', i, len(result.nodes))
            n = result.nodes[i]
            n_lon, n_lat = sonar.lowrance_log_parser.lnglat_to_meters(float(n.lon), float(n.lat))
            lat_dist = middle_lat - n_lat
            lon_dist = middle_lon - n_lon
            dist = math.sqrt((lat_dist * lat_dist) + (lon_dist * lon_dist))
            logger.debug ('Distance: %s from middle of travelled area to node: %s %s', dist, n, n.tags)
            distances.append(dist)

            if min_dist_index is None or dist < distances[min_dist_index]:
                min_dist_index = i

        if min_dist_index is not None:
            node = result.nodes[min_dist_index]
            node_lon, node_lat = sonar.lowrance_log_parser.lnglat_to_meters(float(node.lon), float(node.lat))

            logger.debug('Selecting the nearest landmark: %s to include in graph with lat:%s lon:%s to the center of the travelled area lat:%s lon:%s with boundary: %s, %s, %s, %s', node.tags, node_lat, node_lon, middle_lat, middle_lon, lon_min, lat_min, lon_max, lat_max)
            nearest_landmark_debug = str(node.tags['name'])

    logger.debug('Adjusting map edges using node: %s', node)

    if node is None:
        logger.warning('Failed to locate the nearest landmark to (%s, %s) within radius: %s', middle_lon_degrees, middle_lat_degrees, radius)
        # You can debug this using the overpass API : https://overpass-turbo.eu/#
        # The query might look something like:
        # [out:json][timeout:30];
        # (
        #  node(around:<radius>,<latitude>,<longitude>) ["place"];
        # );
        # out body;

    else:
        # So lets first adjust bbox to fit in the new node
        node_lat = float(node_lat)
        node_lon = float(node_lon)

        if node_lat < lat_min:
            diff = lat_min - node_lat
            lat_min -= (diff + (diff / 4))
            lat_max += (diff / 4)

        if node_lat > lat_max:
            diff = node_lat - lat_max
            lat_min -= (diff / 4)
            lat_max += (diff + (diff / 4))

        if node_lon < lon_min:
            diff = lon_min - node_lon
            lon_min -= (diff + (diff / 4))
            lon_max += (diff / 4)

        if node_lon > lon_max:
            diff = node_lon - lon_max
            lon_min -= (diff / 4)
            lon_max += (diff + (diff / 4))

    return (lon_min, lon_max, lat_min, lat_max, nearest_landmark_debug)

def GenMap(sonar_data, include_nearest_landmark=True):
    gps_longitude_range = sonar_data.longitude.min().values.item(), sonar_data.longitude.max().values.item()
    gps_latitude_range = sonar_data.latitude.min().values.item(), sonar_data.latitude.max().values.item()
    lon_min = gps_longitude_range[0]
    lon_max = gps_longitude_range[1]
    lat_min = gps_latitude_range[0]
    lat_max = gps_latitude_range[1]

    nearest_landmark_debug = ''
    if include_nearest_landmark:
        lon_min, lon_max, lat_min, lat_max, nearest_landmark_debug = AdjustToIncludeNearestLandmark(lon_min, lon_max, lat_min, lat_max)
        if nearest_landmark_debug != '':
            nearest_landmark_debug = '. With nearest landmark: ' + nearest_landmark_debug

    logger.debug('Generating graph inside area: (%s, %s) - (%s, %s)%s', lon_min, lat_min, lon_max, lat_max, nearest_landmark_debug)

    tiles = holoviews.Tiles('https://maps.wikimedia.org/osm-intl/{Z}/{X}/{Y}@2x.png', name="Wikipedia")
    tiles = tiles.opts(width=600, height=600)

    # Adjust the framing of the tiles to show the path area and not the entire world
    # From: https://examples.pyviz.org/nyc_taxi/nyc_taxi.html
    #left, bottom = datashader.geo.lnglat_to_meters(lon_min, lat_min)
    #right, top = datashader.geo.lnglat_to_meters(lon_max, lat_max)
    # @todo cleanup, we are now using web mercator metres everywhere
    left, bottom = (lon_min, lat_min)
    right, top = (lon_max, lat_max)

    # http://holoviews.org/_modules/holoviews/core/dimension.html
    tiles = tiles.redim(
        x=holoviews.Dimension('x', range=(left, right)),
        y=holoviews.Dimension('y', range=(bottom, top))
        )

    logger.debug('left:%s right:%s bottom:%s top:%s', left, right, bottom, top)
    #import code
    #code.interact(local=dict(globals(), **locals()))

    channel = sonar_data.sel(channel=sonar.lowrance_log_parser.PRIMARY)
    latitude_arr = channel.latitude.values
    longitude_arr = channel.longitude.values
    frame_index_arr = channel.frame_index.values
    depth_arr = channel.water_depth.values

    #logger.info('Creating vector field for the path')
    #x_arr = []
    #y_arr = []
    #angle_arr = []
    #magnitude_arr = []
    #for i in range(0, len(frame_index_arr)):
    #    x,y = datashader.geo.lnglat_to_meters(longitude_arr[i], latitude_arr[i])
    #    angle = channel.heading.values[i]
    #    magnitude = channel.speed_gps.values[i]
    #    x_arr.append(x)
    #    y_arr.append(y)
    #    angle_arr.append(angle)
    #    magnitude_arr.append(magnitude)
    ## http://holoviews.org/reference/elements/bokeh/VectorField.html
    #path = holoviews.VectorField((x_arr, y_arr, angle_arr, magnitude_arr))
    #path = path.opts(magnitude='Magnitude', color='Magnitude')
    #logger.info('Done')

    path_points = []
    for i in range(0, len(frame_index_arr)):
        # @todo cleanup
        #path_points.append(datashader.geo.lnglat_to_meters(longitude_arr[i], latitude_arr[i]))
        path_points.append((longitude_arr[i], latitude_arr[i], depth_arr[i]))
    path = holoviews.Path(path_points, vdims='depth', kdims=[
        holoviews.Dimension('easting'),
        holoviews.Dimension('northing')])
    path = path.opts(color='depth', width=600, height=600, cmap='viridis')

    # See https://holoviz.org/tutorial/Composing_Plots.html for the easting/northing plot
    # @todo Note: Sometimes the x/y axis in overlay changes to use the path values not the tiles values which is not what we want we want to displat lon/lat not northings eastings
    overlay = tiles * path
    return overlay