import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import pickle
import seaborn as sns

import matplotlib.pyplot as plt

from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor
from sklearn.metrics import plot_confusion_matrix
# Different classification metrics
# Accuracy, Reciver Operating Characteristic (ROC curve)/Area under curve (AUC), Confusion matrix, Classification report
from sklearn.metrics import accuracy_score, roc_curve, roc_auc_score, confusion_matrix, classification_report, mean_absolute_error
from sklearn.preprocessing import OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.model_selection import cross_val_score
# Let's try the Ridge Regression model
from sklearn.linear_model import Ridge
# Import the LinearSVC estimator class
from sklearn.svm import LinearSVC

# Import Boston housing dataset
from sklearn.datasets import load_boston

# Fill missing values with Scikit-Learn
from sklearn.impute import SimpleImputer
from sklearn.compose import ColumnTransformer

selector = 1

def plot_roc_curve(fpr, tpr):
    """
    Plots a ROC curve given the false positive rate (fpr)
    and true positive rate (tpr) of a model.
    """
    # Plot roc curve
    plt.plot(fpr, tpr, color="orange", label="ROC")
    # Plot line with no predictive power (baseline)
    # plt.plot([0, 1], [0, 1], color="darkblue", linestyle="--", label="Guessing")

    # Customize the plot
    plt.xlabel("False positive rate (fpr)")
    plt.ylabel("True positive rate (tpr)")
    plt.title("Receiver Operating Characteristic (ROC) Curve")
    plt.legend()
    plt.show()

def plot_conf_mat(conf_mat):
    """
    Plots a confusion matrix using Seaborn's heatmap().
    """
    fig, ax = plt.subplots(figsize=(3, 3))
    ax = sns.heatmap(conf_mat,
                     annot=True,  # Annotate the boxes with conf_mat info
                     cbar=False)
    plt.xlabel("Predicted label")
    plt.ylabel("True label")

    # Fix the broken annotations (this happened in Matplotlib 3.1.1)
    bottom, top = ax.get_ylim()
    ax.set_ylim(bottom + 0.5, top - 0.5)
    plt.show()

def main_fn(string0: str = "fn") -> None:

    # Import dataset
    heart_disease = pd.read_csv("./data/heart-disease.csv")

    # View the data
    print(string0)
    print(heart_disease.head())

    # Create X (all the feature columns)
    X = heart_disease.drop("target", axis=1)

    # Create y (the target column)
    y = heart_disease["target"]

    # Split the data into training and test sets
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

    # View the data shapes
    print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)

    # Choose the model/estimator
    model = RandomForestClassifier(n_estimators=100)

    # default parameters
    print(model.get_params())

    model.fit(X_train, y_train)

    # Make predictions
    y_preds = model.predict(X_test)

    # This will be in the same format as y_test
    print(y_preds)

    # print(X_test.loc[1])

    print(heart_disease.loc[206])

    # Make a prediction on a single sample (has to be array)
    # model.predict(np.array(X_test.loc[206]).reshape(1, -1))

    # On the training set
    print(model.score(X_train, y_train))

    # On the test set (unseen)
    print(model.score(X_test, y_test))

    print(classification_report(y_test, y_preds))

    print(confusion_matrix(y_test, y_preds))

    print(accuracy_score(y_test, y_preds))

    # Try different numbers of estimators (n_estimators is a hyperparameter you can change)
    np.random.seed(42)
    for i in range(10, 100, 10):
        print(f"Trying model with {i} estimators...")
        model = RandomForestClassifier(n_estimators=i).fit(X_train, y_train)
        print(f"Model accruacy on test set: {model.score(X_test, y_test)}")
        print("")

    # Try different numbers of estimators with cross-validation and no cross-validation
    np.random.seed(42)
    for i in range(10, 100, 10):
        print(f"Trying model with {i} estimators...")
        model = RandomForestClassifier(n_estimators=i).fit(X_train, y_train)
        print(f"Model accruacy on test set: {model.score(X_test, y_test)}")
        print(f"Cross-validation score: {np.mean(cross_val_score(model, X, y, cv=5)) * 100}%")
        print("")

    # Save trained model to file
    pickle.dump(model, open("random_forest_model_1.pkl", "wb"))

    # Load a saved model and make a prediction on a single example
    loaded_model = pickle.load(open("random_forest_model_1.pkl", "rb"))
    print(loaded_model.score(X_test, y_test))
    # loaded_model.predict(np.array(X_test.loc[206]).reshape(1, -1))

    print("1.-", model.score(X_test, y_test))
    # Compare predictions to truth labels to evaluate the model
    y_preds = model.predict(X_test)
    print("2.-", np.mean(y_preds == y_test))
    print("3.-", accuracy_score(y_test, y_preds))

    # predict_proba() returns probabilities of a classification label
    print(model.predict_proba(X_test[:5]))

    # Let's predict() on the same data...
    print(model.predict(X_test[:5]))

    print(heart_disease["target"].value_counts())

    print(mean_absolute_error(y_test, y_preds))

    # Single training and test split score
    model_single_score = model.score(X_test, y_test)

    # Take the mean of 5-fold cross-validation score
    model_cross_val_score = np.mean(cross_val_score(model, X, y, cv=5))

    print(model_single_score, model_cross_val_score)
    print(f"Heart Disease Classifier Cross-Validated Accuracy: {model_cross_val_score * 100:.2f}%")

    # Make predictions with probabilities
    y_probs = model.predict_proba(X_test)

    y_probs_positive = y_probs[:, 1]

    # Caculate fpr, tpr and thresholds
    fpr, tpr, thresholds = roc_curve(y_test, y_probs_positive)
    print("roc_auc_score: ", roc_auc_score(y_test, y_probs_positive))

    plot_roc_curve(fpr, tpr)

    # Plot perfect ROC curve and AUC score
    fpr, tpr, thresholds = roc_curve(y_test, y_test)
    plot_roc_curve(fpr, tpr)
    # Perfect AUC score
    print(roc_auc_score(y_test, y_test))

    y_preds = model.predict(X_test)

    print("confusion_matrix", confusion_matrix(y_test, y_preds))
    # Visualize confusion matrix with pd.crosstab()
    print(pd.crosstab(y_test,
                y_preds,
                rownames=["Actual Labels"],
                colnames=["Predicted Labels"]))

    # Set the font scale
    sns.set(font_scale=1.5)

    # Create a confusion matrix
    conf_mat = confusion_matrix(y_test, y_preds)

    # Plot it using Seaborn
    sns.heatmap(conf_mat)

    plot_conf_mat(conf_mat)

    plot_confusion_matrix(model, X, y)
    plt.show()

def second_fn(string1: str = "fn") -> None:
    # data converted to numerical data
    # Turn the categories into numbers
    print(string1)
    categorical_features = ["Make", "Colour", "Doors"]
    one_hot = OneHotEncoder()
    transformer = ColumnTransformer([("one_hot",
                                      one_hot,
                                      categorical_features)],
                                    remainder="passthrough")

    # Import data and drop the rows with missing labels
    data = pd.read_csv("./data/car-sales-extended.csv")

    print(data.head(), "len: " + str(len(data)), sep='\n')

    X = data.drop("Price", axis=1)
    y = data["Price"]

    transformed_X = transformer.fit_transform(X)
    # print(transformed_X)
    print(pd.DataFrame(transformed_X))
    print(X.head())

    # Another way to do it with pd.dummies...
    dummies = pd.get_dummies(data[["Make", "Colour", "Doors"]])
    print(dummies)

    # Split the data into training and test sets
    X_train, X_test, y_train, y_test = train_test_split(transformed_X, y, test_size=0.2)

    model = RandomForestRegressor()

    model.fit(X_train, y_train)
    print(model.score(X_test, y_test))

def third_fn(string2: str = "fn") -> None:
    # Import car sales missing data
    print(string2)
    car_sales_missing = pd.read_csv("./data/car-sales-extended-missing-data.csv")
    print(car_sales_missing.head())

    print("1", car_sales_missing.isna().sum())

    # Fill the "Make" column
    car_sales_missing["Make"].fillna("missing", inplace=True)

    # Fill the "Colour" column
    car_sales_missing["Colour"].fillna("missing", inplace=True)

    # Fill the "Odometer (KM)" column
    car_sales_missing["Odometer (KM)"].fillna(car_sales_missing["Odometer (KM)"].mean(), inplace=True)

    # Fill the "Doors" column
    car_sales_missing["Doors"].fillna(4, inplace=True)

    print("2", car_sales_missing.isna().sum())

    # Remove rows with missing Price value
    car_sales_missing.dropna(inplace=True)

    # Check our dataframe again
    print(3, car_sales_missing.isna().sum())
    print(car_sales_missing.shape, car_sales_missing.shape[0], np.size(car_sales_missing, 0), len(car_sales_missing))

    X = car_sales_missing.drop("Price", axis=1)
    y = car_sales_missing["Price"]

    categorical_features = ["Make", "Colour", "Doors"]
    one_hot = OneHotEncoder()
    transformer = ColumnTransformer([("one_hot",
                                      one_hot,
                                      categorical_features)],
                                    remainder="passthrough")

    transformed_X = transformer.fit_transform(X)

def fourth_fn(string3: str = "fn") -> None:
    car_sales_missing = pd.read_csv("./data/car-sales-extended-missing-data.csv")
    print(car_sales_missing.head())
    print(car_sales_missing.isna().sum())

    # Drop the rows with no labels
    car_sales_missing.dropna(subset=["Price"], inplace=True)
    print(car_sales_missing.isna().sum())

    # Split into X & y
    X = car_sales_missing.drop("Price", axis=1)
    y = car_sales_missing["Price"]

    # Split data into train and test
    np.random.seed(42)
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

    # Fill categorical values with 'missing' & numerical values with mean
    cat_imputer = SimpleImputer(strategy="constant", fill_value="missing")
    door_imputer = SimpleImputer(strategy="constant", fill_value=4)
    num_imputer = SimpleImputer(strategy="mean")

    # Define columns
    cat_features = ["Make", "Colour"]
    door_feature = ["Doors"]
    num_features = ["Odometer (KM)"]

    # Create an imputer (something that fills missing data)
    imputer = ColumnTransformer([
        ("cat_imputer", cat_imputer, cat_features),
        ("door_imputer", door_imputer, door_feature),
        ("num_imputer", num_imputer, num_features)
    ])

    # Fill train and test values separately
    filled_X_train = imputer.fit_transform(X_train)
    filled_X_test = imputer.transform(X_test)

    print(filled_X_train)

    # Get our transformed data array's back into DataFrame's
    car_sales_filled_train = pd.DataFrame(filled_X_train, columns=["Make", "Colour", "Doors", "Odometer (KM)"])

    car_sales_filled_test = pd.DataFrame(filled_X_test, columns=["Make", "Colour", "Doors", "Odometer (KM)"])

    # Check missing data in training set
    print(car_sales_filled_train.isna().sum())

    car_sales_filled_train.to_csv(r'./data/car-sales-extended-no-missing-data.csv', index=False, header=True)

    # Check to see the original... still missing values
    # car_sales_missing.isna().sum()
    # Now let's one hot encode the features with the same code as before
    categorical_features = ["Make", "Colour", "Doors"]
    one_hot = OneHotEncoder()
    transformer = ColumnTransformer([("one_hot",
                                      one_hot,
                                      categorical_features)],
                                    remainder="passthrough")

    # Fill train and test values separately
    transformed_X_train = transformer.fit_transform(car_sales_filled_train)
    transformed_X_test = transformer.transform(car_sales_filled_test)

    # Check transformed and filled X_train
    transformed_X_train.toarray()

    # Now we've transformed X, let's see if we can fit a model
    np.random.seed(42)

    model = RandomForestRegressor(n_estimators=100)

    # Make sure to use transformed (filled and one-hot encoded X data)
    model.fit(transformed_X_train, y_train)
    print(model.score(transformed_X_test, y_test))

def fiveth_fn(string4: str = "fn") -> None:
    boston = load_boston()

    print(type(boston))

    boston_df = pd.DataFrame(boston["data"], columns=boston["feature_names"])
    boston_df["target"] = pd.Series(boston["target"])

    print(boston_df.head())

    # How many samples?
    print("len", len(boston_df))
    print(np.size(boston_df, 0), boston_df.shape[0], boston_df.shape[1], boston_df.size, sep="\n")

    # Setup random seed
    np.random.seed(42)

    # Create the data
    X = boston_df.drop("target", axis=1)
    y = boston_df["target"]

    # Split into train and test sets
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

    # Instantiate Ridge model
    model = Ridge()
    model.fit(X_train, y_train)

    # Check the score of the Ridge model on test data
    print(model.score(X_test, y_test))

def sixth_fn(string5: str = "fn") -> None:
    # Setup random seed
    np.random.seed(42)

    boston = load_boston()

    boston_df = pd.DataFrame(boston["data"], columns=boston["feature_names"])
    boston_df["target"] = pd.Series(boston["target"])

    # Create the data
    X = boston_df.drop("target", axis=1)
    y = boston_df["target"]

    # Split the data
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

    # Instatiate Random Forest Regressor
    rf = RandomForestRegressor(n_estimators=100)
    rf.fit(X_train, y_train)

    # Evaluate the Random Forest Regressor
    rf.score(X_test, y_test)

def seventh_fn(string6: str = "fn") -> None:
    # Setup random seed
    np.random.seed(42)

    # Import dataset
    heart_disease = pd.read_csv("./data/heart-disease.csv")

    # Make the data
    X = heart_disease.drop("target", axis=1)
    y = heart_disease["target"]

    # Split the data
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

    # Instantiate LinearSVC
    clf = LinearSVC(max_iter=10000)
    clf.fit(X_train, y_train)

    # Evaluate the LinearSVC
    print("1.-", clf.score(X_test, y_test))
    # Compare predictions to truth labels to evaluate the model
    y_preds = clf.predict(X_test)
    print("2.-", np.mean(y_preds == y_test))
    print("3.-", accuracy_score(y_test, y_preds))

    # predict_proba() returns probabilities of a classification label
    clf.predict_proba(X_test[:5])

# Press the green button in the gutter to run the script.
if __name__ == '__main__':

    if selector == 1:
        main_fn('dummy0')
    elif selector == 2:
        second_fn('dummy1')
    elif selector == 3:
        third_fn('dummy2')
    elif selector == 4:
        fourth_fn('dummy3')
    elif selector == 5:
        fiveth_fn('dummy4')
    elif selector == 6:
        sixth_fn('dummy5')
    elif selector == 7:
        seventh_fn('dummy6')
# See PyCharm help at https://www.jetbrains.com/help/pycharm/


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Sep 16 17:32:20 2018

@author:
Chung Yang 31732286
Yi-Pei Chen 31739156
Hao Cheng Cheam 31749564
Wenting Wang 31930946

# Coding question 3.27

"""

from scipy import misc
import matplotlib.pyplot as plt
import numpy as np
from numpy.linalg import norm
from numpy.linalg import svd
from q3_17_powersvd import powersvd # own svd function

# Show input image
def showImg(image):
    print('Input image:')
    plt.figure(1)
    plt.imshow(image, cmap='gray')
    plt.title("The input image")
    plt.draw()
    print(' ')

# Perform SVD, then reconstruct image in several levels and show it
def reconImg(image, pct, figure_n):
    plt.figure(figure_n)
    # SVD
    n, m = image.shape
    u, s, vh = svd(image, full_matrices=True)
#    u, s, vh = powersvd(image, m) # very slow

    # Reconstruct
    idx = int(min(n,m) * pct)
    img_recon = u[:, :idx].dot(np.diag(s[:idx])).dot(vh[:idx,:])
    print('Use Top {:.0%} of the singular values.'.format(pct), '\n')

    # Percentage of Frobenius norm
    fb_norm_pct = norm(s[:idx])/norm(s)
    print('{:.5%} percent of the Forbenius norm is captured.'.format(fb_norm_pct))

    # Show image
    plt.imshow(img_recon, cmap='gray')
    plt.title('Top {:.0%} of the singular values.'.format(pct) + '\n' + \
              '{:.5%} percent of the Forbenius norm is captured.'.format(fb_norm_pct))
    plt.draw()

if __name__ == "__main__":
    # Read Image
    # (put the image file to the folder os.getcwd())
    img = misc.imread('image.jpg', 1)
    showImg(img) # show the input image

    percentages = [0.05, 0.10, 0.25, 0.50]
    figure_n = 2
    for pct in percentages:
        reconImg(img, pct, figure_n) # show the reconstructed image
        figure_n += 1
    plt.show()


from sklearn.utils import shuffle
import torch
from torch import nn
import numpy as np
import copy
import random

class SentenceFocus():

    def __init__(self,opts) -> None:

        self.beta = opts.sief_beta

        if opts.use_model == "bert":
            self.use_bert = True
        else:
            self.use_bert = False

        self.no_na_loss = opts.no_na_loss
        self.relation_nums = opts.relation_nums

        self.entropy = nn.BCEWithLogitsLoss(reduction='none')

    def prepro_data(self,data):
        newdata = copy.deepcopy(data)
        N_bt = data["context_idxs"].shape[0]

        for i in range(N_bt):
            rand_mask_sentence(data, newdata, i,self.use_bert)

        max_len = torch.max(newdata["context_word_length"]).item()

        newdata["context_idxs"] = newdata["context_idxs"][:,:max_len]
        newdata["context_sent"] = newdata["context_sent"][:,:max_len]
        newdata["context_word_mask"] = newdata["context_word_mask"][:,:max_len]
        newdata["context_mention"] = newdata["context_mention"][:,:max_len]
        newdata["context_pos"] = newdata["context_pos"][:,:max_len]
        newdata["context_ner"] = newdata["context_ner"][:,:max_len]

        return newdata
    def importance_estimation(self,predictions,predictions_hat):
        p = torch.sigmoid(predictions)
        p_hat = torch.sigmoid(predictions_hat)
        score = p*torch.log(p/(p_hat+1e-11))
        return score
    def sentence_focusing(self,predictions,predictions_hat,relation_mask_hat,relation_multi_label):
        importance_score = self.importance_estimation(predictions,predictions_hat)
        evidence_mask = torch.logical_and((importance_score>self.beta),(relation_multi_label>0))
        evidence_mask[...,0] = False

        instance_mask = relation_mask_hat.unsqueeze(2).repeat(1,1,self.relation_nums)
        instance_mask[evidence_mask] = 0

        if self.no_na_loss:
            loss_sf = torch.sum(self.entropy(predictions_hat[...,1:], torch.sigmoid(predictions)[...,1:]) * instance_mask[...,1:]) / torch.sum(instance_mask[...,1:])
        else:
            loss_sf = torch.sum(self.entropy(predictions_hat, torch.sigmoid(predictions)) * instance_mask) / torch.sum(instance_mask)

        return loss_sf

def rand_mask_sentence(data,newdata,nb,use_bert,delete_id=None):
    N_sent = torch.max(data["context_sent"][nb]).item()
    N_words = data["context_sent"][nb].shape[0]
    if delete_id is None:
        delete_id = np.random.randint(N_sent)
    else:
        assert delete_id < N_sent
    sent_len = []
    for i in range(N_sent):
        sent_len.append(torch.sum(data["context_sent"][nb]==(i+1)).item())
    if use_bert:
        L_sent = [1]
        sent_len[0] -= 1
        sent_len[-1] -= 1
    else:
        L_sent = [0]
    left_len = np.sum(sent_len[delete_id+1:])
    sent_dict = np.arange(N_sent)
    sent_dict[delete_id] = -1
    sent_dict[delete_id+1:] -= 1
    for sent_id in range(N_sent):
        L_sent.append(L_sent[-1]+sent_len[sent_id])

    word_dict = np.arange(N_words)
    if left_len == 0:
        start1 = L_sent[delete_id]
        word_dict[start1:] = 0
        newdata["context_idxs"][nb,start1:] = 0
        if use_bert:
            new_w_sum = torch.sum(newdata["context_idxs"][nb]>0).item()
            w_sum = torch.sum(data["context_idxs"][nb]>0).item()
            newdata["context_idxs"][nb,new_w_sum] = data["context_idxs"][nb,w_sum-1]
        newdata["context_sent"][nb,start1:] = 0
        newdata["context_word_length"][nb] = torch.sum(newdata["context_idxs"][nb]>0,dim=-1)
        newdata["context_word_mask"][nb] = newdata["context_idxs"][nb]>0
        newdata["context_mention"][nb,start1:] = 0
        newdata["context_pos"][nb,start1:] = 0
        newdata["context_ner"][nb,start1:] = 0
    else:
        start1 = L_sent[delete_id]
        start2 = L_sent[delete_id+1]
        word_dict[start2:start2+left_len] = word_dict[start1:start1+left_len]
        word_dict[start1:start2] = 0
        newdata["context_idxs"][nb,start1:start1+left_len] = data["context_idxs"][nb,start2:start2+left_len]
        newdata["context_idxs"][nb,start1+left_len:] = 0
        if use_bert:
            new_w_sum = torch.sum(newdata["context_idxs"][nb]>0).item()
            w_sum = torch.sum(data["context_idxs"][nb]>0).item()
            newdata["context_idxs"][nb,new_w_sum] = data["context_idxs"][nb,w_sum-1]

        newdata["context_sent"][nb,start1:start1+left_len] = data["context_sent"][nb,start2:start2+left_len]-1
        newdata["context_sent"][nb,start1+left_len:] = 0
        if use_bert:
            newdata["context_sent"][nb,new_w_sum] = data["context_sent"][nb,w_sum-1]-1

        newdata["context_word_length"][nb] = torch.sum(newdata["context_idxs"][nb]>0,dim=-1)
        newdata["context_word_mask"][nb] = newdata["context_idxs"][nb]>0

        newdata["context_mention"][nb,start1:start1+left_len] = data["context_mention"][nb,start2:start2+left_len]
        newdata["context_mention"][nb,start1+left_len:] = 0
        newdata["context_pos"][nb,start1:start1+left_len] = data["context_pos"][nb,start2:start2+left_len]
        newdata["context_pos"][nb,start1+left_len:] = 0
        newdata["context_ner"][nb,start1:start1+left_len] = data["context_ner"][nb,start2:start2+left_len]
        newdata["context_ner"][nb,start1+left_len:] = 0

    left_entity_set = []
    total_entity_set= []
    delete_node = []
    for n_id in range(newdata["graph_info"].shape[1]):
        if newdata["graph_info"][nb,n_id,5].item() == -1:
            continue
        newdata["graph_info"][nb,n_id,0] = word_dict[data["graph_info"][nb,n_id,0]]
        newdata["graph_info"][nb,n_id,1] = word_dict[data["graph_info"][nb,n_id,1]-1]+1
        newdata["graph_info"][nb,n_id,5] = sent_dict[data["graph_info"][nb,n_id,5]]
        if newdata["graph_info"][nb,n_id,5].item() == -1:
            newdata["graph_info"][nb,n_id,0] = -1
            newdata["graph_info"][nb,n_id,1] = -1
            newdata["graph_info"][nb,n_id,2] = -1
            newdata["graph_adj"][nb,n_id,:] = 0
            newdata["graph_adj"][nb,:,n_id] = 0
            delete_node.append(n_id)

        if newdata["graph_info"][nb,n_id,3]==1:
            continue
        elif newdata["graph_info"][nb,n_id,3]==2:
            total_entity_set.append(newdata["graph_info"][nb,n_id,2].item())
            if newdata["graph_info"][nb,n_id,5].item() != -1:
                left_entity_set.append(newdata["graph_info"][nb,n_id,2].item())
        else:
            break
    delete_entity = set(total_entity_set) - set(left_entity_set) -set([-1])
    for it in delete_entity:
        p_ind,_ = torch.where(newdata['h_t_pairs'][nb]==it)
        newdata['relation_mask'][nb,p_ind] = 0
    for it in delete_node:
        if it == 0:
            continue
        p_ind,m_ind,_ = torch.where(newdata['relation_path'][nb]==it)
        newdata['relation_path'][nb,p_ind,m_ind] = 0
    return newdata

def rand_shuffle_sentence(data,newdata,nb,use_bert=False):
    N_sent = torch.max(data["context_sent"][nb]).item()
    N_words = data["context_sent"][nb].shape[0]
    new_sent_seq = list(range(N_sent))
    random.shuffle(new_sent_seq)
    sent_len = []
    for i in range(N_sent):
        sent_len.append(torch.sum(data["context_sent"][nb]==(i+1)).item())
    if use_bert:
        L_sent = [1]
        new_L_sent = [1]
    else:
        L_sent = [0]
        new_L_sent = [0]
    for sent_id in range(N_sent):
        L_sent.append(L_sent[-1]+sent_len[sent_id])
        new_L_sent.append(new_L_sent[-1]+sent_len[new_sent_seq[sent_id]])
    word_dict = np.arange(N_words)
    for sent_id in range(N_sent):
        cur_id = new_sent_seq[sent_id]
        word_dict[L_sent[cur_id]:L_sent[cur_id+1]] = \
            torch.arange(new_L_sent[sent_id],new_L_sent[sent_id+1])
        newdata["context_sent"][nb,new_L_sent[sent_id]:new_L_sent[sent_id+1]]=sent_id+1
        newdata["context_idxs"][nb,new_L_sent[sent_id]:new_L_sent[sent_id+1]]=\
        data["context_idxs"][nb,L_sent[cur_id]:L_sent[cur_id+1]]
        newdata["context_mention"][nb,new_L_sent[sent_id]:new_L_sent[sent_id+1]]=\
        data["context_mention"][nb,L_sent[cur_id]:L_sent[cur_id+1]]
        newdata["context_pos"][nb,new_L_sent[sent_id]:new_L_sent[sent_id+1]]=\
        data["context_pos"][nb,L_sent[cur_id]:L_sent[cur_id+1]]
        newdata["context_ner"][nb,new_L_sent[sent_id]:new_L_sent[sent_id+1]]=\
        data["context_ner"][nb,L_sent[cur_id]:L_sent[cur_id+1]]
    for n_id in range(newdata["graph_info"].shape[1]):
        if newdata["graph_info"][nb,n_id,5] == -1:
            continue
        sent_id = new_sent_seq.index(data["graph_info"][nb,n_id,5])
        if data["graph_info"][nb,n_id,3]==1:
            newdata["graph_info"][nb,n_id,0] = new_L_sent[sent_id]
            newdata["graph_info"][nb,n_id,1] = new_L_sent[sent_id+1]
            newdata["graph_info"][nb,n_id,5] = sent_id
        elif newdata["graph_info"][nb,n_id,3]==2:
            newdata["graph_info"][nb,n_id,0] = word_dict[data["graph_info"][nb,n_id,0]]
            newdata["graph_info"][nb,n_id,1] = word_dict[data["graph_info"][nb,n_id,1]-1]+1
            newdata["graph_info"][nb,n_id,5] = sent_id
        else:
            break
    for n_id in range(newdata["context_ems_info"].shape[1]):
        if newdata["context_ems_info"][nb,n_id,0]==1:
            continue
        elif newdata["context_ems_info"][nb,n_id,0]==2 and newdata["graph_info"][nb,n_id,5] != -1:
            newdata["context_ems_info"][nb,n_id,2] = word_dict[data["context_ems_info"][nb,n_id,2]]
            newdata["context_ems_info"][nb,n_id,3] = word_dict[data["context_ems_info"][nb,n_id,3]-1]+1
            newdata["context_ems_info"][nb,n_id,6] = new_sent_seq.index(data["context_ems_info"][nb,n_id,6])
        elif newdata["context_ems_info"][nb,n_id,0]==3 and newdata["graph_info"][nb,n_id,5] != -1:
            newdata["context_ems_info"][nb,n_id,2] = word_dict[data["context_ems_info"][nb,n_id,2]]
            newdata["context_ems_info"][nb,n_id,3] = word_dict[data["context_ems_info"][nb,n_id,3]-1]+1
        else:
            break
    return newdata


#   Here are suggested sensor values:
#       Min  Typ  Max  Condition
#       0    0    0    sensor in open air
#       0    20   300  sensor in dry soil
#       300  580  700  sensor in humid soil
#       700  940  950  sensor in water

import time
import grovepi

# Connect the Grove Moisture Sensor to analog port A0
# SIG,NC,VCC,GND
sensor = 0

while True:
    try:
        print(grovepi.analogRead(sensor))
        time.sleep(.5)

    except KeyboardInterrupt:
        break
    except IOError:
        print ("Error")


from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

from .models import PVPGameStats, PVCGameStats
from user_profile.models import User
from .serializers import PVPGameStatsSerializer, PVCGameStatsSerializer

GAME_REWARD_POINTS_AMOUNT = 1
GAME_PENALTY_POINTS_AMOUNT = -1
GAME_TIE_POINTS_AMOUNT = 0

class PVPGameStatsView(APIView):

    def post(self, request, *args, **kwargs):
        winner_wallet_address = request.data.get('winner_wallet_address')
        loser_wallet_address = request.data.get('loser_wallet_address')

        winner = User.objects.get(wallet_address=winner_wallet_address)
        loser = User.objects.get(wallet_address=loser_wallet_address)

        winner.add_points(GAME_REWARD_POINTS_AMOUNT)
        loser.add_points(GAME_PENALTY_POINTS_AMOUNT)

        winner.save()
        loser.save()

        game_stats = PVPGameStats.objects.create()
        game_stats.winner.add(winner)
        game_stats.loser.add(loser)

        serializer = PVPGameStatsSerializer(game_stats)

        return Response(serializer.data, status=status.HTTP_201_CREATED)

class PVCGameStatsView(APIView):

    def post(self, request, *args, **kwargs):
        player_wallet_address = request.data.get('player_wallet_address')
        is_winner = request.data.get('is_winner')

        player = User.objects.get(wallet_address=player_wallet_address)

        if is_winner == 'True':
            player.add_points(GAME_REWARD_POINTS_AMOUNT)
        elif is_winner == 'False':
            player.add_points(GAME_PENALTY_POINTS_AMOUNT)
        else:
            player.add_points(GAME_TIE_POINTS_AMOUNT)

        player.save()

        game_stats = PVCGameStats.objects.create(is_winner=is_winner)
        game_stats.player.add(player)

        serializer = PVCGameStatsSerializer(game_stats)

        return Response(serializer.data, status=status.HTTP_201_CREATED)


import torch
from torch import nn

class Conv2d(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, stride, has_relu=True):
        super().__init__()

        self.net = nn.Sequential(nn.ReflectionPad2d(kernel_size//2),
                                 nn.Conv2d(in_channels, out_channels, kernel_size, stride),
                                 nn.InstanceNorm2d(out_channels, affine=True))

        self.relu = nn.ReLU() if has_relu else None

    def forward(self, x):
        x = self.net(x)

        if self.relu:
            x = self.relu(x)

        return x

class Residual(nn.Module):
    def __init__(self, in_channels, out_channels):
        super().__init__()

        i = in_channels
        o = out_channels

        self.net = nn.Sequential(nn.Conv2d(i, o, 3, 1, 1),
                                 nn.InstanceNorm2d(o, affine=True),
                                 nn.ReLU(),
                                 nn.Conv2d(o, o, 3, 1, 1),
                                 nn.InstanceNorm2d(o, affine=True))

    def forward(self, x):
        return self.net(x) + x

class Deconv2d(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, scale_factor, has_relu=True):
        super().__init__()

        self.net = nn.Sequential(nn.Upsample(scale_factor=scale_factor),
                                 nn.ReflectionPad2d(kernel_size // 2),
                                 nn.Conv2d(in_channels, out_channels, kernel_size),
                                 nn.InstanceNorm2d(out_channels, affine=True))

        self.relu = nn.ReLU() if has_relu else None

    def forward(self, x):
        x = self.net(x)

        if self.relu:
            x = self.relu(x)

        return x

# https://cs.stanford.edu/people/jcjohns/papers/fast-style/fast-style-supp.pdf
class StyleTransfer(nn.Module):
    name = 'style_transfer'

    def __init__(self):
        super().__init__()

        # to fit output in range(0, 1) Sigmoid is used instead of Tanh
        self.net = nn.Sequential(Conv2d(3, 32, 9, 1),
                                 Conv2d(32, 64, 3, 2),
                                 Conv2d(64, 128, 3, 2),

                                 Residual(128, 128),
                                 Residual(128, 128),
                                 Residual(128, 128),
                                 Residual(128, 128),
                                 Residual(128, 128),

                                 Deconv2d(128, 64, 3, 2.),
                                 Deconv2d(64, 32, 3, 2.),
                                 Conv2d(32, 3, 9, 1, False),

                                 nn.Sigmoid())

    def forward(self, x):
        return self.net(x)


# TF-IDF vectorizer child created solely to avoid
# repetitively defining the stemmer and tokenizer defaults

import re
import nltk.tokenize
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer

default_tokenizer = TfidfVectorizer().build_tokenizer()
stemmer = nltk.stem.SnowballStemmer("english", ignore_stopwords=True)

# standard nltk stop words plus some common useless words
base_stop_words = nltk.corpus.stopwords.words('english') + \
  [
    'ever','sure','want','review','got','somewhat','along',
    'see','know','something','beer'
  ]

def nonnum_stem_tokenizer(text):
    """
    use the default tokenizer from TfidfVectorizer, combined with the nltk SnowballStemmer.
    """
    def non_num_tokenizer(text):
      return default_tokenizer(re.sub(r'\d', '', text))

    return map(stemmer.stem, non_num_tokenizer(text))

class ReviewTfidf(TfidfVectorizer):
  def __init__(self,
        max_features=None,
        ngram_range=(1,1),
        min_df=0.00,
        max_df=1.0,
        tokenizer=nonnum_stem_tokenizer,
        stop_words=[],
        use_idf = True,
        sublinear_tf = False,
        binary=False,
        vocabulary=None,
        **kwargs):

    # standard nltk stop words plus some common useless words
    stop_words.extend(base_stop_words)

    super(ReviewTfidf, self).__init__(
      max_features=max_features,
      ngram_range=ngram_range,
      min_df=min_df,
      max_df=max_df,
      tokenizer=tokenizer,
      stop_words=map(stemmer.stem, stop_words),
      use_idf = use_idf,
      sublinear_tf = sublinear_tf,
      binary=binary,
      vocabulary=vocabulary,
      **kwargs)

  def feature_vals(self):
    idf = self._tfidf.idf_
    w_lst = zip(self.get_feature_names(), idf)

    return { w[0]: w[1] for w in w_lst }

# count vectorizer
class ReviewCountVec(CountVectorizer):

  def __init__(self,
        max_features=None,
        ngram_range=(1,1),
        tokenizer=nonnum_stem_tokenizer,
        stop_words=[],
        binary=False,
        vocabulary=None):

    # standard nltk stop words plus some common useless words
    stop_words.extend(base_stop_words)

    super(ReviewCountVec, self).__init__(
      max_features=max_features,
      ngram_range=ngram_range,
      tokenizer=tokenizer,
      stop_words=map(stemmer.stem, stop_words),
      binary=binary,
      vocabulary=vocabulary)


from flask import Flask, render_template, request, jsonify  # เพิ่ม jsonify
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing import image
import numpy as np
import cv2

app = Flask(__name__)

@app.route('/')
def home():
   return render_template('index.html')

@app.route('/about')
def about():
   return render_template('about.html')

# Load the pomelo detection model
model = load_model('pomelo.h5', compile=True)

# Define a function to preprocess the image
def preprocess_image(image_path):
    img = image.load_img(image_path, target_size=(224, 224))  # Resize to (224, 224)
    img = image.img_to_array(img)
    img = img / 255.0
    img = np.expand_dims(img, axis=0)
    return img

# Define a function to predict emotion
def predict_emotion(image_path):
    img = preprocess_image(image_path)
    result = model.predict(img)
    emotion_labels = ['Good','Normal','Bad']
    emotion = emotion_labels[np.argmax(result)]
    return emotion

@app.route('/detect_org', methods=['POST'])
def detect_org():
    if 'image' in request.files:
        uploaded_image = request.files['image']
        if uploaded_image.filename != '':
            image_path = 'static/uploaded_image.png'
            uploaded_image.save(image_path)
            emotion = predict_emotion(image_path)

            if emotion == "Good":
                return render_template('good.html', image=image_path)
            elif emotion == "Normal":
                return render_template('normal.html', image=image_path)
            elif emotion == "Bad":
                 return render_template('bad.html', image=image_path)
            else:
                # หากไม่ใช่  ให้กลับไปที่หน้าหลัก
                return render_template('index.html', result=emotion, image=image_path)
    return render_template('index.html')

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


# multiAgents.py
# --------------
# Licensing Information:  You are free to use or extend these projects for
# educational purposes provided that (1) you do not distribute or publish
# solutions, (2) you retain this notice, and (3) you provide clear
# attribution to UC Berkeley, including a link to http://ai.berkeley.edu.
#
# Attribution Information: The Pacman AI projects were developed at UC Berkeley.
# The core projects and autograders were primarily created by John DeNero
# (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu).
# Student side autograding was added by Brad Miller, Nick Hay, and
# Pieter Abbeel (pabbeel@cs.berkeley.edu).

from util import manhattanDistance
from game import Directions
import random, util

from game import Agent

class ReflexAgent(Agent):
    """
      A reflex agent chooses an action at each choice point by examining
      its alternatives via a state evaluation function.

      The code below is provided as a guide.  You are welcome to change
      it in any way you see fit, so long as you don't touch our method
      headers.
    """

    def getAction(self, gameState):
        """
        You do not need to change this method, but you're welcome to.

        getAction chooses among the best options according to the evaluation function.

        Just like in the previous project, getAction takes a GameState and returns
        some Directions.X for some X in the set {North, South, West, East, Stop}
        """
        # Collect legal moves and successor states
        legalMoves = gameState.getLegalActions()

        # Choose one of the best actions
        scores = [self.evaluationFunction(gameState, action) for action in legalMoves]
        bestScore = max(scores)
        bestIndices = [index for index in range(len(scores)) if scores[index] == bestScore]
        chosenIndex = random.choice(bestIndices) # Pick randomly among the best

        "Add more of your code here if you want to"

        return legalMoves[chosenIndex]

    def evaluationFunction(self, currentGameState, action):
        """
        Design a better evaluation function here.

        The evaluation function takes in the current and proposed successor
        GameStates (pacman.py) and returns a number, where higher numbers are better.

        The code below extracts some useful information from the state, like the
        remaining food (newFood) and Pacman position after moving (newPos).
        newScaredTimes holds the number of moves that each ghost will remain
        scared because of Pacman having eaten a power pellet.

        Print out these variables to see what you're getting, then combine them
        to create a masterful evaluation function.
        """
        # Useful information you can extract from a GameState (pacman.py)
        successorGameState = currentGameState.generatePacmanSuccessor(action)
        newPos = successorGameState.getPacmanPosition()
        newFood = successorGameState.getFood()
        newGhostStates = successorGameState.getGhostStates()
        newScaredTimes = [ghostState.scaredTimer for ghostState in newGhostStates]

        "*** YOUR CODE HERE ***"

        current = successorGameState.getScore()
        fVal  = 8.0
        gVal = 9.0

        ghosts = []
        foods = []

        for ghost in newGhostStates:
            ghostPosition = ghost.getPosition()
            ghostDistance = manhattanDistance(newPos, ghostPosition)
            ghosts.append(ghostDistance)

        for food in newFood.asList():
            foodDistance = manhattanDistance(newPos, food)
            foods.append(foodDistance)

        if len(foods):
            fVal = min(foods)

        if ghosts and min(ghosts) != 0:
            gVal = min(ghosts)

        return current + (8.0/fVal) - (9.0/gVal)

def scoreEvaluationFunction(currentGameState):
    """
      This default evaluation function just returns the score of the state.
      The score is the same one displayed in the Pacman GUI.

      This evaluation function is meant for use with adversarial search agents
      (not reflex agents).
    """
    return currentGameState.getScore()

class MultiAgentSearchAgent(Agent):
    """
      This class provides some common elements to all of your
      multi-agent searchers.  Any methods defined here will be available
      to the MinimaxPacmanAgent, AlphaBetaPacmanAgent & ExpectimaxPacmanAgent.

      You *do not* need to make any changes here, but you can if you want to
      add functionality to all your adversarial search agents.  Please do not
      remove anything, however.

      Note: this is an abstract class: one that should not be instantiated.  It's
      only partially specified, and designed to be extended.  Agent (game.py)
      is another abstract class.
    """

    def __init__(self, evalFn = 'scoreEvaluationFunction', depth = '2'):
        self.index = 0 # Pacman is always agent index 0
        self.evaluationFunction = util.lookup(evalFn, globals())
        self.depth = int(depth)

class MinimaxAgent(MultiAgentSearchAgent):
    """
      Your minimax agent (question 2)
    """

    def getAction(self, gameState):
        """
          Returns the minimax action from the current gameState using self.depth
          and self.evaluationFunction.

          Here are some method calls that might be useful when implementing minimax.

          gameState.getLegalActions(agentIndex):
            Returns a list of legal actions for an agent
            agentIndex=0 means Pacman, ghosts are >= 1

          gameState.generateSuccessor(agentIndex, action):
            Returns the successor game state after an agent takes an action

          gameState.getNumAgents():
            Returns the total number of agents in the game

          gameState.isWin():
            Returns whether or not the game state is a winning state

          gameState.isLose():
            Returns whether or not the game state is a losing state
        """
        "*** YOUR CODE HERE ***"
        opt = []

        def succ(agentIndex, gameState, depth):
            options = []
            if agentIndex == gameState.getNumAgents():
              depth = 1 + depth
              return succ(0,gameState, depth)

            if gameState.isLose() or gameState.isWin() or self.depth == depth:
              return self.evaluationFunction(gameState)

            for act in gameState.getLegalActions(agentIndex):
                options.append(succ(1 + agentIndex, gameState.generateSuccessor(agentIndex, act), depth))

            if agentIndex % gameState.getNumAgents() != 0:
              return min(options)
            else:
              return max(options)

        for action in gameState.getLegalActions(0):
            state = gameState.generateSuccessor(0, action)
            temp = succ(1, state, 0)
            opt.append([temp, action])

        opt.sort()
        return opt[-1][1]

class AlphaBetaAgent(MultiAgentSearchAgent):
    """
      Your minimax agent with alpha-beta pruning (question 3)
    """

    def getAction(self, gameState):
        """
          Returns the minimax action using self.depth and self.evaluationFunction
        """
        "*** YOUR CODE HERE ***"
        #util.raiseNotDefined()
        # opt = []

        def maxValue(gameState, depth, alpha, beta, agentIndex):
          v = [None,float("-inf")]

          for act in gameState.getLegalActions(agentIndex):
            x = succ(1 + agentIndex, gameState.generateSuccessor(agentIndex, act), depth, alpha, beta)
            x = x[1]
            maxv = max(v[1], x)

            if maxv > v[1]:
              v = [act, maxv]

            if v[1] > beta:
              return v
            alpha = max(alpha, v[1])
          return v

        def minValue(gameState, depth, alpha, beta, agentIndex):
          v = [None,float("inf")]
          for act in gameState.getLegalActions(agentIndex):
            x = succ(1 + agentIndex, gameState.generateSuccessor(agentIndex, act), depth, alpha, beta)

            x = x[1]
            minv = min(v[1], x)

            if minv < v[1]:
              v = [act, minv]

            if v[1] < alpha:
              return v
            beta = min(beta, v[1])
          return v

        def succ(agentIndex, gameState, depth, alpha, beta):
            # options = []
            if agentIndex >= gameState.getNumAgents():
              depth = 1 + depth
              # return succ(0,gameState, depth, alpha, beta)
              agentIndex = 0

            if gameState.isLose() or gameState.isWin() or self.depth == depth:
              return [None, self.evaluationFunction(gameState)]

            # for act in gameState.getLegalActions(agentIndex):
            #     options.append(succ(1 + agentIndex, gameState.generateSuccessor(agentIndex, act), depth, alpha, beta))

            # if agentIndex % gameState.getNumAgents() != 0:
            if agentIndex % gameState.getNumAgents() != 0:
              return minValue(gameState,depth , alpha,beta, agentIndex)

            else:
              return maxValue(gameState,depth , alpha,beta, agentIndex)

        # for action in gameState.getLegalActions(0):
        #     state = gameState.generateSuccessor(0, action)
        #     temp = succ(1, state, 0, alpha, beta)
        #     opt.append([temp, action])

        # #Cannot sort values?
        # opt.sort()
        # return opt[-1][1]
        alpha = float("-inf")
        beta = float("inf")
        temp = succ(0, gameState, 0, alpha, beta)
        return temp[0]

class ExpectimaxAgent(MultiAgentSearchAgent):
    """
      Your expectimax agent (question 4)
    """

    def getAction(self, gameState):
        """
          Returns the expectimax action using self.depth and self.evaluationFunction

          All ghosts should be modeled as choosing uniformly at random from their
          legal moves.
        """
        "*** YOUR CODE HERE ***"
        # util.raiseNotDefined()
        opt = []
        def succ(agentIndex, gameState, depth):
            options = []
            if agentIndex == gameState.getNumAgents():
              depth = 1 + depth
              return succ(0,gameState, depth)

            if gameState.isLose() or gameState.isWin() or self.depth == depth:
              return self.evaluationFunction(gameState)

            for act in gameState.getLegalActions(agentIndex):
                options.append(succ(1 + agentIndex, gameState.generateSuccessor(agentIndex, act), depth))

            if agentIndex % gameState.getNumAgents() != 0:
              return sum(options)/len(options)
            else:
              return  max(options)

        for action in gameState.getLegalActions(0):
            state = gameState.generateSuccessor(0, action)
            temp = succ(1, state, 0)
            opt.append([temp, action])

        opt.sort()
        return opt[-1][1]

def betterEvaluationFunction(currentGameState):
    """
      Your extreme ghost-hunting, pellet-nabbing, food-gobbling, unstoppable
      evaluation function (question 5).

      DESCRIPTION: <write something here so we know what you did>

      Very similar to evaluationFunction (gave me 5/6 points). Instead of finding the min
      distance to food, I found the average distance and that did it for the 6/6 points.
      I am adding the currentGameSate.getScore() to the reciprocal of average distance of food
      multiplied by a weight and also adding the reciprocal of the nearest ghosts multiplied by a weigth.

      In the previous evaluationFunction, if the ghost(s) was far from pacman, pacman would stay still
      even if there was food nearby and waited util the ghost approached. This was severely affecting
      the score average. Adding instead of subtracting the recipricated distance of the closest
      ghost and changing from adding the min distance to food to the average distance, fixed this problem
      for the most part. Now, pacman isn't afraid to approach the ghost and make "risky" moves to get the
      food.
    """
    "*** YOUR CODE HERE ***"
    # successorGameState = currentGameState.generatePacmanSuccessor(action)
    newPos = currentGameState.getPacmanPosition()
    newFood = currentGameState.getFood()
    newGhostStates = currentGameState.getGhostStates()
    newScaredTimes = [ghostState.scaredTimer for ghostState in newGhostStates]
    # "*** YOUR CODE HERE ***"

    current = currentGameState.getScore()
    fVal  = 8.0
    gVal = 8.0

    ghosts = []
    foods = []

    for ghost in newGhostStates:
        ghostPosition = ghost.getPosition()
        ghostDistance = manhattanDistance(newPos, ghostPosition)
        ghosts.append(ghostDistance)

    for food in newFood.asList():
        foodDistance = manhattanDistance(newPos, food)
        foods.append(foodDistance)

    if len(foods):
        fVal = sum(foods)
        fVal = fVal / float(len(foods))

    if ghosts and min(ghosts) != 0:
        gVal = min(ghosts)

    return current + (8.0/fVal) + (8.0/gVal)

# Abbreviation
better = betterEvaluationFunction


from aocd import lines
from day1 import delimit
from itertools import zip_longest, chain
import functools
from math import prod

def parse(lines):
    return [(eval(left), eval(right)) for left, right in delimit(lines)]

def compare(left, right, level=0, p=False):
    if left == right:
        return 0

    def _compare(left, right, level=0, p=False):
        if p:
            print(f"{'  ' * level}- Compare {left} vs {right}")
        if left is None:
            return (True, True)
        elif right is None:
            return (False, False)
        elif type(left) == int and type(right) == int:
            return (right is not None and left <= right, left < right)
        elif type(left) == list and type(right) == list:
            for l, r in zip_longest(left, right):
                correct, short_circuit = _compare(l, r, level=level + 1, p=p)
                if correct and short_circuit:
                    return (True, True)
                if not correct:
                    return (False, False)
            return (True, False)
        elif type(left) == int and type(right) == list:
            if p:
                print(
                    f"{'  ' * level}- Mixed types; convert {left} to list and try again"
                )
            return _compare([left], right, level=level, p=p)
        elif type(left) == list and type(right) == int:
            if p:
                print(
                    f"{'  ' * level}- Mixed types; convert {right} to list and try again"
                )
            return _compare(left, [right], level=level, p=p)
        else:
            return (False, False)

    return 1 if _compare(left, right, level=level, p=p)[0] else -1

def part_1(groups, p=False):
    solution = 0
    for i, group in enumerate(groups):
        if p:
            print(f"== Pair {i+1} ==")
        result = compare(*group, p=p)
        if p:
            print(result)
        solution += i + 1 if result == 1 else 0
    return solution

def part_2(groups):
    decoder_packets = [[[2]], [[6]]]
    packets = list(chain(*groups)) + decoder_packets
    packets.sort(key=functools.cmp_to_key(compare), reverse=True)
    return prod(
        [i + 1 for i, packet in enumerate(packets) if packet in decoder_packets]
    )

def main():
    groups = parse(lines)
    p = False
    print("Part 1:", part_1(groups, p=p))
    print("Part 2:", part_2(groups))

if __name__ == "__main__":
    main()


"""Integration tests for WeMo Switch devices."""

import pytest

from pywemo import Switch

class Base:
    """Tests that run for each Switch model."""

    @pytest.mark.vcr()
    def test_turn_on(self, switch):
        switch.on()
        assert switch.get_state(force_update=True) == 1

    @pytest.mark.vcr()
    def test_turn_off(self, switch):
        switch.off()
        assert switch.get_state(force_update=True) == 0

class Test_F7C027(Base):
    """Tests for the WeMo F7C027 model switch."""

    @pytest.fixture
    def switch(self, vcr):
        with vcr.use_cassette("WeMo_US_2.00.2769.PVT.yaml"):
            return Switch("http://192.168.1.100:49153/setup.xml")

    @pytest.mark.vcr()
    def test_config_any(self, switch):
        assert switch._config_any == {
            "binaryState": "0",
            "firmwareVersion": "WeMo_US_2.00.2769.PVT",
            "iconVersion": "0|49153",
        }

class Test_F7C063(Base):
    """Tests for the WeMo F7C063 model switch."""

    @pytest.fixture
    def switch(self, vcr):
        with vcr.use_cassette("WeMo_WW_2.00.11420.PVT-OWRT-SNSV2.yaml"):
            return Switch("http://192.168.1.100:49153/setup.xml")

    @pytest.mark.vcr()
    def test_config_any(self, switch):
        assert switch._config_any == {
            "binaryState": "0",
            "firmwareVersion": "WeMo_WW_2.00.11420.PVT-OWRT-SNSV2",
            "hkSetupCode": "012-34-567",
            "hwVersion": "v3",
            "iconVersion": "2|49153",
            "new_algo": "1",
        }

class Test_WSP080(Base):
    """Tests for the WeMo WSP080 model switch."""

    @pytest.fixture
    def switch(self, vcr):
        with vcr.use_cassette("WEMO_WW_4.00.20101902.PVT-RTOS-SNSV4.yaml"):
            return Switch("http://192.168.1.100:49153/setup.xml")

    @pytest.mark.vcr()
    def test_config_any(self, switch):
        assert switch._config_any == {
            "binaryState": "0",
            "firmwareVersion": "WEMO_WW_4.00.20101902.PVT-RTOS-SNSV4",
            "hkSetupCode": "012-34-567",
            "hwVersion": "v4",
            "iconVersion": "1|49152",
            "new_algo": "1",
            "rtos": "1",
        }


def ali_je_prastevilo(n):
    """preveri, ali je n praštevilo"""
    if n < 2:
        return False
    else:
        for i in range(2, n):
            if n % i == 0:
                return False
        return True

def najvecji_prafaktor(n):
    """poišče največji prafaktor števila n"""
    a = 2
    while a <= n:
        if ali_je_prastevilo(a) == True:
            if n % a == 0:
                n //= a
            else:
                a += 1
        else:
            a += 1
    return a

print(najvecji_prafaktor(600851475143))


from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from fastapi.security import OAuth2PasswordBearer
from server.models.student import Student
from server.models.tutor import Tutor

from server.schemas import UserIn, Token

from server.database import get_db

from server.CRUD.user import create_user
from server.CRUD.student import create_student
from server.CRUD.tutor import create_tutor

from server.token import create_access_token
from server.utils import UserType
from server.validation.registration import check_user_exists, validate_user_data

router = APIRouter()

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/auth/token")

@router.post("/register/{user_type}", response_model=Token)
async def register(
    user_type: UserType, user_in: UserIn, db: AsyncSession = Depends(get_db)
):
    validate_user_data(user_type=user_type, user_in=user_in)

    await check_user_exists(db=db, user_type=user_type, user_in=user_in)

    if user_type == UserType.STUDENT:
        new_user = Student(
            first_name=user_in.first_name,
            last_name=user_in.last_name,
            email=user_in.email,
        )
        try:
            student = await create_student(db=db, student=new_user)
            user_id = student.id
        except Exception:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Bad student data",
            )
    elif user_type == UserType.TUTOR:
        new_user = Tutor(
            first_name=user_in.first_name,
            last_name=user_in.last_name,
            email=user_in.email,
        )
        try:
            tutor = await create_tutor(db=db, tutor=new_user)
            user_id = tutor.id
        except Exception as e:
            print(e)
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Bad tutor data",
            )

    try:
        creds = await create_user(
            db=db, user_in=user_in, user_type=user_type, user_id=user_id
        )
        creds_id = creds.id
    except Exception as e:
        print(e)
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Bad credetials",
        )

    return create_access_token(creds_id, user_type)


# bm_edit_dist.py
# given a collection of groups of metabolites (for instance, various sets of
# biomass precursors), find the average edit distance between each pair of
# metabolites from each pair of groups of metabolites

import itertools as it
import editdistance as ed
import pandas as pd

# given two lists of strings, find the average edit distance between all pairs
# of strings
def avg_ed(l1, l2):
    dists = list()
    #print('list 1')
    #print(l1)
    #print('list 2')
    #print(l2)
    for met1 in l1:
        # if this metabolite is in the other list, give it a zero for all
        # combinations
        if met1 in l2:
            dists.extend(list(it.repeat(0, len(l2))))
        # only compute edit distances if the metabolite isn't in the list
        else:
            for met2 in l2:
                dists.append(ed.distance(met1, met2))
    avg_dist = sum(dists)/len(dists)
    return(avg_dist)

# given a list of lists of strings, make a matrix of edit distances between all
# pairs of sublists
def make_ed_mat(met_list_list):
    print(met_list_list)
    dist_mat = list()
    # loop over indices in met_list_list
    for i in range(len(met_list_list)-1):
        # add a new empty list to dist_mat
        dist_mat.append(list())
        # for each metabolite list in met_list_list, including the ith one,
        # compute the average edit distance between it and the ith list
        for met_list in met_list_list:
            dist_mat[i].append(avg_ed(met_list_list[i], met_list))
    return(dist_mat)

# coerce to set to remove some duplicates
bms_with_dups = list(set(
    pd.read_csv('../data/ab_5_100x2ins_5outs.tsv', sep = '\t').biomass
))

# might have same metabolites in different orders; need to remove those dups
# split metabolites into lists, alphabetize lists, then turn back into comma-
# delimited strings and use set coercion to remove duplicates
bms_no_dups = list(set(
    [','.join(sorted(met_list.split(','))) for met_list in bms_with_dups]
))
print(bms_no_dups)
#out = make_ed_mat(bms)
#print(out)


'''
Name: Prithvi Raj Singh
Assignment 3: Linear Regression problem Part2.
Printing the optimal weight of 3 variable datas using formula7 .
**Note: Please use the attached .csv file (twoVarBPdata.csv) for the program to produce desired output.
This produces the 3d plot of the given data which is optional and not optimized.
The data given by Dr. Maida was slightly reformatted for the program to read all the rows and columns of the data
'''

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from mpl_toolkits import mplot3d

data_frame = pd.read_csv("twoVarBPdata.csv", skiprows=None)
data_frame.head()
data_frame.tail()
data_set2 = data_frame.values
data_set2 = np.insert(data_set2, 1, 1, axis=1)

x = data_set2[0:17, 1:4]
print("\nThe value of x is the collection of matrix of Age and Weight. It is used for optimal value calculation")
print(x)
y = data_set2[:, 4]
print("\n This will print out y, the matrix value of SBP")
print(y)
x_transpose = np.transpose(x)
W = np.matmul(np.matmul(np.linalg.inv(np.matmul(x_transpose,x)), x_transpose), y)
print("The optimal weight is:\n", W)

'''
The below code for the plotting is optional for this part of assignment3. Dr. Maida asked us to just print out the optimal
weight for this.
'''
fig = plt.figure()
ax= plt.axes(projection='3d')
zline = np.linspace(30,120,100)
xline = np.linspace(20,80,100)
yline = W[1]*xline + W[0]+W[2]*zline
ax.plot3D(xline, yline, zline, 'red')
ax.plot(xline,yline,zline, 'red')


import os
import datetime
import math
import pandas as pd
import tkinter as tk
from tkinter import StringVar, IntVar, ttk
from tkinter import filedialog as fd

class GoalSetter(tk.Toplevel):
    def __init__(self, parent, title_set):
        super().__init__(parent)
        self.destroy_ind = 0
        self.title('Задание цели')
        self.label_num=len(title_set)
        self.minsize(200,self.label_num*27)
        label_list=[]
        self.text_list=[]
        textbox_list=[]
        for i in range(self.label_num):
            label_list.append(tk.Label(self, text=str(title_set[i])).pack())
            self.text_list.append(tk.StringVar(self))
            textbox_list.append(ttk.Entry(self,textvariable=self.text_list[i]).pack())
        btn = ttk.Button(self, text="Ок", command=self.values_check)
        btn.pack()
        self.protocol("WM_DELETE_WINDOW", self.handler)

    def handler(self):
        self.destroy_ind = 1
        self.destroy()

    def values_check(self):
        self.destroy_ind = 0
        for i in range(self.label_num):
            if not (('.' in self.text_list[i].get() and self.text_list[i].get().replace('.', '').isdigit())
                    or self.text_list[i].get().isdigit()
                    or self.text_list[i].get() in ['зачет','незачет']):
                tk.messagebox.showinfo(title='Ошибка', message='Проверьте введенные данные')
                return
        self.destroy()

    def open(self):
        self.grab_set()
        self.wait_window()
        goal=[]
        for i in range(self.label_num):
            if '.' in self.text_list[i].get() and self.text_list[i].get().replace('.', '').isdigit():
                goal.append(float(self.text_list[i].get()))
            elif self.text_list[i].get().isdigit():
                goal.append(int(self.text_list[i].get()))
            elif self.text_list[i].get() == '': goal.append(1)
            else: goal.append(0)
        return goal, self.destroy_ind

class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.data = pd.DataFrame()
        self.title('Приложение: Рейтинг успеваемости')
        self.geometry('900x600')
        self.minsize(900,600)
        self.frame_filedialog = tk.Frame(self,width=150,height=30)
        self.frame_view = tk.Frame(self, width=150, height=150)
        self.frame_buttons = tk.Frame(self, width=150, height=30)
        self.frame_filedialog.place(relx=0, rely=0, relwidth=1, relheight=0.08)
        self.frame_view.place(relx=0, rely=0.08, relwidth=1, relheight=0.84)
        self.frame_buttons.place(relx=0, rely=0.92, relwidth=1, relheight=0.08)
        self.open_button = ttk.Button(self.frame_filedialog, text='Открыть файл', command=self.select_file)
        self.text = tk.StringVar(self.frame_filedialog)
        self.open_textbox = ttk.Entry(self.frame_filedialog,textvariable=self.text)
        self.open_textbox.place(relx=0.01, rely=0.2, relwidth=0.6, relheight=0.6)
        self.open_button.place(relx=0.62, rely=0.2, relwidth=0.15, relheight=0.6)
        # место для отображения таблицы с данными
        self.table = ttk.Treeview(self.frame_view, show='headings')
        self.scroll_pane_y =ttk.Scrollbar(self.frame_view, command=self.table.yview)
        self.scroll_pane_x =ttk.Scrollbar(self.frame_view, command=self.table.xview, orient='horizontal')
        self.table.configure(yscrollcommand=self.scroll_pane_y.set, xscrollcommand=self.scroll_pane_x.set)
        self.scroll_pane_y.pack(side=tk.RIGHT, fill=tk.Y)
        self.scroll_pane_x.pack(side=tk.BOTTOM, fill=tk.X)
        self.table.pack(expand=tk.YES, fill=tk.BOTH)
        #конпки сохранения и оценки
        self.no_goal = IntVar()
        self.no_pass = IntVar()
        self.flunk_button = ttk.Checkbutton(self.frame_buttons, text="Учитывать неуспевающих студентов", variable=self.no_pass).place(relx=0.23, rely=0.2,relheight=0.6)
        self.goal_button = ttk.Checkbutton(self.frame_buttons, text="Ввести цель вручную", variable=self.no_goal).place(relx=0.03, rely=0.2,relheight=0.6)
        self.rate_button = ttk.Button(self.frame_buttons,text='Рейтинг',command = self.rate_up)
        self.save_button = ttk.Button(self.frame_buttons, state=tk.DISABLED, text='Сохранить как',command=self.save_file_as)
        self.rate_button.place(relx=0.83, rely=0.2,relwidth=0.15, relheight=0.6)
        self.save_button.place(relx=0.65, rely=0.2,relwidth=0.15, relheight=0.6)

    # проверка имени файла в строке на существование и тип
    def name_check(self, file):
        if os.path.exists(file):
            filename, file_extension = os.path.splitext(file)
            if file_extension in ['.xls', '.xlsx', '.xlsm', '.xlsb']: return False
            else: return True
        else: return True

    # вывод таблицы на форму
    def table_update(self):
        self.table.delete(*self.table.get_children())
        headers=self.data.columns.values.tolist()
        self.table['columns'] = headers
        for header in headers:
            self.table.heading(header, text=header, anchor='center')
            self.table.column(header,anchor='center')
        for row in self.data.values.tolist():
            self.table.insert('', tk.END, values=row)

    # открыть выбранный файл
    def select_file(self):
        if self.text.get() == '' or self.name_check(self.text.get()):
            filetypes = (
                ('Excel Files', '*.xls *.xlsx *.xlsm *.xlsb'),
                ('All Files', '*.*')
            )
            filename = fd.askopenfilename(
                title='Выберите файл',
                initialdir=r'C:\\',
                filetypes=filetypes)
            self.text.set(filename)
        else: filename = self.text.get()

        if filename != '':
            self.save_button.configure(state=tk.DISABLED)
            self.rate_button.configure(state=tk.ACTIVE)
            # загрузка содержимого в датафрейм
            self.data = pd.read_excel(filename,0)
            self.table_update()

    # сохранение файла
    def save_file_as(self):
        filename = fd.asksaveasfilename(
            initialfile ="Рейтинг"+str(datetime.date.today()),
            defaultextension=".xlsx",
            initialdir=r'C:\\')
        with pd.ExcelWriter(filename) as writer:
            self.data.to_excel(writer)

    def target_proximity(self, vector, goal):
        goal
        result1 = result2 = 0
        ab=0
        a2=0
        b2=0
        size=len(goal)
        for i in range(size):
            if vector[i] == 0 and self.no_pass.get() == 0:
                return [0, 0]
            else:
                ab=ab+goal[i]*vector[i]
                a2=a2+math.pow(goal[i],2)
                b2=b2+math.pow(vector[i],2)
        result1=ab/(math.sqrt(a2)*math.sqrt(b2))
        result2=ab*100/a2
        return [result1, result2]

    def rate_up(self):
        # переводим зачет и незачет в числовые эквиваленты
        # временный датафрейм для удобства вычислений
        df=self.data.copy()
        credit_map = {'незачет': 0, 'зачет': 1}
        df=df.replace(credit_map)
        first_column=''

        # заполняем пропущенные значения
        df = df.replace(r'^\s+$', pd.np.nan, regex=True)
        df.fillna(0,inplace=True)

        # проверяем присутствие только числовых значений
        columns = df.columns.tolist()
        types = df.dtypes.tolist()
        try:
            int_pos = types.index('int64')
        except ValueError:
            int_pos=len(columns)
        try:
            float_pos = types.index('float64')
        except ValueError:
            float_pos=len(columns)
        if float_pos>-1 and int_pos<float_pos:
            try:
                types.index('object',int_pos)
                tk.messagebox.showinfo(title='Ошибка', message='Данные предоставлены с ошибками. Проверьте источник информации')
                return
            except ValueError:
                first_column=columns[int_pos]
        elif int_pos>float_pos:
            try:
                types.index('object',float_pos)
                tk.messagebox.showinfo(title='Ошибка', message='Данные предоставлены с ошибками. Проверьте источник информации')
                return
            except ValueError:
                first_column=columns[float_pos]
        else:
            tk.messagebox.showinfo(title='Ошибка', message='Данные предоставлены с ошибками. Проверьте источник информации')
            return

        # проверяем на отрицательные значения и отмечаем неуспевающих студентов
        for name in columns[columns.index(first_column):]:
            if not df[df[name]<0].empty :
                tk.messagebox.showinfo(title='Ошибка', message='В таблице присутствуют отрицательные значения.')
                return
            if self.no_pass.get() == 0 : df.loc[(df[name]==2), name] = 0

        # отделяем цель
        if self.no_goal.get()==0:
            goal = df.loc[0][first_column:].values.tolist()
            self.data=self.data[1:].copy()
            df=df[1:].copy()
        else:
            window= GoalSetter(self, columns[columns.index(first_column):])
            goal, answer = window.open()
            if answer > 0: return

        # применяем формулы к данным
        self.data[['Приближенность к цели','Успешность, %']] = df.apply(lambda x: pd.Series(self.target_proximity(x.loc[first_column:].values.tolist(),goal)), axis =  1)
        # сортировка по убыванию
        self.data = self.data.sort_values(['Успешность, %','Приближенность к цели'],ascending=[False, False]).reset_index(drop=True)
        self.save_button.configure(state=tk.ACTIVE)
        self.rate_button.configure(state=tk.DISABLED)
        self.table_update()

if __name__ == "__main__":
    app = App()
    app.mainloop()


prop_list = ["Eyewear", "Eye color", "Hair", "Outerwear", "T-shirt color", "Trousers", "Socks color", "Shoes"]
prop = {
    "Eyewear": ["Glasses", "Monocle", "None"],
    "Eye color": ["Brown", "Blue", "Hazel"],
    "Hair": ["Straight", "Curly", "Bald"],
    "Outerwear": ["Coat", "Hoodie", "Poncho"],
    "T-shirt color": ["Red", "Orange", "Green"],
    "Trousers": ["Jeans", "Leggings", "Sweatpants"],
    "Socks color": ["Black", "Gray", "White"],
    "Shoes": ["Boots", "Slippers", "Sneakers"],
}

def checker(i, j, desc):
    for t in range(0, 3):
        if (1 << t) & j and desc[i] == prop[prop_list[i]][t]:
            return True
    return False

def ask_query(whi_i, whi_j):
    r.sendline(prop_list[whi_i])
    s = ""
    for i in range(0, 3):
        if whi_j & (1 << i):
            s += prop[prop_list[whi_i]][i]
            s += " "
    s = s[:-1]
    r.sendline(s)
    res = r.recvline()
    print(res)
    sx = False
    if b"YES" in res:
        sx = True
    return sx

def gogo(ppl_desc, num_query):
    print(len(ppl_desc))
    if len(ppl_desc) == 1:
        if num_query >= 1:
            r.sendline(b"Solution")
        s = ""
        for i in range(0, 8):
            s += ppl_desc[0][i]
            if i != 7:
                s += " "
        r.sendline(s)
        r.recvline()
        return
    if num_query == 0:
        t = random.randrange(0, len(ppl_desc))
        s = ""
        for i in range(0, 8):
            s += ppl_desc[t][i]
            if i != 7:
                s += " "
        r.sendline(s)
        r.recvline()
        return
    T = len(ppl_desc)
    whi_i, whi_j, opt = -1, -1, 0
    for i in range(0, 8):
        for j in range(1, 4):
            cnt = 0
            for k in range(0, T):
                ex = checker(i, j, ppl_desc[k])
                if ex == True:
                    cnt += 1
            if min(cnt, T-cnt) > opt:
                opt = min(cnt, T-cnt)
                whi_i, whi_j = i, j
    sx = ask_query(whi_i, whi_j)
    nppl_desc = []
    for k in range(0, T):
        ex = checker(whi_i, whi_j, ppl_desc[k])
        if ex == sx:
            nppl_desc.append(ppl_desc[k])
    gogo(nppl_desc, num_query - 1)
    return

def solve(num_pp, num_ask):
    print(r.recvline())
    print(r.recvline())
    print(r.recvline())
    ppl_desc = []
    for i in range(0, num_pp):
        cur = []
        r.recvline()
        for j in range(0, 8):
            s = r.recvline()
            s = s.split(b":")[1]
            s = s[1:-1].decode()
            cur.append(s)
        ppl_desc.append(cur)
        r.recvline()
    r.recvline()
    gogo(ppl_desc, num_ask)

r = remote("find-rbtree.chal.perfect.blue", 1)

for i in range(0, 9):
    r.recvline()

cases = [(5, 3), (7, 3), (10, 4), (15, 4), (20, 5), (25, 5), (50, 6), (75, 7), (100, 8), (250, 9)]
cases += [(400, 10)] * 5 + [(750, 11)] * 5 + [(1000, 12)] * 5 + [(1600, 12)] * 5

for i in range(0, 30):
    solve(cases[i][0], cases[i][1])

print(r.recvline())


#-------------------------------------------------------------------------------
# Name:        morse_code.py
# Purpose:
#
# Author:      Akshay
#
# Created:     12-06-2015
#-------------------------------------------------------------------------------

morse = {'A': '._', 'B': '_...', 'C': '_._.', 'D': '_..', 'E': '.', 'F': '.._.',
'G': '__.', 'H': '....', 'I': '..', 'J': '.___', 'K': '_._', 'L':'._..', 'M':'__',
'N': '_.', 'O':'___', 'P':'.__.', 'Q': '__._', 'R':'._.', 'S':'...', 'T':'_',
'U': '.._', 'V': '..._', 'W':'.__', 'X': '_.._','Y': '_.__', 'Z':'__..'
}

reverse_morse = {}

def create_dict():
    p = morse.items()
    for k,v in p:
        reverse_morse[v] = k

create_dict()

def remove_puncts_and_upper(sentence):
    res = ''
    valid = [chr(x) for x in range(ord('A'), ord('Z') + 1)]
    valid += [chr(x) for x in range(ord('a'), ord('z') + 1)]
    valid.append(' ')
    valid.append('.')
    for c in sentence:
        if c in valid:
            res += str.upper(c)

    return res

def to_morse(sentence):
    """
    Convert a string sentence into equivalent morse code with words separated by newline, and sentences seperated by two new lines.
    Ignore non-alphabet characters excluding space and period.
    Case insensitive.
    """
    sentence = sentence.strip()
    if sentence[-1] != '.':
        sentence[-1] = '.'
    #sentence = sentence + ' '
    sentence = remove_puncts_and_upper(sentence)
    res = ''
    for c in sentence:
        if c in (' ', '.'):
            res = res + ' ' + '\n'
        else:
            res = res + morse[c] + '\n'
    return res

def valid_morse(encoded):
    """Return whether encoded is valid morse coded string."""
    temp = encoded.split('\n')
    temp = [x for x in temp if x]
    v = list(reverse_morse.keys())
    v.append(' ')
    for s in temp:
        if s not in v:
            return False

    return True

def to_plain_text(encoded):
    """Decode morse coded string."""
    assert valid_morse(encoded), "Cannot decode this invalid morse code."
    res = ''
    temp = encoded.split('\n')
    temp = [x for x in temp if x]
    #print(temp)
    for i, letter in enumerate(temp):
        if letter == ' ':
            try:
                if temp[i+1] == ' ':
                    res += '.'
                else:
                    res += ' '
            except IndexError:
                res += '.'
        else:
            c = reverse_morse[letter]
            res += c
    return res

def valid(s):
    valid = [chr(x) for x in range(ord('A'), ord('Z') + 1)]
    valid += [chr(x) for x in range(ord('a'), ord('z') + 1)]
    valid.append(' ')
    valid.append('.')
    for c in s:
        if c not in valid:
            return False

    return True

def get_input(msg):
    inp = None
    while True:
        inp = input(msg)
        if valid(inp):
            break
        else:
            print('Cannot convert this string to morse due to special characters. Only A-Z, period, and space characters allowed.')

    return inp

def main():
    text = get_input('Enter a string to be converted to morse code.')
    print('The encoded string is:\n{}'.format(to_morse(text)))

if __name__ == '__main__':
    main()


#import the libraries
import warnings
warnings.filterwarnings('ignore')
import numpy as np
import pandas as pd

#load data
advertising = pd.read_csv("advertising.csv")
advertising.head()

#print shape
advertising.shape

#print the dataset information
advertising.info()

#describe the dataset
advertising.describe()

#Visualizing the data
import matplotlib.pyplot as plt
import seaborn as sns

#pair plot
sns.pairplot(advertising, x_vars=['TV', 'Newspaper', 'Radio'], y_vars='Sales', size=4, aspect=1, kind='scatter')
plt.show()

#correlation heatmap
sns.heatmap(advertising.corr(), cmap='YlGnBu', annot=True)
plt.show()

#Performing Simple Linear Regression
X = advertising['TV']
y = advertising['Sales']

#split the data
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size = 0.7, test_size = 0.3, random_state = 100)

#check the train data
X_train.head()
y_train.head()

#Build a Linear Model
import statsmodels.api as sm

X_train_sm = sm.add_constant(X_train)
lr = sm.OLS(y_train, X_train_sm).fit()
lr.params

#print the linear regression summary
print(lr.summary())

#visualize the fitted line
plt.scatter(X_train, y_train)
plt.plot(X_train, 6.948 + 0.054*X_train, 'r')
plt.show()

#Residual analysis
y_train_pred = lr.predict(X_train_sm)
res = (y_train - y_train_pred)

fig = plt.figure()
sns.distplot(res, bins = 15)
fig.suptitle('Error Terms', fontsize = 15)                  # Plot heading
plt.xlabel('y_train - y_train_pred', fontsize = 15)         # X-label
plt.show()

#check the residual plots
plt.scatter(X_train,res)

#Prediction on Test Set
# Add a constant to X_test
X_test_sm = sm.add_constant(X_test)

# Predict the y values corresponding to X_test_sm
y_pred = lr.predict(X_test_sm)
y_pred.head()

#Check the fitness metrics
from sklearn.metrics import mean_squared_error
from sklearn.metrics import r2_score

#Returns the mean squared error; we'll take a square root
np.sqrt(mean_squared_error(y_test, y_pred))
r_squared = r2_score(y_test, y_pred)
r_squared

plt.scatter(X_test, y_test)
plt.plot(X_test, 6.948 + 0.054 * X_test, 'r')
plt.show()

from sklearn.model_selection import train_test_split
X_train_lm, X_test_lm, y_train_lm, y_test_lm = train_test_split(X, y, train_size = 0.7, test_size = 0.3, random_state = 100)
X_train_lm.shape

print(X_train.head())
print(X_train_lm[:5,])

X_train_lm = X_train_lm.reshape(-1,1)
X_test_lm = X_test_lm.reshape(-1,1)

print(X_train_lm[:5,])

print(X_train_lm.shape)
print(y_train_lm.shape)
print(X_test_lm.shape)
print(y_test_lm.shape)

from sklearn.linear_model import LinearRegression

# Representing LinearRegression as lr(Creating LinearRegression Object)
lm = LinearRegression()

# Fit the model using lr.fit()
lm.fit(X_train_lm, y_train_lm)

print(lm.intercept_)
print(lm.coef_)

corrs = np.corrcoef(X_train, y_train)
print(corrs)

corrs[0,1] ** 2

############ Scaling the variables ##############
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size = 0.7, test_size = 0.3, random_state = 100)

from sklearn.preprocessing import StandardScaler, MinMaxScaler

# One aspect that you need to take care of is that the 'fit_transform' can be performed on 2D arrays only. So you need to
# reshape your 'X_train_scaled' and 'y_trained_scaled' data in order to perform the standardisation.
X_train_scaled = X_train.reshape(-1,1)
y_train_scaled = y_train.reshape(-1,1)

X_train_scaled.shape

# Create a scaler object using StandardScaler()
scaler = StandardScaler()
#'Fit' and transform the train set; and transform using the fit on the test set later
X_train_scaled = scaler.fit_transform(X_train_scaled)
y_train_scaled = scaler.fit_transform(y_train_scaled)

print("mean and sd for X_train_scaled:", np.mean(X_train_scaled), np.std(X_train_scaled))
print("mean and sd for y_train_scaled:", np.mean(y_train_scaled), np.std(y_train_scaled))

# Let's fit the regression line following exactly the same steps as done before
X_train_scaled = sm.add_constant(X_train_scaled)

lr_scaled = sm.OLS(y_train_scaled, X_train_scaled).fit()

# Check the parameters
lr_scaled.params

print(lr_scaled.summary())


from PIL import Image
from pyboy import PyBoy, WindowEvent
import schedule
from argparse import ArgumentParser
from io import BytesIO
import time
from typing import List
import twitter_plays_pyboy
import tpp_twitter as twitter

parser = ArgumentParser(
    prog="Twitter Plays Game Boy",
    description="A clone of Constantin Liétard's 'Twitter Plays Pokémon' (https://nitter.net/screenshakes/status/1347589296593788933). Powered by PyBoy (https://github.com/Baekalfen/PyBoy)."
)
parser.add_argument('filename', help="Location of ROM.")
parser.add_argument('-g', '--game', help="Game class used. If you're unsure what to use, pick `BaseGame`.", default="BaseGame", choices=twitter_plays_pyboy.games.__all__)
parser.add_argument('-V', '--version', action='version', version='%(prog)s ' + twitter_plays_pyboy.__version__)

args = parser.parse_args()

engine = getattr(twitter_plays_pyboy.games, args.game)

# Initialize emulator
emu = PyBoy(args.filename, window_type="headless", debug=False, game_wrapper=True)
emu.set_emulation_speed(0)

game = engine(emu)

def job():
    for status in twitter.get_replies_from_latest():
        button = status.text.split(" | ", 1)[0]
        inputs = twitter_plays_pyboy.constants.BUTTON_INPUTS.get(button, [])
        if not inputs:
            continue
        press, release = inputs
        game.input(press, release)
    else:
        inputs = twitter_plays_pyboy.constants.BUTTON_INPUTS['pass']
        press, release = inputs
        game.input(press, release)

    with game.screenshot() as screenshot:
        screenshot_bin = BytesIO()
        screenshot.save(screenshot_bin, "JPEG")

    twitter.update(screenshot_bin, BytesIO(screenshot_bin.getvalue()), text="", bio=game.bio())

schedule.every(30).seconds.do(job)

while True:
    try:
        schedule.run_pending()
        time.sleep(1)
    except KeyboardInterrupt:
        game.emu.stop()
        exit(0)


import os
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
# from email import MIMEImage
from email.mime.base import MIMEBase
from email.mime.application import MIMEApplication
# from email import Encoders

def mail(to,attach):
    # allow either one recipient as string, or multiple as list
    if not isinstance(to,list):
        to = [to]
    # allow either one attachment as string, or multiple as list
    if not isinstance(attach,list):
        attach = [attach]

    gmail_user='*****@aristopharma.com'
    gmail_pwd = "*********"
    msg = MIMEMultipart()
    msg['From'] = gmail_user
    msg['To'] = ", ".join(to)
    msg['Subject'] = "Hi mozur vai ! any attachment there "
    body_text="Mail automation for target sheets"
    msg.attach(MIMEText(body_text,'plain'))

    #get all the attachments
    for file in attach:
        with open(file, "rb") as f:
            #attach = email.mime.application.MIMEApplication(f.read(),_subtype="pdf")
            part = MIMEApplication(f.read(),_subtype="pdf")

        # part = MIMEBase('application', 'octet-stream')
        # part.set_payload(open(file, 'rb').read())
        # Encoders.encode_base64(part)
            part.add_header('Content-Disposition', 'attachment; filename= %s' % file)
            msg.attach(part)

    mailServer = smtplib.SMTP("smtp.aristopharma.com", 587)
    # mailServer.ehlo()
    mailServer.starttls()
    # mailServer.ehlo()
    mailServer.login(gmail_user, gmail_pwd)
    text = msg.as_string().encode('ascii', 'ignore')

    mailServer.sendmail(gmail_user, to, text)
    # Should be mailServer.quit(), but that crashes...
    mailServer.close()

# dicm={1310:'monzur.it@aristopharma.com',1311:'almamun.it@aristopharma.com'}

# # M=['monzur.it@aristopharma.com','almamun.it@aristopharma.com']
dicm={
1310:'***@aristopharma.com',

}

dir = input("Enter attachment Directory : ")
os.chdir(dir)
a = os.listdir()
arr=[]

for x in dicm.keys():
    for y in a:
        print(x)
        name,e = y.split('.')
        print(name[:4])
        if x == int(name[:4]):
            arr.append(y)
    if arr:
        mail(dicm[x],arr)
        arr=[]
    else:
        print(str(x)+"-This depot has no file in Directory")

# for x in dicm:

#     a = os.listdir()

#     mail(M,arr)


import streamlit as st
from PIL import Image
import pandas as pd
import gráficas as gr
import plotly.express as px
import folium
from folium import Choropleth, Circle, Marker, Icon, Map
from folium.plugins import HeatMap, MarkerCluster
from streamlit_folium import folium_static

#Poner título
#st.title("El mundo inmobiliario en Londres")
st.markdown("
¿Quieres conocer el mundo inmobiliario de Londres?
", unsafe_allow_html=True)

#Poner imagen
image = Image.open('data/londres.jpg')
st.image(image,use_column_width=True)

#Breve resumen de la funcionalidad de la API
st.write(
"""
¿Quieres venir a vivir a Londres? ¿No sabes que zona escoger para vivir? ¿Quieres invertir en la inmobiliaria de Londres?

Bien, estas en el lugar adecuado! Aqui, podrás tener la información que necesitas de las distintas zonas de Londres.

"""
)
#Resumen del apartado general de Londres
st.header("1- Información general")
st.write(
"""
A continuación, se puede apreciar un estudio general del mundo inmobiliario en Inglaterra.

1.1 Evolución de los precios medios de las viviendas de todas las regiones de Inglaterra.

 - Cuales son las regiones con mayores y menores precios
 - Comparativa del resto de regiones con Londres
 - Visualizar la tendencia de los precios

"""
)

#Gráfica de la evolución de los precios
gr.gráfica_regiones()

st.write(
"""
1.2 Evolución del número de casas vendidas en cada región de Inglaterra, mensualmente desde 1995 hasta 2020.

 - Tendencias de las ventas de casas
 - Crisis del 2008
"""
)

#Gráfica de las ventas de inmuebles por zonas
data = pd.read_csv("data/regiones-london.csv")
zona = st.selectbox("Elige una región", list(data.area.unique()))
gr.casas_vendidas(zona)

map_1 = folium.Map(location = [51.51753,-0.11214], zoom_start = 6)
folium_static(map_1)

#Apartado mas concreto por zona elegida.
st.header("2- Información específica de los municipios de Londres")

st.write(
"""
Elige una zona y obtendrás información de ella:
"""
)

#Selector por zonas
data1 = pd.read_csv("data/houses-yearly-london.csv")
data2 = pd.read_csv("data/houses-monthly-london.csv")
data3 = pd.read_csv("data/c.postal-london.csv")
london = data1[data1['borough_flag'] == 1]
london = data2[data2['borough_flag'] == 1]
zona = st.selectbox("Elige un municipio", list(london.area.unique()))
st.write(
"""
Código Postal:
"""
)
data3 = pd.read_csv("data/c.postal-london.csv")
data2=data3[data3.area == zona]["code"].unique()[0]
data2
tipo_gráfica = st.selectbox("Elige que gráfica quieres ver", ["Precio medio viviendas", "Salario medio", "Porcentage de hogares que reciclan", "Número de trabajos/Número de habitantes", "Número de crímenes"])

if  tipo_gráfica == "Salario medio":
    gr.media_salarios(zona)
if tipo_gráfica == "Número de trabajos/Número de habitantes":
    gr.numero_trabajos(zona)
if tipo_gráfica == "Porcentage de hogares que reciclan":
    gr.hogares_reciclan(zona)
if tipo_gráfica == "Precio medio viviendas":
    gr.precios_medios(zona)
if tipo_gráfica == "Número de crímenes":
    gr.crimenes_zona(zona)


from typing import Optional

from sqlalchemy.orm import Session

from app import crud, models, schemas
from app.tests.utils.design import create_random_design
from app.tests.utils.user import create_random_user
from app.tests.utils.utils import random_float, random_integer, random_lower_string

def create_random_synth(
    db: Session, *, owner_id: Optional[int] = None, design_id: Optional[int] = None
) -> models.Synth:
    if owner_id is None:
        user = create_random_user(db)
        owner_id = user.id
    if design_id is None:
        design = create_random_design(db, owner_id=owner_id)
        design_id = design.id
    j5_synth_id = random_integer()
    name = random_lower_string()
    length = random_integer()
    cost = random_float()
    sequence = random_lower_string()
    synth_in = schemas.SynthCreate(
        j5_synth_id=j5_synth_id,
        name=name,
        length=length,
        cost=cost,
        sequence=sequence,
    )
    return crud.synth.create(
        db=db,
        obj_in=synth_in,
        owner_id=owner_id,
        design_id=design_id,
    )


#!/usr/bin/env python3

import sys, os
from PyQt4.QtGui import (QMainWindow, QApplication, QPixmap, QImage, QListWidget, QListWidgetItem, QIcon, QLabel, QStackedWidget,
						QGraphicsScene, QGraphicsView)
from PyQt4.QtCore import SIGNAL, QThread, QSize
from Leap import Controller
from LeapListener import LeapListener

threads = []
library = {}

extensions = ['.jpg', '.jpeg', '.png']

class LeapFlow (QMainWindow):

	def __init__ (self):
		QMainWindow.__init__ (self)

		self.controller = Controller ()
		self.listener = LeapListener (self)
		self.controller.add_listener (self.listener)

		self.mode = "gallery"
		self.scroll = False
		self.direction = ""
		self.direction_x = 0
		self.scroll_velocity = 0
		self.current_index = 0

		# List containing images for the gallery
		self.list_view = QListWidget ()
		self.list_view.setFlow (0)
		self.list_view.setHorizontalScrollMode (1)
		self.list_view.setMouseTracking (True)
		self.list_view.itemClicked.connect (self.show_image)

		# Setting the style of the ListView, background, item selected, etc
		self.list_view.setStyleSheet ("""
				QListWidget::item:hover {background: transparent;}
				QListWidget::item:disabled:hover {background: transparent;}
				QListWidget::item:hover:!active {background: transparent;}
				QListWidget::item:selected:active {background: transparent;}
	            QListWidget::item:selected:!active {background: transparent;}
	            QListWidget::item:selected:disabled {background: transparent;}
	            QListWidget::item:selected:!disabled {background: transparent;}
	            QListWidget {background: #2C3539}
			""")

		# Image viewer
		self.scene = QGraphicsScene ()
		self.viewer = QGraphicsView (self.scene)

		self.stackedWidget = QStackedWidget ()
		self.stackedWidget.addWidget (self.list_view)
		self.stackedWidget.addWidget (self.viewer)

		self.setCentralWidget (self.stackedWidget)
		self.resize (500, 400)
		self.showMaximized ()

		scan = ScanLibrary ("/home/chris/Example")
		threads.append (scan)
		self.connect (scan, SIGNAL (scan.signal), self.add_images_to_list)
		scan.start ()

		self.connect (self, SIGNAL ("scrollChanged(bool)"), self.scroll_view)

	def setScroll (self, scroll):
		"""Emit signal to scroll the view"""
		if (self.scroll != scroll):
			self.scroll = scroll
			self.emit (SIGNAL("scrollChanged(bool)"), scroll)

	def scroll_view (self):
		"""Scroll the view based on scroll velocity and direction"""

		x = self.direction_x * self.scroll_velocity / 100
		bar_x = self.list_view.horizontalScrollBar ().value ()
		self.list_view.horizontalScrollBar ().setValue (bar_x + x)

	def add_images_to_list (self):
		"""To add a widget to the listview you must add a QListWidgetItem
		and replace with your widget"""

		for image in library:
			item = QListWidgetItem ()
			pixmap = QPixmap.fromImage (QImage (library[image]))
			label = QLabel ()
			label.setPixmap (pixmap.scaled (600, 400))
			item.setSizeHint (label.sizeHint ())
			item.setData (0, library[image])
			self.list_view.addItem (item)
			self.list_view.setItemWidget (item, label)

	def show_image (self, item):
		""""Display the selected image"""

		self.current_index = self.list_view.indexFromItem (item).row ()
		self.scene.addPixmap ((QPixmap.fromImage (QImage (item.text()))).scaled (self.viewer.size()))

		self.stackedWidget.setCurrentIndex (1)
		self.mode = "viewer"

	def previous_image (self):
		"""Load previous image"""

		if self.current_index - 1 >= 0:
			self.current_index -= 1
			self.load_image ()

	def next_image (self):
		"""Load next image"""

		if self.current_index + 1 <= len(library.keys ()) - 1:
			self.current_index += 1
			self.load_image ()

	def load_image (self):
		"""Load the image in self.current_index"""

		self.scene.addPixmap (QPixmap.fromImage (QImage (library[library.keys()[self.current_index]])))

class ScanLibrary (QThread):

	def __init__ (self, location):
		QThread.__init__ (self)
		self.location = location
		self.signal = "scan_finished"

	def run (self):
		for path, subdirs, files in os.walk(self.location):
			for f in files:
				location = os.path.join(path, f)
				extension = os.path.splitext(f)[1]
				if extension in extensions:
					name = os.path.basename(location)
					library[name] = location

		print (library)
		self.emit (SIGNAL(self.signal), 'Collection scan finished')

app = QApplication (sys.argv)
leapflow = LeapFlow ()
sys.exit (app.exec_())


import keras
import tensorflow as tf
from model import Deeplabv3

class Deeplabv3Model(keras.Model):
    def __init__(self):
        super(Deeplabv3Model, self).__init__()
        # self.input_shape = (1, 512, 512, 3)
        # self.input_l = Input(batch_shape=(BATCH_SIZE, 224, 224, 3))  # let us say this new InputLayer
        self.base_model = Deeplabv3()

    def call(self, inputs):
        # print("inputs", inputs)
        img_final = tf.cast(inputs, tf.float32) / 127.5

        inputs = img_final - 1.
        # inputs.resize((512, 512, 3))

        ## ConcateLayer
        return self.base_model(inputs)