# Title: Ames Housing Statistical Analysis
# Author: Alexander Zakrzeski
# Date: January 17, 2023

# Import the necessary libraries and modules

import numpy as np
import pandas as pd
import scipy.stats as stats
import statsmodels.api as sm
from statsmodels.stats.outliers_influence import variance_inflation_factor

import matplotlib.pyplot as plt
import seaborn as sns
import plotnine as pn

from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.linear_model import LinearRegression, Lasso, LassoCV
from sklearn.neighbors import KNeighborsRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error

import janitor as jan
import movecolumn as mc

##### Part A - Data Preprocessing #####

# Take the following steps:
  # 1. Create a list
  # 2. Import the data
  # 3. Consolidate the column names
  # 4. Rename a specific column
  # 5. Create new columns
  # 6. Modifying existing columns
  # 7. Drop columns

cols1_drop = ["pid", "ms_subclass", "year_built", "year_remod_add",
              "fireplaces", "garage_yr_blt", "mo_sold", "yr_sold"]

data1_all = (
    jan.clean_names(pd.read_csv("Ames_Data.csv"))
       .rename(columns = {"order": "id"})
       .assign(age = lambda x: x["yr_sold"] - x["year_built"])
       .assign(age = lambda x: np.where(x["age"] < 0, 0, x["age"]),
               overall_cond = lambda x:
                   np.where(x["overall_cond"] < 5, "below",
                   np.where(x["overall_cond"] == 5, "average",
                                                      "above")),
               overall_qual = lambda x:
                   np.where(x["overall_qual"] < 5, "below",
                   np.where(x["overall_qual"] == 5, "average",
                                                      "above")),
               kitch_qual = lambda x:
                   np.where((x["kitchen_qual"] == "Po") |
                            (x["kitchen_qual"] == "Fa"), "below",
                   np.where(x["kitchen_qual"] == "TA", "average",
                                                         "above")),
               fplace = lambda x: np.where(x["fireplaces"] > 0, "yes", "no"))
       .drop(columns = cols1_drop))

# Take the following steps:
  # 1. Select columns with certain data types
  # 2. Change the data type of a specific column
  # 3. Replace missing values with 0

data1_num = (data1_all
             .select_dtypes(include = np.number)
             .astype({"id": str})
             .fillna(0))

# Take the following steps:
  # 1. Calculate the Pearson correlation coefficients
  # 2. Sort by the selected column
  # 3. Filter appropriately
  # 4. Select the necessary column
  # 5. Get the index of the column as a list

corr1 = (data1_num
         .corr(numeric_only = True)
         .sort_values(by = "price", ascending = False)
         .query("price > 0.45 | price < -0.45")
         .price
         .index
         .tolist())

# Define the name of the extra column

cols1_extra = "id"

# Append the column

if cols1_extra not in corr1:
    corr1.append(cols1_extra)

# Select the columns that are in the list

data1_num = data1_num[corr1]

# Take the following steps:
  # 1. Create a list
  # 2. Change the data type of a specific column
  # 3. Select columns with certain data types
  # 4. Select the necessary columns

cols1_keep = ["id", "overall_cond", "overall_qual", "kitch_qual", "fplace"]

data1_str = (data1_all
             .astype({"id": str})
             .select_dtypes(include = object)
             [cols1_keep])

# Take the following steps:
  # 1. Create a list
  # 2. Merge the data frames
  # 3. Rename certain columns
  # 4. Drop a specific column
  # 5. Reorder the columns

cols1_order = ["price", "abv_grd_sf", "garage_cars", "garage_sf",
               "bsmt_sf","x1st_flr_sf", "full_bath", "mas_area",
               "totrms_abvgrd", "age", "kitch_qual", "fplace",
               "overall_cond", "overall_qual"]

data2 = (data1_num
         .merge(data1_str, on = "id", how = "left")
         .rename(columns = {"area": "abv_grd_sf",
                            "garage_area": "garage_sf",
                            "total_bsmt_sf": "bsmt_sf",
                            "mas_vnr_area": "mas_area"})
         .drop(columns = "id")
         [cols1_order])

##### Part B - Exploratory Data Analysis #####

# Select columns with certain data types

data2_num = data2.select_dtypes(include = np.number)

# Take the following steps:
  # 1. Create a dictionary
  # 2. Generate the descriptive statistics
  # 3. Rename index

index1_rename = {"count": "Count",
                 "mean": "Mean",
                 "std": "Standard Deviation",
                 "min": "Minimum",
                 "max": "Maximum"}

ds1 = (data2_num
       .agg(["count", "mean", "std", "min", "max"])
       .rename(index = index1_rename))

# Create a new row for the median

ds1.loc["Median"] = data2_num.median()

# Create a new row for the mode

ds1.loc["Mode"] = data2_num.mode().iloc[0]

# Take the following steps:
  # 1. Create a dictionary
  # 2. Rename columns
  # 3. Transpose the data frame
  # 4. Modify the position of columns

cols1_rename = {"price": "Price", "abv_grd_sf": "Abv. Grd. SF",
                "garage_cars": "Garage Doors", "garage_sf": "Garage SF",
                "bsmt_sf": "Basement SF",  "x1st_flr_sf": "1st Flr. SF",
                "full_bath": "Bathrooms", "mas_area": "Masonry SF",
                "totrms_abvgrd": "Rooms Abv. Grd.", "age": "Age"}

ds1 = (ds1
       .rename(columns = cols1_rename)
       .T
       .pipe(mc.MoveToN, "Median", 3)
       .pipe(mc.MoveToN, "Mode", 4))

# Take the following steps:
  # 1. Select columns with certain data types
  # 2. Rename all the columns
  # 3. Calculate the Pearson correlation coefficients

corr2 = (data2
         .select_dtypes(include = np.number)
         .rename(columns = cols1_rename)
         .corr())

# Create a correlation matrix displaying the Pearson correlation coefficients

plt.figure(figsize = (8, 6))
color = sns.diverging_palette(10, 240, as_cmap = True)
cmat = sns.heatmap(corr2, vmin = -1, vmax = 1, annot = True, cmap = color,
                   linewidths = 0.5, linecolor = "black", xticklabels = True,
                   yticklabels = True, annot_kws = {"color": "black"})
cmat.tick_params(bottom = False, left = False)
cmat.set_title("Figure 1 - Correlation Matrix of Numeric Analysis Variables",
               fontdict = {"fontsize": 18}, pad = 12)

plt.show()

# Take the following steps:
  # 1. Modifying existing column
  # 2. Select the necessary columns
  # 3. Calculate Spearman's rank correlation coefficient

corr3 = (data2
         .assign(kitch_qual =
                 np.where(data2["kitch_qual"] == "below", 1,
                 np.where(data2["kitch_qual"] == "average", 2,
                                                            3)))
         [["price", "kitch_qual"]])

corrtest3 = stats.spearmanr(corr3["kitch_qual"], corr3["price"])

# Take the following steps:
  # 1. Modifying existing column
  # 2. Select the necessary columns
  # 3. Calculate the point biserial correlation coefficient

corr4 = (data2
         .assign(fplace = np.where(data2["fplace"] == "yes", 1, 0))
         [["price", "fplace"]])

corrtest4 = stats.pointbiserialr(corr4["fplace"], corr4["price"])

# Take the following steps:
  # 1. Modifying existing column
  # 2. Select the necessary columns
  # 3. Calculate Spearman's rank correlation coefficient

corr5 = (data2
         .assign(overall_cond =
                 np.where(data2["overall_cond"] == "below", 1,
                 np.where(data2["overall_cond"] == "average", 2,
                                                              3)))
         [["price", "overall_cond"]])

corrtest5 = stats.spearmanr(corr5["overall_cond"], corr5["price"])

# Take the following steps:
  # 1. Modifying existing column
  # 2. Select the necessary columns
  # 3. Calculate Spearman's rank correlation coefficient

corr6 = (data2
         .assign(overall_qual =
                 np.where(data2["overall_qual"] == "below", 1,
                 np.where(data2["overall_qual"] == "average", 2,
                                                              3)))
         [["price", "overall_qual"]])

corrtest6 = stats.spearmanr(corr6["overall_qual"], corr6["price"])

# Create a histogram displaying the distribution

(pn.ggplot(data = data2, mapping = pn.aes(x = "price")) +
 pn.geom_histogram(fill = "#005288", color = "black", bins = 25) +
 pn.scale_x_continuous(labels = lambda x: ["${:,.0f}".format(i) for i in x]) +
 pn.labs(title = "Figure 2 - Distribution of Price",
         x = "Price", y = "Frequency") +
 pn.theme_bw() +
 pn.theme(plot_title = pn.element_text(hjust = 0.5),
          text = pn.element_text(size = 14)))

# Create a new variable

data2["log_price"] = np.log(data2["price"])

# Create a histogram displaying the distribution

(pn.ggplot(data = data2, mapping = pn.aes(x = "log_price")) +
 pn.geom_histogram(fill = "#c0c2c4", color = "black", bins = 25) +
 pn.labs(title = "Figure 3 - Distribution of the Log of Price",
         x = "Log of Price", y = "Frequency") +
 pn.theme_bw() +
 pn.theme(plot_title = pn.element_text(hjust = 0.5),
          text = pn.element_text(size = 14)))

# Create a scatter plot displaying the relationship between the variables

(pn.ggplot(data = data2, mapping = pn.aes(x = "abv_grd_sf", y = "price")) +
 pn.geom_point(color = "#005288", size = 0.6) +
 pn.geom_smooth(method = "lm", se = False, size = 0.7) +
 pn.scale_x_continuous(labels = lambda x: ["{:,.0f}".format(i) for i in x]) +
 pn.scale_y_continuous(labels = lambda x: ["${:,.0f}".format(i) for i in x]) +
 pn.labs(title = "Figure 4 - Price vs. Above Ground Sq. Ft.",
         x = "Above Ground Sq. Ft.", y = "Price") +
 pn.theme_bw() +
 pn.theme(plot_title = pn.element_text(hjust = 0.5),
          text = pn.element_text(size = 14)))

# Create a function that identifies outliers using the IQR method

def get_outliers(df, col):
    q1 = df[col].quantile(0.25)
    q3 = df[col].quantile(0.75)
    iqr = q3 - q1
    lower_bound = q1 - (1.5 * iqr)
    upper_bound = q3 + (1.5 * iqr)
    outliers = df[(df[col] < lower_bound) | (df[col] > upper_bound)]
    return outliers

# Use function to get outliers using the IQR method for two different variables

outliers1 = get_outliers(data2, "abv_grd_sf")

outliers2 = get_outliers(data2, "price")

# Filter appropriately to produce a new data frame

data3 = data2.query("abv_grd_sf < 4000 & price > 15000")

# Create a scatter plot displaying the relationship between the variables

(pn.ggplot(data = data3, mapping = pn.aes(x = "abv_grd_sf", y = "log_price")) +
 pn.geom_point(color = "#0078ae", size = 0.6) +
 pn.geom_smooth(method = "lm", se = False, size = 0.7) +
 pn.scale_x_continuous(labels = lambda x: ["{:,.0f}".format(i) for i in x]) +
 pn.labs(title = "Figure 5 - Log of Price vs. Above Ground Sq. Ft.",
         x = "Above Ground Sq. Ft.", y = " Log of Price") +
 pn.theme_bw() +
 pn.theme(plot_title = pn.element_text(hjust = 0.5),
          text = pn.element_text(size = 14)))

# Create a scatter plot displaying the relationship between the variables

(pn.ggplot(data = data2, mapping = pn.aes(x = "age", y = "price")) +
 pn.geom_point(color = "#005288", size = 0.6) +
 pn.geom_smooth(method = "lm", se = False, color = "black", size = 0.7) +
 pn.scale_y_continuous(labels = lambda x: ["${:,.0f}".format(i) for i in x]) +
 pn.labs(title = "Figure 6 - Price vs. Age", x = "Age", y = "Price") +
 pn.theme_bw() +
 pn.theme(plot_title = pn.element_text(hjust = 0.5),
          text = pn.element_text(size = 14)))

# Create a scatter plot displaying the relationship between the variables

(pn.ggplot(data = data3, mapping = pn.aes(x = "age", y = "log_price")) +
 pn.geom_point(color = "#0078ae", size = 0.6) +
 pn.geom_smooth(method = "lm", formula = "y ~ x + I(x**2)", se = False,
                color = "black", size = 0.7) +
 pn.labs(title = "Figure 7 - Log of Price vs. Age",
         x = "Age", y = "Log of Price") +
 pn.theme_bw() +
 pn.theme(plot_title = pn.element_text(hjust = 0.5),
          text = pn.element_text(size = 14)))

# Create a new variable

data3["age2"] = np.power(data2["age"], 2)

##### Part C - Statistical Modeling #####

# Take the following steps:
  # 1. Convert categorical variables to dummy variables
  # 2. Drop columns
  # 3. Modify the position of the columns

data3 = (data3
         .join(pd.get_dummies(data3[["kitch_qual", "fplace",
                                     "overall_cond", "overall_qual"]],
                              prefix = ["kitch_qual", "fplace",
                                        "overall_cond", "overall_qual"]))
         .drop(columns = ["kitch_qual", "fplace",
                          "overall_cond", "overall_qual"])
         .pipe(mc.MoveToN, "log_price", 2)
         .pipe(mc.MoveToN, "age2", 12))

### Polynomial Regression

# Take the following steps:
  # 1. Create a list
  # 2. Create a data frame with the necessary independent variables
  # 3. Create a series with just the dependent variable
  # 4. Use hold-out validation to split data into training and testing sets
  # 5. Save function as an object and fit the model to the training data
  # 6. Generate regression output

cols2_keep = ["abv_grd_sf", "garage_sf", "bsmt_sf", "age", "age2",
              "kitch_qual_below", "kitch_qual_average", "fplace_yes",
              "overall_cond_below", "overall_cond_average",
              "overall_qual_below", "overall_qual_average"]

iv1 = data3[cols2_keep]

dv1 = data3["log_price"]

iv1_train, iv1_test, dv1_train, dv1_test = train_test_split(
    iv1, dv1, test_size = 0.3, shuffle = True, random_state = 100)

polreg1 = LinearRegression()

polreg1.fit(iv1_train, dv1_train)

polreg1_output = sm.OLS(dv1_train, sm.add_constant(iv1_train)).fit().summary()

# Take the following steps:
  # 1. Make predictions on the training data
  # 2. Generate the model's residuals
  # 3. Create a data frame with the fitted values and residuals
  # 4. Produce residuals vs. fitted plot
  # 5. Produce a histogram of the residuals
  # 6. Use custom function to get VIFs

polreg1_train_pred = polreg1.predict(iv1_train)

polreg1_train_resid = dv1_train - polreg1_train_pred

rfplot1_df = pd.DataFrame({"fitted": polreg1_train_pred,
                           "resid": polreg1_train_resid})

(pn.ggplot(data = rfplot1_df, mapping = pn.aes(x = "fitted", y = "resid")) +
 pn.geom_point(color = "#005288", size = 0.6) +
 pn.geom_hline(yintercept = 0, color = "grey", linetype = "dashed") +
 pn.labs(title = "Residuals vs. Fitted Plot",
         x = "Fitted Values", y = "Residuals") +
 pn.theme_bw() +
 pn.theme(plot_title = pn.element_text(hjust = 0.5),
          text = pn.element_text(size = 14)))

(pn.ggplot(data = rfplot1_df, mapping = pn.aes(x = "resid")) +
 pn.geom_histogram(fill = "#c0c2c4", color = "black", bins = 25) +
 pn.labs(title = "Distribution of Residuals",
         x = "Residuals", y = "Frequency") +
 pn.theme_bw() +
 pn.theme(plot_title = pn.element_text(hjust = 0.5),
          text = pn.element_text(size = 14)))

def compute_vifs(data):
    iv_with_intercept = sm.add_constant(data)
    vifs = [variance_inflation_factor(iv_with_intercept.values, i)
            for i in range(iv_with_intercept.shape[1])]
    vif_series = pd.Series(vifs[1:], index = data.columns)
    return vif_series

compute_vifs(iv1_train.drop(columns = "age2"))

# Take the following steps:
  # 1. Get r-squared
  # 2. Make predictions on the test data
  # 3. Get the RMSE

polreg1.score(iv1_test, dv1_test)

polreg1_test_pred = polreg1.predict(iv1_test)

rmse1 = np.sqrt(mean_squared_error(dv1_test, polreg1_test_pred))

### Lasso Regression

# Take the following steps:
  # 1. Create a data frame with the necessary independent variables
  # 2. Create a series with just the dependent variable
  # 3. Use hold-out validation to split data into training and testing sets
  # 4. Standardize the necessary variables
  # 5. Use 5-fold cross-validation to find optimal hyperparameter
  # 6. Save function as an object and fit the model to the training data
  # 7. Get the r-squared

cols3_keep = ["abv_grd_sf", "garage_cars", "garage_sf", "bsmt_sf",
              "x1st_flr_sf", "full_bath", "mas_area", "totrms_abvgrd",
              "age", "age2", "kitch_qual_below", "kitch_qual_average",
              "fplace_yes", "overall_cond_below", "overall_cond_average",
              "overall_qual_below", "overall_qual_average"]

iv2 = data3[cols3_keep]

dv2 = data3["log_price"]

iv2_train, iv2_test, dv2_train, dv2_test = train_test_split(
    iv2, dv2, test_size = 0.3, shuffle = True, random_state = 100)

def standardize_df(df):
    df_stand = df.copy()
    num_cols = (df_stand.select_dtypes(include = np.number)
                        .select_dtypes(exclude = "uint8").columns)
    scaler = StandardScaler()
    scaler.fit(df_stand[num_cols])
    df_stand[num_cols] = scaler.transform(df_stand[num_cols])
    return df_stand

iv2_train = standardize_df(iv2_train)

iv2_test = standardize_df(iv2_test)

lasso1_cv = LassoCV(cv = 5, random_state = 100)

lasso1_cv.fit(iv2_train, dv2_train)

lasso1 = Lasso(alpha = lasso1_cv.alpha_)

lasso1.fit(iv2_train, dv2_train)

lasso1.score(iv2_train, dv2_train)

# Take the following steps:
  # 1. Get r-squared
  # 2. Make predictions on the test data
  # 3. Get the RMSE

lasso1.score(iv2_test, dv2_test)

lasso1_pred = lasso1.predict(iv2_test)

rmse2 = np.sqrt(mean_squared_error(dv2_test, lasso1_pred))

### K-Nearest Neighbors

# Take the following steps:
  # 1. Use hold-out validation to split data into training and testing sets
  # 2. Save function as an object and perform hyperparameter tuning
  # 3. Fit the model to the training data
  # 4. Get the r-squared

iv3_train, iv3_test, dv3_train, dv3_test = train_test_split(
    iv2, dv2, test_size = 0.3, shuffle = True, random_state = 100)

knn1 = KNeighborsRegressor()

hp1_grid = {"n_neighbors": [4, 8, 12, 16, 20]}

knn1_cv = GridSearchCV(knn1, param_grid = hp1_grid, cv = 5)

knn1_cv.fit(iv3_train, dv3_train)

knn1 = knn1_cv.best_estimator_

knn1.fit(iv3_train, dv3_train)

knn1.score(iv3_train, dv3_train)

# Take the following steps:
  # 1. Get r-squared
  # 2. Make predictions on the test data
  # 3. Get the RMSE

knn1.score(iv3_test, dv3_test)

knn1_test_pred = knn1.predict(iv3_test)

rmse3 = np.sqrt(mean_squared_error(dv3_test, knn1_test_pred))

### Random Forest

# Take the following steps:
  # 1. Use hold-out validation to split data into training and testing sets
  # 2. Perform hyperparameter tuning
  # 3. Save function as an object and fit the model to the training data
  # 4. Get the r-squared

iv4_train, iv4_test, dv4_train, dv4_test = train_test_split(
    iv2, dv2, test_size = 0.3, shuffle = True, random_state = 100)

hp2_grid = {"n_estimators": [200, 250, 500],
            "max_depth": [20, 21, 22],
            "min_samples_split": [4]}

rf1_cv = GridSearchCV(RandomForestRegressor(random_state = 100),
                      hp2_grid, cv = 5)

rf1_cv.fit(iv4_train, dv4_train)

rf1_bp = rf1_cv.best_params_

rf1 = RandomForestRegressor(n_estimators = rf1_bp["n_estimators"],
                            max_depth = rf1_bp["max_depth"],
                            min_samples_split = rf1_bp["min_samples_split"],
                            random_state = 100)

rf1.fit(iv4_train, dv4_train)

rf1.score(iv4_train, dv4_train)

# Take the following steps:
  # 1. Get r-squared
  # 2. Make predictions on the test data
  # 3. Get the RMSE

rf1.score(iv4_test, dv4_test)

rf1_test_pred = rf1.predict(iv4_test)

rmse4 = np.sqrt(mean_squared_error(dv4_test, rf1_test_pred))


# -*- coding: utf-8 -*-
import json
import os

from fake_useragent import UserAgent, FakeUserAgentError

class UserAgentUtil(object):
    file_path = os.getcwd() + '/useragent.txt'
    file_json = {}

    def getUA(self):
        file_exists = os.path.isfile(self.file_path)
        if file_exists:
            with open(self.file_path, 'r') as f:
                self.file_json = json.loads(f.read())
        else:
            try:
                ua = UserAgent()
                ua_list = []
                for i in ua.data_browsers.values():
                    ua_list.extend(i)
                self.file_json['useragent'] = ua_list
                with open(self.file_path, 'w') as f:
                    f.write(json.dumps(self.file_json, indent=4))
            except FakeUserAgentError:
                print("获取UA失败，请重试。。。")
        return self.file_json


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

from mpl_toolkits.mplot3d import Axes3D
from matplotlib.animation import FuncAnimation
from src.aircraft.AircraftDynamics import AircraftDynamics, AircraftDynamicsV2
from src.aircraft.Aircraft import AircraftInfo
from src.Utils import get_airplane_params

"""

Just evaluating the numerical approximations between the using
Euler's method and Runge-Kutta 4th order method.

"""

plt.close('all')
if __name__=="__main__":
    #check if csv file exists

    df = pd.read_csv("SIM_Plane_h_vals.csv")
    airplane_params = get_airplane_params(df)

    use_csv_for_init = False

    if use_csv_for_init == False:

        init_states = {'x':0.0, 'y':0.0, 'z':0.0,
                    'u':25.0, 'v':0.0, 'w':0.0,
                    'phi':0.0, 'theta':0.0, 'psi':0.0,
                    'p':0.0, 'q':0.0, 'r':0.0}

        #a negatitive elevator command makes it go up
        controls = {'delta_e':np.deg2rad(10.0),
                    'delta_a':np.deg2rad(0.0),
                    'delta_r':np.deg2rad(0.0),
                    'delta_t':0.4}

    else:
        #load csv file
        states_df = pd.read_csv("final_states.csv")
        #skip the first column
        states_df = states_df.iloc[:,1:]
        init_states = states_df.iloc[-1].to_dict()

        controls_df = pd.read_csv("final_controls.csv")
        controls_df = controls_df.iloc[:,1:]
        controls = controls_df.iloc[-1].to_dict()

        init_states = {'x':0.0, 'y':0.0, 'z':0.0,
                    'u':25.0, 'v':0.0, 'w':0.0,
                    'phi':0.0, 'theta':np.deg2rad(0.0306), 'psi':0.0,
                    'p':0.0, 'q':0.0, 'r':0.0}

        controls = {'delta_e':np.deg2rad(0.0),
                    'delta_a':np.deg2rad(0.0),
                    'delta_r':np.deg2rad(0.0),
                    'delta_t':0.128}

    aircraft_info_euler = AircraftInfo(
        airplane_params,
        init_states,
        controls)

    aircraft_info_rk = AircraftInfo(
        airplane_params,
        init_states,
        controls)

    aircraft_dynamics_eulers = AircraftDynamicsV2(aircraft_info_euler)
    aircraft_dynamics_rk = AircraftDynamicsV2(aircraft_info_rk)

    dt = 0.01
    t_init = 0.0
    t_final = 5.0
    N = int((t_final - t_init) / dt)
    N = 20
    # N = 100

    input_aileron = controls['delta_a']
    input_elevator = controls['delta_e']
    input_rudder = controls['delta_r']
    input_throttle = controls['delta_t']

    euler_states = []
    rk_states = []

    use_linear_csv = False
    if use_linear_csv == True:
        controls_df = pd.read_csv("MPC_Plane_controls.csv")
        states_df = pd.read_csv("MPC_Plane_states.csv")

    for i in range(N):
        if use_linear_csv == True:
            input_aileron = controls_df['delta_a'][i]
            input_elevator = controls_df['delta_e'][i]
            input_rudder = controls_df['delta_r'][i]
            input_throttle = controls_df['delta_t'][i]

        new_states_eulers = aircraft_dynamics_eulers.eulers(
            input_aileron,
            input_elevator,
            input_rudder,
            input_throttle,
            aircraft_info_euler.states,
            dt
        )

        aircraft_info_euler.update_states(new_states_eulers)
        euler_states.append(new_states_eulers)

        new_states_rk = aircraft_dynamics_rk.rk45(
            input_aileron,
            input_elevator,
            input_rudder,
            input_throttle,
            aircraft_info_rk.states,
            dt
        )

        aircraft_info_rk.update_states(new_states_rk)
        rk_states.append(new_states_rk)

    euler_states = pd.DataFrame(euler_states)
    rk_states = pd.DataFrame(rk_states)

    #set column names
    euler_states.columns = ['x','y','z',
                            'u','v','w',
                            'phi','theta',
                            'psi','p','q','r']

    euler_states['z'] = -euler_states['z']

    rk_states.columns = ['x','y','z',
                         'u','v','w',
                         'phi','theta','psi',
                         'p','q','r']

    #save rk45 states to csv
    rk_states.to_csv("rk45_states.csv", index=False)

    print(euler_states)
    print("RK45", rk_states)

    # # plot the results
    import matplotlib.pyplot as plt

    #3d plot
    from mpl_toolkits.mplot3d import Axes3D
    fig,ax = plt.subplots(1,1,subplot_kw={'projection':'3d'})
    # ax.plot(euler_states['x'], euler_states['y'], -euler_states['z'], 'o-',
    #         label='Euler',)
    # ax.plot(rk_states['x'], rk_states['y'], -rk_states['z'], 'x-' ,
    #         label='RK45')
    ax.legend()
    #plot attitudes in euler angles in a subplot
    fig1, ax1 = plt.subplots(3,1,sharex=True)
    time_vec = np.linspace(0, t_final, N)
    ax1[0].plot(time_vec, np.rad2deg(euler_states['phi']), label='Euler')
    ax1[0].plot(time_vec, np.rad2deg(rk_states['phi']), label='RK45')

    ax1[1].plot(time_vec, np.rad2deg(euler_states['theta']), label='Euler')
    ax1[1].plot(time_vec, np.rad2deg(rk_states['theta']), label='RK45')

    ax1[2].plot(time_vec, np.rad2deg(euler_states['psi']), label='Euler')
    ax1[2].plot(time_vec, np.rad2deg(rk_states['psi']), label='RK45')
    ax1[2].set_xlabel('Time (s)')
    ax1[0].set_ylabel('Roll (deg)')
    ax1[1].set_ylabel('Pitch (deg)')
    ax1[2].set_ylabel('Yaw (deg)')

    #plot 3d position
    fig2, ax2 = plt.subplots(1,1,subplot_kw={'projection':'3d'})

    ax2.plot(euler_states['x'], euler_states['y'], euler_states['z'], 'o-',
                label='Euler')
    if use_linear_csv == True:
        ax2.plot(states_df['x'], states_df['y'], -states_df['h'], 'x-',
                label='Linear')

    ax2.legend()

    #format axis to be same scale
    max_range = np.array([euler_states['x'].max()-euler_states['x'].min(),
                            euler_states['y'].max()-euler_states['y'].min(),
                            euler_states['z'].max()-euler_states['z'].min()]).max() / 2.0

    mid_x = (euler_states['x'].max()+euler_states['x'].min()) * 0.5
    mid_y = (euler_states['y'].max()+euler_states['y'].min()) * 0.5
    mid_z = (euler_states['z'].max()+euler_states['z'].min()) * 0.5

    # ax2.set_xlim(mid_x - max_range, mid_x + max_range)
    # ax2.set_ylim(mid_y - max_range, mid_y + max_range)
    # ax2.set_zlim(mid_z - max_range, mid_z + max_range)

    #plot body velocities
    fig3, ax3 = plt.subplots(3,1,sharex=True)
    ax3[0].plot(time_vec, euler_states['u'], label='Euler')
    # ax3[0].plot(time_vec, rk_states['u'], label='RK45')
    if use_linear_csv == True:
        ax3[0].plot(time_vec, states_df['u'], label='Linear')

    ax3[0].set_ylabel('u (m/s)')
    ax3[0].legend()

    ax3[1].plot(time_vec, euler_states['v'], label='Euler')
    ax3[1].plot(time_vec, rk_states['v'], label='RK45')
    ax3[1].set_ylabel('v (m/s)')
    ax3[2].plot(time_vec, euler_states['w'], label='Euler')
    ax3[2].plot(time_vec, rk_states['w'], label='RK45')
    ax3[2].set_ylabel('w (m/s)')
    ax3[2].set_xlabel('Time (s)')

    def update(frame):
        ax.cla()  # Clear the previous frame
        ax.set_xlabel('X')
        ax.set_ylabel('Y')
        ax.set_zlabel('Z')
        ax.set_title('Aircraft Animation')

        #keep last 100 frames
        frame_len = 150

        if frame > frame_len:
            pos_bounds = 0.5
            x_positions = euler_states['x'][frame-frame_len:frame]
            y_positions = euler_states['y'][frame-frame_len:frame]
            z_positions = euler_states['z'][frame-frame_len:frame]

            # Set axis limits based on the current frame's positions
            ax.set_xlim(min(x_positions) - pos_bounds, max(x_positions) + pos_bounds)
            ax.set_ylim(min(y_positions) - pos_bounds, max(y_positions) + pos_bounds)
            ax.set_zlim(min(z_positions) - pos_bounds, max(z_positions) + pos_bounds)
        else:
            # plot everything
            x_positions = euler_states['x'][0:frame]
            y_positions = euler_states['y'][0:frame]
            z_positions = euler_states['z'][0:frame]

        #modulus of the frame
        frame = frame % frame_len

        alpha_vector = np.linspace(0, 1, len(x_positions))
        # print(alpha_vector)
        #multiply the color blue to the alpha vector
        # color_vector = []
        # for alpha in alpha_vector:
        #     color_vector.append((0,0,1,alpha))

        # Plot the new positions for each frame
        # for i in range(len(x_positions)):
            # ax.scatter(x_positions[i], y_positions[i], z_positions[i], color='b', alpha=alpha_vector[i])
        ax.plot(x_positions, y_positions, z_positions, 'o-', color='b', label='Euler and RK45')
        ax.legend()

    # Function to draw the aircraft orientation
    def draw_aircraft(ax, x, y, z, heading, pitch, roll):
        # Define aircraft body dimensions (for example)
        body_length = 5
        body_width = 1
        body_height = 1

        # Calculate body orientation
        rotation_matrix = np.array([
            [np.cos(heading) * np.cos(pitch),
            np.cos(heading) * np.sin(pitch) * np.sin(roll) - np.sin(heading) * np.cos(roll),
            np.cos(heading) * np.sin(pitch) * np.cos(roll) + np.sin(heading) * np.sin(roll)],
            [np.sin(heading) * np.cos(pitch),
            np.sin(heading) * np.sin(pitch) * np.sin(roll) + np.cos(heading) * np.cos(roll),
            np.sin(heading) * np.sin(pitch) * np.cos(roll) - np.cos(heading) * np.sin(roll)],
            [-np.sin(pitch),
            np.cos(pitch) * np.sin(roll),
            np.cos(pitch) * np.cos(roll)]
        ])

        # Define body vertices in body-fixed frame
        body_vertices = np.array([
            [body_length / 2, 0, 0],
            [-body_length / 2, body_width / 2, 0],
            [-body_length / 2, -body_width / 2, 0],
            [-body_length / 2, -body_width / 2, -body_height],
            [-body_length / 2, body_width / 2, -body_height],
            [body_length / 2, 0, -body_height]
        ])

        # Rotate body vertices to world frame
        rotated_vertices = np.dot(body_vertices, rotation_matrix.T)
        rotated_vertices += np.array([x, y, z])  # Translate to the aircraft position

        # Draw the aircraft body
        ax.plot3D(rotated_vertices[:, 0], rotated_vertices[:, 1], rotated_vertices[:, 2], color='b')

    # Create the animation
    fig,ax = plt.subplots(1,1,subplot_kw={'projection':'3d'})

    ani = FuncAnimation(fig, update, frames=len(euler_states), interval=30)
    plt.show()


import sys
import json
import annpy
import numpy as np

loss = "BinaryCrossEntropy"
monitored_loss = f'val_{loss}'
n_seed_search = 42

def parsing(dataset_path, seeds_path=None):

	data = annpy.parsing.DataProcessing()
	data.parse_dataset(dataset_path=dataset_path,
						columns_range=[1, None],
						target_index=0)
	data.normalize()
	features, targets = data.get_data(binary_targets=['B', 'M'])

	seed = None
	try:
		with open(seeds_path, 'r') as f:
			lines = [elem for elem in f.read().split('\n') if elem and elem[0] == '{']

			global best_loss_file
			best_loss_file = 42
			for line in lines:

				# print(f"line {type(line)}: {line}")
				line = json.loads(line)
				if line.get(monitored_loss, None) < best_loss_file:
					best_loss_file = line.get(monitored_loss, None)
					seed = line.get('seed', None)

			print(f"end parsing, seed: {type(seed)}, loss: {best_loss_file}\n")

	except:
		print(f"No seed.\n")

	return features, targets, features[0].shape[0], seed

def get_model(input_shape, seed=None, tts_seed=None):

	model = annpy.models.SequentialModel(
		input_shape=layers_shp[0],
		name="First model",
		seed=seed,
		tts_seed=tts_seed
	)
	# model = annpy.models.sequential(input_shape=input_shape, name="First model")

	model.add(annpy.layers.FullyConnected(
		layers_shp[1],
		# activation="relu",
	))
	model.add(annpy.layers.FullyConnected(
		layers_shp[2],
		# activation="relu",
		# activation="tanh",
	))
	model.add(annpy.layers.FullyConnected(
		layers_shp[3],
		# activation="Sigmoid",
		activation="Softmax",
	))
	model.compile(
		loss=loss,
		# loss="MSE",
		# optimizer="SGD",
		optimizer="Adam",
		# optimizer=annpy.optimizers.Adam(
		# 	lr=0.001
		# ),
		# optimizer=annpy.optimizers.SGD(
		# 	lr=0.2,
		# 	momentum=0.92,
		# ),
		# metrics=["RangeAccuracy"]
	)
	return model

def get_model_train(input_shape, seed=None, tts_seed=None, graph=False):

	model = get_model(input_shape, seed, tts_seed)

	early_stopping = annpy.callbacks.EarlyStopping(
		model=model,
		monitor=monitored_loss,
		patience=15,
	)

	logs = model.fit(
		features,
		targets,
		epochs=500,
		batch_size=32,
		callbacks=[early_stopping],
		verbose=False,
		print_graph=graph
	)

	print(f"Fit result: {logs[monitored_loss][-1]}")
	logs = early_stopping.get_best_metrics()
	print(f"Fit best  : {logs}")
	return model, logs

def estimate_tts_seed(input_shape, seed, tts_seed, iter=5):
	# return sum(get_model_train(input_shape, seed)[1][monitored_loss] for i in range(iter)) / iter
	losses = 0
	for i in range(iter):
		print(f"\nTrain {i+1}/{iter} ...")
		losses += get_model_train(input_shape, seed, tts_seed)[1][monitored_loss]
	return losses / iter

# Protection
if len(sys.argv) < 3:
	raise Exception("usage: python3 test.py dataset seeds")
else:
	print(f"dataset: {sys.argv[1]}\nseeds: {sys.argv[2] if len(sys.argv) > 2 else None}\n")

# Parsing
features, targets, input_shape, seed = parsing(sys.argv[1], sys.argv[2] if len(sys.argv) > 2 else None)

layers_shp = (input_shape, 64, 32, 2)

# mode = get_model(input_shape, seed)
# mode2 = get_model(input_shape, seed)

# mode.deepsummary()
# mode2.deepsummary()
# np.random.seed(42)
# print(np.random.get_state())
# np.random.seed(101)
# print(np.random.get_state())
# i=42
# np.random.seed(i)
# print(np.random.get_state())
# exit(0)

best_tts_seed = None
best_loss = 1
for i in range(n_seed_search):

	tts_seed = int(np.random.randn()) % 1000000
	np.random.seed(tts_seed)
	loss_ = estimate_tts_seed(input_shape, seed, np.random.get_state())

	if loss_ < best_loss:
		best_loss = loss_
		best_tts_seed = tts_seed

	print(f"tts_seed {i}: {loss_}\n")

print(f"\tBEST TTS_SEED ({n_seed_search}): {best_tts_seed} -- loss: {loss_}\n")

if best_loss < best_loss_file:

	np.random.seed(best_tts_seed)
	tts_seed = np.random.get_state()
	with open("ressources/seeds.txt", 'a') as f:
		seed = list(seed)
		tts_seed = list(tts_seed)

		seed[1] = [int(n) for n in seed[1]]
		tts_seed[1] = [int(n) for n in tts_seed[1]]

		seed_dict = {
			monitored_loss: best_loss,
			'layers_shp': layers_shp,
			'seed': seed,
			'tts_seed': tts_seed,
		}
		print(f"seed == tts_seed -> {seed == tts_seed}")
		print(f"Write best loss in file")
		json.dump(seed_dict, f)
		print('\n', file=f)

else:
	print(f"Best loss found is worst than best loss file fetch in seeds file: {best_loss} (script) > (file) {best_loss_file}")


import re
from pathlib import Path

from translator.parser import Parser
from translator.commands import COMMANDS, Context, Call

class Writer:
    def __init__(self, parser: Parser) -> None:
        self.parser = parser

    def clean_asm(self, asm: str) -> str:
        return '\n'.join([s for s in asm.replace(' ', '').splitlines() if s])

    def init_asm(self) -> str:
        return '''
            @256
            D=A
            @SP
            M=D
        '''

    def init_section(self) -> str:
        constants = ''.join([c('').constant() for c in COMMANDS.values()])
        return '''
            {}
            {}
            {}
        '''.format(
                self.init_asm(),
                Call('call Sys.init 0').to_asm(Context('', '')),
                constants
            )

    def write_to(self, path: Path) -> None:
        f = open(path, 'w')
        context = Context('', '')
        f.write(self.clean_asm(self.init_section()) + '\n')
        for file, command in self.parser:
            context.file = file
            f.write(self.clean_asm(command.to_asm(context)) + '\n')
        f.close()


from PIL import Image
import base64
import zlib
import StringIO
import io

# Run:		python compressionTest.py
# Creates 6 files for file size comparison:
#	1. The byte array obtained via io
#	2. The byte array as a base64 encoded string
#	3. The compressed byte array
#	4. The compressed base64 string byte array
#	5. The decompressed byte array
#	6. The decompressed base64 string byte array

try:
	# THIS IS HOW WE GET THE BYTE ARRAY WE SHOULD SAVE... 100-300 KB
	picture = Image.open("./patagonia/21911159_1940465642891993_2672871879034798080_n.jpg")

	imgByteArr = io.BytesIO()
	picture.save(imgByteArr, format='jpeg')
	imgByteArr = imgByteArr.getvalue()
	# COPY ABOVE

	#TESTING OTHER METHODS + COMPRESSION
	#Compression does not decrease file size
	picBase64 = base64.encodestring(imgByteArr)

	picBytesCompressed = zlib.compress(imgByteArr)
	picBase64Compressed = zlib.compress(picBase64)

	picBytesDecompressed = zlib.decompress(picBytesCompressed)
	picBase64Decompressed = zlib.decompress(picBase64Compressed)

	with open('file1.jpg', 'wb') as file:
		file.write(imgByteArr)
	with open('file2.jpg', 'wb') as file:
		file.write(picBase64)

	with open('file1.jpg.gz', 'wb') as file:
		file.write(picBytesCompressed)
	with open('file2.jpg.gz', 'wb') as file:
		file.write(picBase64Compressed)

	with open('file1Decom.jpg', 'wb') as file:
		file.write(picBytesDecompressed)
	with open('file2Decom.jpg', 'wb') as file:
		file.write(picBase64Decompressed)

	'''stream = StringIO.StringIO(picBytes)
	stream.write(picBytes)
	with open('file1pic.jpg', 'wb') as file:
		file.write(stream.getvalue())'''

except IOError:
	print("error")


from typing import List

from EnumerationIterator import Enumeration
from IteratorEnumeration import Iterator

class EI:
    @staticmethod
    def main(args: List[str]) -> None:
        v = args
        enumeration: Enumeration = Enumeration(v)
        while enumeration.hasMoreElements():
            print(enumeration.nextElement())
        iterator: Iterator = Iterator(v)
        while iterator.hasNext():
            print(iterator.next())

if __name__ == "__main__":
    EI.main(['a', 'b', 'c'])


import pygame
from plane_sprites import *

class PlaneGame(object):
    """飞机大战主程序"""

    def __init__(self):
        print("游戏初始化")

        # 1 创建游戏的窗口,SCREEC_RECT是定义好的常量，本身是一个矩形对象，set_mode接受的是元祖
        # 使用size属性可以得到元祖＋
        self.screen = pygame.display.set_mode(SCREEN_RECT.size)
        # 2 创建游戏的时钟
        self.clock = pygame.time.Clock()
        # 3 调用私有方法，精灵和精灵组的创建
        self.__creat_sprites()
        # 4 设置定时器是事件　－　创建敌机，时间间隔为１ｓ  创建子弹，０．５ｓ
        pygame.time.set_timer(CREAT_ENEMY_EVENT, 1000)
        pygame.time.set_timer(HERO_FIRE_EVET, 500)

    def __creat_sprites(self):

        # 创建背景精灵和精灵组
        bg1 = Background()
        bg2 = Background(True)
        self.back_ground = pygame.sprite.Group(bg1, bg2)

        # 创建敌机精灵组
        self.enemy_group = pygame.sprite.Group()

        # 创建英雄精灵和精灵组，因为精灵也要在其他方法使用，所以把精灵也定义成属性
        self.hero = Hero()
        self.hero_group = pygame.sprite.Group(self.hero)

    def start_game(self):
        print("游戏开始。。。")
        while True:
            # 1 设置刷新帧率
            self.clock.tick(FRAME_PER_SEC)
            # 2 设置时间监听
            self.__event_handler()
            # 3 碰撞检测
            self.__check_collide()
            # 4 更新/绘制精灵组
            self.__update_sprites()
            # 5 更新显示
            pygame.display.update()

    def __event_handler(self):

        for event in pygame.event.get():

            # 判断是否退出游戏
            if event.type == pygame.QUIT:
                PlaneGame.__game_over()

            elif event.type == CREAT_ENEMY_EVENT:
                print("敌机出场")
                # 创建敌机精灵
                enemy = Enemy()
                # 将敌机精灵添加到敌机精灵组
                self.enemy_group.add(enemy)

            elif event.type == HERO_FIRE_EVET:
                self.hero.fire()

            # 键盘捕获第一种方式，事件监听。按一下动一下。
            # 第一种方式event.type用户必须要抬起按键算一次按键事件，操作灵活性会大打折扣
            # elif event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:
            #     print("向右移动")

        # 键盘捕获第二种方式,使用键盘提供的方法获取键盘－返回按键元组，可以按下一直动
        # 第二种方式用户可以按住方向键不放，就能够实现持续向某一个方向移动了，操作灵活性更好
        keys_pressed = pygame.key.get_pressed()
        # 判断元组中对应按键的索引值
        if keys_pressed[pygame.K_RIGHT]:
            self.hero.speed = 2
        elif keys_pressed[pygame.K_LEFT]:
            self.hero.speed = -2
        else:
            self.hero.speed = 0

    def __check_collide(self):

        # 1 子弹摧毁敌机
        # - 两个精灵组中所有的精灵的碰撞检测
        # groupcollide(group1, group2, dokill1, dokill2, collided=None) -> Sprite_dict
        # - 如果将dokill设置为True，则发生碰撞的精灵将被自动移除
        # - collided参数是用于计算碰撞的回调函数
        # - 如果没有指定，则每个精灵必须有一个rect属性
        pygame.sprite.groupcollide(self.hero.bullets, self.enemy_group, True, True)

        # 2 敌机撞毁英雄
        # - 判断某个精灵和指定精灵组中的精灵的碰撞
        # spritecollide(sprite, group, dokill, collided=None) -> Sprite_list
        # - 如果将dokill设置为True，则指定精灵组中发生碰撞的精灵将被自动移除
        # - collided参数是用于计算碰撞的回调函数
        # - 如果没有指定，则每个精灵必须有一个rect属性
        # - 返回精灵组中跟精灵发生碰撞的精灵列表
        enemies = pygame.sprite.spritecollide(self.hero, self.enemy_group, True)

        #判断列表是否有内容
        if len(enemies) > 0:

            # 让英雄牺牲
            self.hero.kill()

            # 结束游戏
            PlaneGame.__game_over()

    def __update_sprites(self):

        self.back_ground.update()
        self.back_ground.draw(self.screen)

        self.enemy_group.update()
        self.enemy_group.draw(self.screen)

        self.hero_group.update()
        self.hero_group.draw(self.screen)

        self.hero.bullets.update()
        self.hero.bullets.draw(self.screen)

    @staticmethod
    def __game_over():
        print("游戏结束")

        pygame.quit()
        exit()

if __name__ == '__main__':

    # 创建游戏对象
    game = PlaneGame()

    # 启动游戏
    game.start_game()


import json
from pathlib import Path

from langchain import PromptTemplate, LLMChain
from langchain.chains import SequentialChain
from langchain.chat_models import ChatOpenAI

from aws import get_secret

TEMPLATE_FINAL = """
You are a financial advisor of user Matej. His financial goal is to {goal}. His balance at the start of last month was {balance}. His monthly income is {income}.

This is list of the transactions with dates, amounts, currencies and notes:
==================
{financial_history}
==================

You are very friendly, pleasant and funny.
Use direct language, speak directly to the user.

Use this structure:
==========
2 Sentences, maximum 300 characters: Concise, short paragraph summary of the spending overview
empty line
2 Sentences, maximum 300 characters: Short summary of the status of user's financial goal {goal}. Compliment him/her.
empty line
2 Sentences, maximum 300 characters: Provide user some meaningful advice based specifically on the transaction summary paragraph and point out expense that can be most easily managed or ommited next month and provide the amount. Don't advise to pick up another job or reaching back to you.
==========
"""

TEMPLATE_SPONSORS_ = """
Given the following customer's financial transactions history and our sponsors, pick the sponsor that may interest our customer:

financial transactions history:
==========
{financial_history}
==========

sponsors:
==========
""" + Path('sponsors_ok').read_text() + """
==========

Provide a condensed message.
"""

def get_chain():
    openai_api_key = json.loads(get_secret("OpenaiApiKey"))['OpenaiApiKey']

    llm = ChatOpenAI(temperature=0.8, max_retries=1, request_timeout=90, max_tokens=1024, openai_api_key=openai_api_key, model="gpt-4")  # 30sec timeout, 0 retries for bot

    final_prompt = PromptTemplate(
        template=TEMPLATE_FINAL,
        input_variables=["balance", "financial_history", "goal", "income"]
    )

    return LLMChain(llm=llm, prompt=final_prompt, output_key="result")

    ### uncomment to add sponsor messages
    # sponsors_prompt = PromptTemplate(
    #     template=TEMPLATE_SPONSORS_,
    #     input_variables=["financial_history"]
    # )
    # sponsors_chain = LLMChain(llm=llm, prompt=sponsors_prompt, output_key="sponsor")
    # return SequentialChain(
    #     chains=[sponsors_chain, final_chain],
    #     input_variables=["balance", "financial_history", "goal", "income"],
    #     output_variables=["result"],
    # )

def lambda_handler(event, context):
    print(event)

    llm_chain = get_chain()
    llm_results = llm_chain(event)
    print(llm_results["result"]["data"])

    return {
        "statusCode": 200,
        "body": {
            "result": llm_results["result"],
        }
    }

# Test locally
if __name__ == "__main__":
    inputs = { "data": {
        #         "balance": "1000 CZK",
        #         "goal": "save 1000000 CZK for a new house",
        #         "financial_history": """
        # type|date|amount|currency|note
        # DEBIT|21.04.2023|2000|CZK|ESSENTIAL|ČEZ PRODEJ, A.S.
        # DEBIT|21.04.2023|3598|CZK|ESSENTIAL|Spol.vl.jed.domu Vodova 92
        # DEBIT|20.04.2023|1279|CZK|NON_ESSENTIAL|MCDONALDS JINDRICHUV HRADEC
        # CREDIT|20.04.2023|55000|CZK|INCOME|MGR. MATEJ PRISTAK
        # DEBIT|20.04.2023|31281|CZK|NON_ESSENTIAL|PRISTAK MATEJ
        # DEBIT|17.04.2023|1279|CZK|NON_ESSENTIAL|MCDONALDS JINDRICHUV HRADEC
        # DEBIT|17.04.2023|548|CZK|ESSENTIAL|O2 Czech Republic a.
        # DEBIT|17.04.2023|250|CZK|ESSENTIAL|STARNET, s.r.o.
        # DEBIT|17.04.2023|3230|CZK|ESSENTIAL|EYELLO CZ, K.S.
        # DEBIT|17.04.2023|1630|CZK|ESSENTIAL|EYELLO CZ, K.S.
        # DEBIT|15.04.2023|1279|CZK|NON_ESSENTIAL|MCDONALDS JINDRICHUV HRADEC
        # CREDIT|12.04.2023|20831|CZK|INCOME|UlovDomov.cz s.r.o.
        # DEBIT|11.04.2023|3830|CZK|ESSENTIAL|Spol.vl.jed.domu Vodova 92
        # DEBIT|11.04.2023|1142|CZK|ESSENTIAL|Platební brána ČSOB
        # DEBIT|06.04.2023|1279|CZK|NON_ESSENTIAL|MCDONALDS JINDRICHUV HRADEC
        # CREDIT|06.04.2023|802|CZK|INCOME|ZASILKOVNA S.R.O.
        # """
        # In April, you had a total income of 78,633 CZK and spent 45,736 CZK, with essential expenses being 27,277 CZK and non-essential expenses totaling 18,459 CZK.
        #
        # With your current savings rate, you are moving closer to your goal of saving 1,000,000 CZK for a new house. Great job! As a reward, you might enjoy our sponsor's offer, "Degustační menu na Pivolodi."
        #
        # To improve your savings, consider reducing non-essential expenses, such as the 5,116 CZK spent on McDonald's visits. Cutting back on these outings could significantly increase your monthly savings.

        #             "balance": "500000 CZK",
        #             "goal": "save 1000000 CZK for a new car until the end of this year",
        #             "financial_history": """
        #     type|date|amount|currency|note
        #     DEBIT|21.04.2023|2000|CZK|ESSENTIAL|ČEZ PRODEJ, A.S.
        #     DEBIT|21.04.2023|3598|CZK|ESSENTIAL|Spol.vl.jed.domu Vodova 92
        #     DEBIT|20.04.2023|1279|CZK|NON_ESSENTIAL|MCDONALDS JINDRICHUV HRADEC
        #     CREDIT|20.04.2023|275000|CZK|INCOME|MGR. MATEJ PRISTAK
        #     DEBIT|20.04.2023|11281|CZK|NON_ESSENTIAL|PRISTAK MATEJ
        #     DEBIT|17.04.2023|1279|CZK|NON_ESSENTIAL|MCDONALDS JINDRICHUV HRADEC
        #     DEBIT|17.04.2023|548|CZK|ESSENTIAL|O2 Czech Republic a.
        #     DEBIT|17.04.2023|250|CZK|ESSENTIAL|STARNET, s.r.o.
        #     DEBIT|17.04.2023|3230|CZK|ESSENTIAL|EYELLO CZ, K.S.
        #     DEBIT|17.04.2023|1630|CZK|ESSENTIAL|EYELLO CZ, K.S.
        #     DEBIT|15.04.2023|1279|CZK|NON_ESSENTIAL|MCDONALDS JINDRICHUV HRADEC
        #     CREDIT|12.04.2023|20831|CZK|INCOME|UlovDomov.cz s.r.o.
        #     DEBIT|11.04.2023|3830|CZK|ESSENTIAL|Spol.vl.jed.domu Vodova 92
        #     DEBIT|11.04.2023|1142|CZK|ESSENTIAL|Platební brána ČSOB
        #     DEBIT|06.04.2023|1279|CZK|NON_ESSENTIAL|MCDONALDS JINDRICHUV HRADEC
        #     CREDIT|06.04.2023|802|CZK|INCOME|ZASILKOVNA S.R.O.
        # """
        # Hey Matej, in April you had a total income of 304,633 CZK and spent 27,036 CZK, with 9,066 CZK on non-essential expenses like McDonald's visits.
        #
        # Great job on saving so far! You're halfway to your goal of 1,000,000 CZK for a new car by the end of the year. Treat yourself to a "Degustační menu na Pivolodi" for a unique dining experience with beer tasting.
        #
        # To save even more, consider cutting back on non-essential expenses like McDonald's visits, which totaled 5,116 CZK in April. Reducing these expenses could help you reach your goal even faster.

        "balance": "1000 CZK",
        "goal": "save 5000 CZK a month",
        "income": "48000 CZK",
        "financial_history": """
        type|date|amount|currency|note
        DEBIT|21.04.2023|2000|CZK|ESSENTIAL|ČEZ PRODEJ, A.S.
        DEBIT|21.04.2023|3598|CZK|ESSENTIAL|Spol.vl.jed.domu Vodova 92
        DEBIT|20.04.2023|1279|CZK|NON_ESSENTIAL|MCDONALDS JINDRICHUV HRADEC
        DEBIT|20.04.2023|31281|CZK|NON_ESSENTIAL|PRISTAK MATEJ
        DEBIT|17.04.2023|1279|CZK|NON_ESSENTIAL|MCDONALDS JINDRICHUV HRADEC
        DEBIT|17.04.2023|548|CZK|ESSENTIAL|O2 Czech Republic a.
        DEBIT|17.04.2023|250|CZK|ESSENTIAL|STARNET, s.r.o.
        DEBIT|17.04.2023|3230|CZK|ESSENTIAL|EYELLO CZ, K.S.
        DEBIT|17.04.2023|1630|CZK|ESSENTIAL|EYELLO CZ, K.S.
        DEBIT|15.04.2023|1279|CZK|NON_ESSENTIAL|MCDONALDS JINDRICHUV HRADEC
        DEBIT|11.04.2023|3830|CZK|ESSENTIAL|Spol.vl.jed.domu Vodova 92
        DEBIT|11.04.2023|1142|CZK|ESSENTIAL|Platební brána ČSOB
        DEBIT|06.04.2023|1279|CZK|NON_ESSENTIAL|MCDONALDS JINDRICHUV HRADEC
        """
        # Hey Matej, you rockin' spender! Last month you had a total outgoing of 45,826 CZK, with 23,579 CZK on essential expenses and 22,247 CZK on non-essential ones.
        #
        # Amazingly, your balance ended at 4,174 CZK, which means you almost reached your goal to save 5,000 CZK a month. High five!
        #
        # Now, let's make a tiny change to hit that goal: maybe cut down on those tasty McDonald's trips, which cost you 5,116 CZK last month. With this tweak, you'll be a saving superstar in no time!
    }}

    print(lambda_handler(inputs, None))


import matplotlib.pyplot as plt
import pandas as pd
import argparse
import json

from importlib import reload

def load_file(input_file):
    loaded = []
    with open(input_file) as jfile:
        for jline in jfile:
            load_dict = {}
            data = json.loads(jline)
            loaded.append({'x' : data['x'], 'y' : data['y']})
    return pd.DataFrame(loaded)

def plot_histogram(df, out_file="hist.png"):
    plt.hist(x=df.sort_values(by=['x'])['x'], bins=df['x'].size, weights=df.sort_values(by=['x'])['y'])
    plt.savefig(out_file)

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('--input_file', type=str, help='input file')
    args = parser.parse_args()
    df = load_file(args.input_file)
    plot_histogram(df)


import argparse
import logging
import os
import sys

from datasets.email_dataset import EmailDataset
from train_builder import TrainBuilder

class ExperimentEmail:

    def __init__(self):
        pass

    def run(self, train_file, val_file, out_dir, batch_size=32, epochs=10, **kwargs):
        # Set up dataset
        train_dataset = EmailDataset(train_file)
        val_dataset = EmailDataset(val_file)

        # Get trainpipeline
        builder = TrainBuilder(epochs=epochs, batch_size=batch_size, kwargs=kwargs)
        train_pipeline = builder.get_pipeline(train_dataset)

        # Start training
        train_pipeline.run(train_dataset, val_dataset, out_dir)

def list_csv_files(path, limit):
    files = [os.path.join(path, f) for f in
             filter(lambda x: os.path.isfile(os.path.join(path, x)) and x.endswith(".csv"), os.listdir(path))]
    assert len(files) == limit, "Expected exactly {} .csv file in {}, but found {}".format(limit, path, len(files))

    return files

if __name__ == '__main__':
    parser = argparse.ArgumentParser()

    parser.add_argument("--traindir",
                        help="The input train  data", default=os.environ.get("SM_CHANNEL_TRAIN", None))
    parser.add_argument("--valdir",
                        help="The input val data", default=os.environ.get("SM_CHANNEL_VAL", None))

    parser.add_argument("--outdir", help="The output dir", default=os.environ.get("SM_MODEL_DIR", None))

    parser.add_argument("--batchsize", help="The batch size", type=int, default=32)

    parser.add_argument("--epochs", help="The number of epochs", type=int, default=10)

    parser.add_argument("--log-level", help="Log level", default="INFO", choices={"INFO", "WARN", "DEBUG", "ERROR"})

    args = parser.parse_args()

    print(args.__dict__)

    # Set up logging
    logging.basicConfig(level=logging.getLevelName(args.log_level), handlers=[logging.StreamHandler(sys.stdout)],
                        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')

    train_csv_file = list_csv_files(args.traindir, limit=1)[0]
    val_csv_file = list_csv_files(args.valdir, limit=1)[0]

    ExperimentEmail().run(train_csv_file,
                          val_csv_file,
                          args.outdir,
                          args.batchsize,
                          args.epochs)


"""
DJANGO DB TOOLS MODULE
"""
from django.db import connection

def executeRawSqlQuery(query):
    """
    executes a SQL query and returns the result
    """
    cursor = connection.cursor()
    try:
        cursor.execute(query)
        return cursor.fetchall()
    finally:
        cursor.close()


from fastapi import APIRouter, Body, Depends, Request

from app.middlewares import JWTBearer, Role
from app.repositories import supabase
from app.schemas import PoseSet, PoseSetInsert, PoseSetWithPoses

router = APIRouter(
    prefix="/pose_sets", tags=["Pose sets"], dependencies=[Depends(JWTBearer())])

@router.get("/")
def get_pose_sets(request: Request):
    res = supabase.table("pose_sets").select(
        "*,poses(*,cover_image:images!poses_image_fkey(*),skeleton_image:images!poses_skeleton_image_fkey(*))").execute()

    pose_sets_with_poses = [PoseSetWithPoses(**pose_set)
                            for pose_set in res.data]

    return {"data": pose_sets_with_poses, "count": len(pose_sets_with_poses)}

@router.post("/new", dependencies=[Depends(JWTBearer(Role.ADMIN))])
def create_pose_set(new_pose_set: PoseSetInsert = Body(...)):
    pose_res = supabase.table("pose_sets").insert(
        json={"name": new_pose_set.name}).execute()

    pose_set = PoseSet(**pose_res.data[0])

    pose_set_poses_res = supabase.table("pose_sets_poses").insert(json=[
        {"set_id": pose_set.id, "pose_id": pose} for pose in new_pose_set.poses
    ]).execute()

    pose_set_with_poses_res = supabase.table("pose_sets").select(
        "*,poses(*,cover_image:images!poses_image_fkey(*),skeleton_image:images!poses_skeleton_image_fkey(*))").eq("id", pose_set.id).single().execute()

    print(pose_set_with_poses_res.data)

    pose_set_with_poses = PoseSetWithPoses(**pose_set_with_poses_res.data)

    return {"data": pose_set_with_poses, "count": 1}


from collections import defaultdict
from typing import Any, Dict

from llama_index.llama_pack.base import BaseLlamaPack
from llama_index.node_parser.text.utils import split_by_sentence_tokenizer
from llama_index.query_engine import BaseQueryEngine, CustomQueryEngine
from llama_index.response.schema import RESPONSE_TYPE
from llama_index.schema import MetadataMode

DEFAULT_THRESHOLD = 50

class FuzzyCitationQueryEngine(CustomQueryEngine):
    """
    Runs any query engine and then analyzes the response to find relevant sentences.

    Using fuzzy matching, response.metadata is assigned to a dictionary containing a
    mapping of response+node sentence pairs and the node text start and end character
    indices in the original document + the node that the sentence came from.

    Example:
      print(response.metadata)
      >>> {("response_sent", "node_sent"): (0, 25, <BaseNode>), ...}
    """

    query_engine: BaseQueryEngine
    threshold: int = DEFAULT_THRESHOLD

    def get_relevant_sentences(
        self, response: RESPONSE_TYPE, threshold: int = DEFAULT_THRESHOLD
    ) -> Dict[str, Dict[str, Any]]:
        """Get relevant sentences from a response."""
        from thefuzz import fuzz

        tokenizer = split_by_sentence_tokenizer()

        results = {}
        for source_node in response.source_nodes:
            node = source_node.node
            response_sentences = tokenizer(str(response))
            node_sentences = tokenizer(
                node.get_content(metadata_mode=MetadataMode.NONE)
            )

            result_matrix = {}
            for i, response_sentence in enumerate(response_sentences):
                for j, node_sentence in enumerate(node_sentences):
                    result_matrix[(i, j)] = fuzz.ratio(response_sentence, node_sentence)

            top_sentences = {}
            for j in range(len(node_sentences)):
                scores = [result_matrix[(i, j)] for i in range(len(response_sentences))]
                max_value = max(scores)
                if max_value > threshold:
                    response_sent_idx = scores.index(max_value)
                    top_sentences[(response_sent_idx, j)] = node_sentences[j]

            # concat nearby sentences
            top_chunks = defaultdict(list)
            prev_idx = -1
            for response_sent_idx, node_sent_idx in sorted(top_sentences.keys()):
                if prev_idx == -1:
                    top_chunks[response_sent_idx].append(
                        top_sentences[(response_sent_idx, node_sent_idx)]
                    )
                elif node_sent_idx - prev_idx == 1:
                    top_chunks[response_sent_idx][-1] += top_sentences[
                        (response_sent_idx, node_sent_idx)
                    ]
                else:
                    top_chunks[response_sent_idx].append(
                        top_sentences[(response_sent_idx, node_sent_idx)]
                    )
                prev_idx = node_sent_idx

            # associate chunks with their nodes
            for response_sent_idx, chunks in top_chunks.items():
                for chunk in chunks:
                    start_char_idx = node.get_content(
                        metadata_mode=MetadataMode.NONE
                    ).find(chunk)
                    end_char_idx = start_char_idx + len(chunk)

                    response_sent = response_sentences[response_sent_idx]
                    results[(response_sent, chunk)] = {
                        "start_char_idx": start_char_idx,
                        "end_char_idx": end_char_idx,
                        "node": node,
                    }

        return results

    def custom_query(self, query_str: str) -> RESPONSE_TYPE:
        """Custom query."""
        response = self.query_engine.query(query_str)
        fuzzy_citations = self.get_relevant_sentences(
            response, threshold=self.threshold
        )
        response.metadata = fuzzy_citations
        return response

    async def acustom_query(self, query_str: str) -> RESPONSE_TYPE:
        """Async custom query."""
        response = await self.query_engine.aquery(query_str)
        fuzzy_citations = self.get_relevant_sentences(
            response, threshold=self.threshold
        )
        response.metadata = fuzzy_citations
        return response

class FuzzyCitationEnginePack(BaseLlamaPack):
    def __init__(
        self, query_engine: BaseQueryEngine, threshold: int = DEFAULT_THRESHOLD
    ) -> None:
        """Init params."""
        try:
            from thefuzz import fuzz  # noqa: F401
        except ImportError:
            raise ImportError(
                "Please run `pip install thefuzz` to use the fuzzy citation engine."
            )

        self.query_engine = FuzzyCitationQueryEngine(
            query_engine=query_engine, threshold=threshold
        )

    def get_modules(self) -> Dict[str, Any]:
        """Get modules."""
        return {
            "query_engine": self.query_engine,
            "query_engine_cls": FuzzyCitationQueryEngine,
        }

    def run(self, query_str: str, **kwargs: Any) -> RESPONSE_TYPE:
        """Run the pipeline."""
        return self.query_engine.query(query_str)


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

import tensorflow as tf
import os
import tempfile
from six.moves import urllib
import gzip
import shutil # shell utilities
import numpy as np

def read32(bytestream):
    # '>' 大端
    dt = np.dtype(np.uint32).newbyteorder('>')
    return np.frombuffer(bytestream.read(4), dtype=dt)[0]

# magic | num_images | rows | cols
def check_image_file_header(filename):
    with tf.gfile.Open(filename, 'rb') as f:
        magic = read32(f)
        read32(f)
        rows = read32(f)
        cols = read32(f)
        if magic != 2051:
            raise ValueError('Invalid magic number %d in MNIST file %s' % (magic,
                                                                           f.name))
        if rows != 28 or cols != 28:
            raise ValueError(
                'Invalid MNIST file %s: Excepted 28x28 images, found %dx%d' % (f.name, rows, cols))

def check_label_file_header(filename):
    with tf.gfile.Open(filename, 'rb') as f:
        magic = read32(f)
        read32(f)
        if magic != 2049:
            raise ValueError('Invalid magic number %d in MNIST file %s' % (magic,
                                                                           f.name))

def download(dir, filename):
    filepath = os.path.join(dir, filename)
    if tf.gfile.Exists(filepath):
        return filepath
    if not tf.gfile.Exists(dir):
        tf.gfile.MakeDirs(dir)
    url = 'https://storage.googleapis.com/cvdf-datasets/mnist/' + filename + '.gz'
    _, zipped_filepath = tempfile.mkstemp(suffix='.gz')
    urllib.request.urlretrieve(url, zipped_filepath)
    with gzip.open(zipped_filepath, 'rb') as f_in, \
        tf.gfile.Open(filepath, 'wb') as f_out:
        shutil.copyfileobj(f_in, f_out)
    os.remove(zipped_filepath)
    return filepath

def dataset(directory, images_file, labels_file):
    images_file = download(directory, images_file)
    labels_file = download(directory, labels_file)
    check_image_file_header(images_file)
    check_label_file_header(labels_file)

    def decode_image(image):
        # decode_raw, 将字符串解析成图像对应的像素数组
        # tf.string -> [tf.uint8]
        image = tf.decode_raw(image, tf.uint8)
        image = tf.cast(image, tf.float32)
        image = tf.reshape(image, [784])
        return image / 255.0

    def decode_label(label):
        label = tf.decode_raw(label, tf.uint8)
        label = tf.reshape(label, [])
        return tf.cast(label, tf.int32)

    images = tf.data.FixedLengthRecordDataset(
        # map() , Maps `map_func` across the elements of this dataset.
        images_file, 28 * 28, header_bytes=16).map(decode_image)
    labels = tf.data.FixedLengthRecordDataset(
        labels_file, 1, header_bytes=8).map(decode_label)
    return tf.data.Dataset.zip((images, labels))

def train(directory):
    return dataset(directory, 'train-images-idx3-ubyte',
                   'train-labels-idx1-ubyte')

def test(directory):
    return dataset(directory, 't10k-images-idx3-ubyte', 't10k-labels-idx1-ubyte')


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

# In[146]:

import numpy as np
import pandas as pd
import pandas_datareader as pdr #to access live data from yahoo api
import matplotlib.pyplot as plt
from matplotlib import rcParams
rcParams['figure.figsize'] = (20,10)
rcParams["keymap.pan"]
import seaborn as sns
sns.set_theme()

# In[34]:

import yfinance as yf
yf.pdr_override() # <== that's all it takes :-)
from pandas_datareader import data as pdr

amzn = pdr.get_data_yahoo('AMZN').reset_index()

# In[49]:

plottable = amzn[amzn['Date'] > '2020-01-01']

# In[64]:

amzn_close = amzn[amzn['Date'] > '2020-01-01']['Close']
amzn_close_dates = amzn[amzn['Date'] > '2020-01-01']['Date']

amzn_close_dates.head()

# In[54]:

amzn_close.dropna(inplace=True)

# In[56]:

amzn_close

# In[55]:

amzn_close

# In[81]:

ema_series_20 = amzn_close.rolling(window=20).mean()
ema_series_20.fillna(0)
ema_series_50 = amzn_close.rolling(window=50).mean()
ema_series_50.fillna(0)

# In[82]:

whole_thing = pd.DataFrame({'Date': amzn_close_dates, '20 day': ema_series_20, '50 day': ema_series_50})

# In[84]:

whole_thing.fillna(0)

# In[152]:

ema_20_arr = ema_series_20.to_numpy()
ema_50_arr = ema_series_50.to_numpy()
date_arr = whole_thing['Date'].to_numpy()

idx = np.argwhere(np.diff(np.sign(ema_20_arr - ema_50_arr))).flatten()

BUY = []
buy_idx = []
SELL = []
sell_idx = []

amzn['MACD Decision'] = "WAIT"

for i, index_val in np.ndenumerate(idx):
    if ema_20_arr[index_val - 1] > ema_50_arr[index_val - 1]:
        amzn['MACD Decision'].iloc[index_val] = "SELL"
        SELL.append(index_val)
    else:
        amzn['MACD Decision'].iloc[index_val] = "BUY"
        BUY.append(index_val)

print(amzn['MACD Decision'].unique())

# In[133]:

#implement rsi

#BUY → MACD crossover with BUY signal & RSI in oversold region
#SELL → MACD crossover with SELL signal & RSI in overbought region

def getRS(series_obj):
    x = series_obj.to_numpy()
    pos = np.where(x > 0)
    neg = np.where(x <= 0)
    return np.sum(pos)/np.sum(neg)

amzn['Price Change'] = amzn['Open'] - amzn['Close']
amzn['Change Type'] = amzn['Price Change'].apply(lambda x: "Up" if x > 0 else "Down")
amzn['RS'] = amzn['Price Change'].rolling(window=14).apply(getRS)

# In[134]:

amzn['RS'][:16]

# In[135]:

amzn['RSI'] = 100/(1 + amzn['RS'])

# In[136]:

amzn['RSI']

# In[160]:

amzn['RSI Decision'] = amzn['RSI'].apply(lambda x: "BUY" if x < 30 else "SELL" if x > 70 else "WAIT")

conditions = [
    amzn['MACD Decision'].eq('BUY') & amzn['RSI Decision'].eq('BUY'),
    amzn['MACD Decision'].eq('SELL') & amzn['RSI Decision'].eq('SELL')
]

choices = ["BUY","SELL"]

amzn['MACD RSI Decision'] = np.select(conditions, choices, default="WAIT")

# In[177]:

idx_overall_buy = np.argwhere((amzn['MACD RSI Decision']=="BUY").to_numpy()).flatten()
idx_overall_sell = np.argwhere((amzn['MACD RSI Decision']=="SELL").to_numpy()).flatten()

close_nump = amzn['Close'].iloc[idx_overall_sell]

print(close_nump)

print(idx_overall_buy, idx_overall_sell)

# In[176]:

rsi_buy = pd.DataFrame({'Close': amzn[amzn['RSI Decision'] == "BUY"]['Close'], 'Date': amzn[amzn['RSI Decision'] == "BUY"]['Date']})
rsi_sell = pd.DataFrame({'Close': amzn[amzn['RSI Decision'] == "SELL"]['Close'], 'Date': amzn[amzn['RSI Decision'] == "SELL"]['Date']})

#plt.plot(rsi_buy['Date'], rsi_buy['Close'], color='black', label = "RSI buy regions")
#plt.plot(rsi_sell['Date'], rsi_sell['Close'], color='red', label = "RSI sell regions")

plt.title('MACD: crossover of 20 day ma and 50 ma for Amazon from 2020')
plt.plot(whole_thing['Date'], ema_20_arr, label = "20 day ma")
plt.plot(whole_thing['Date'], ema_50_arr, label = "50 day ma")

#plt.plot(whole_thing['Date'].to_numpy()[idx_overall_buy], amzn['Close'].to_numpy()[idx_overall_buy], '*', color = 'purple', label = "BUY")
#plt.plot(whole_thing['Date'].to_numpy()[idx_overall_sell], amzn['Close'].to_numpy()[idx_overall_sell], '*', color = 'green', label = "SELL")

plt.plot(date_arr[BUY], ema_20_arr[BUY], '*', color = 'purple', label="BUY")
plt.plot(date_arr[SELL], ema_20_arr[SELL], '*', color = 'green', label="SELL")

plt.legend()

# In[ ]:


import socket
import threading
import socketserver
import uuid

class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):

    def handle(self):
        id = uuid.uuid4()
        data = str(self.request.recv(1024), 'ascii')
        cur_thread = threading.current_thread()
        mensaje = data.split(" ")
        operacion = mensaje[0]
        print(mensaje)
        response = bytes("Default", 'ascii')
        if operacion == "nocompra":
            #print(str(mensaje[0]) + " " +  str(mensaje[1]))
            respuesta = "nocompra_exitoso " + str(mensaje[1])
            response = bytes(str(respuesta), 'ascii')
        if operacion == "noventa":
            #print(str(mensaje[0]) + " " +  str(mensaje[1]))
            respuesta = "noventa_exitoso " + str(mensaje[1])
            response = bytes(str(respuesta), 'ascii')
        if operacion == "compra":
            response = bytes(str(id), 'ascii')
        if operacion == "venta":
            response = bytes(str(id), 'ascii')
        self.request.sendall(response)

class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass

def client(ip, port, message):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((ip, port))
    try:
        sock.sendall(bytes(message, 'ascii'))
        response = str(sock.recv(1024), 'ascii')
        print("Received: {}".format(response))
    finally:
        sock.close()


import eam_core.util as util
import unittest
import os
from deepdiff import DeepDiff

import eam_core.yaml_runner
from eam_core.yaml_runner import load_configuration
from eam_core.YamlLoader import YamlLoader
from types import SimpleNamespace
import yaml
from ruamel import yaml

def compare_objects(first_object, second_object, ignore_order=False, report_repetition=False, significant_digits=None,
                    verbose_level=2):
    """
    Return difference between two objects.
    :param first_object: first object to compare
    :param second_object: second object to compare
    :param ignore_order: ignore difference in order
    :param report_repetition: report when is repetition
    :param significant_digits: use to properly compare numbers(float arithmetic error)
    :param verbose_level: higher verbose level shows you more details - default 0.
    :return: difference between two objects
    """

    diff = DeepDiff(first_object, second_object, ignore_order=ignore_order,
                    report_repetition=report_repetition, significant_digits=significant_digits,
                    verbose_level=verbose_level)
    return diff

def get_ids(file, flag=True):
    dict = {"IDs": flag, "analysis_config": "dev", "comment": None, "docker": True, "documentation": False,
            "filetype": "pdf", "local": True, "sensitivity": False, "verbose": False,
            "yamlfile": "tests/models/" + file + ".yml"}
    args = SimpleNamespace(**dict)
    model_run_base_directory, simulation_run_description, yaml_struct = load_configuration(args)
    scenario = "default"
    model_output_directory = model_run_base_directory + f"/{scenario}"
    if not os.path.exists(model_output_directory):
        os.makedirs(model_output_directory)
    create_model_func, sim_control, yaml_struct = eam_core.yaml_runner.prepare_simulation(model_output_directory,
                                                                                simulation_run_description, yaml_struct,
                                                                                scenario, filename=args.yamlfile,
                                                                                IDs=args.IDs)
    loader = YamlLoader(version=yaml_struct.get('variant', 1))
    loader.parse_yaml_structure(yaml_struct, sim_control)
    old = open("tests/models/" + file + "_copy.yml")
    old_struct = yaml.load(old, Loader=yaml.RoundTripLoader)
    new = open("tests/models/" + file + ".yml")
    new_struct = yaml.load(new, Loader=yaml.RoundTripLoader)
    diff = compare_objects(old_struct, new_struct)
    old.close()
    new.close()
    with open("tests/models/" + file + ".yml", 'w') as file:
        yaml.dump(old_struct, file, default_flow_style=False, Dumper=yaml.RoundTripDumper,
                  width=4096)
    return diff, loader.id_map

class TestProcessIDs(unittest.TestCase):

    def test_existing_ids(self):
        diff, id_map = get_ids("existing_ids")
        assert (diff == {})
        assert id_map["process"] == {"CDN": 0, "Internet Network": 1, "Laptop": 2}

    def test_some_existing_ids(self):
        diff, id_map = get_ids("some_existing_ids")
        assert (diff == {'dictionary_item_added': {"root['Processes'][1]['id']": 4, "root['Processes'][2]['id']": 5}})
        assert id_map["process"] == {"CDN": 3, "Internet Network": 4, "Laptop": 5}

    def test_no_existing_ids(self):
        diff, id_map = get_ids("no_existing_ids")
        print(diff)
        assert diff == {'dictionary_item_added': {"root['Processes'][0]['id']": 0, "root['Processes'][1]['id']": 1,
                                                  "root['Processes'][2]['id']": 2}}
        assert id_map["process"] == {"CDN": 0, "Internet Network": 1, "Laptop": 2}

    def test_duplicate_ids(self):
        with self.assertRaises(Exception) as context:
            get_ids("duplicate_ids")
        self.assertTrue('Duplicate ID for process ' in str(context.exception))

    def test_no_id_flag(self):
        diff, id_map = get_ids("no_existing_ids", flag=False)
        assert diff == {}
        assert id_map["process"] == {}


from __future__ import (absolute_import, division,
                        print_function, unicode_literals)
from builtins import *

import numpy as np
import skimage.draw

def overlap_measure(A, B, resolution=250):
    # implemented according to ginneken 2002 equation (10), performance = TP/(TP+FP+FN)
    # performance = (intersection of shape 1 and 2) / (union of shape 1 and 2)
    # resolution determines the grid resolution (resolution * resolution) that is used to calculate overlap
    A = np.asanyarray(A)
    B = np.asanyarray(B)

    A_x_min, A_y_min = A.min(axis=0)
    A_x_max, A_y_max = A.max(axis=0)

    B_x_min, B_y_min = B.min(axis=0)
    B_x_max, B_y_max = B.max(axis=0)

    AB_min = np.array([np.min([A_x_min, B_x_min]), np.min([A_y_min, B_y_min])])
    AB_max = np.array([np.max([A_x_max, B_x_max]), np.max([A_y_max, B_y_max])])

    AB_size = AB_max - AB_min

    A_unit = (A - AB_min) / AB_size
    B_unit = (B - AB_min) / AB_size

    A_unit *= resolution
    B_unit *= resolution

    A_polygon = np.zeros((resolution, resolution))
    B_polygon = np.zeros((resolution, resolution))

    A_rr, A_cc = skimage.draw.polygon(A_unit[:, 1], A_unit[:, 0])
    B_rr, B_cc = skimage.draw.polygon(B_unit[:, 1], B_unit[:, 0])

    A_polygon[A_rr, A_cc] = 1
    B_polygon[B_rr, B_cc] = 1

    AB_union = np.logical_or(A_polygon, B_polygon)
    AB_intersection = np.logical_and(A_polygon, B_polygon)

    return np.count_nonzero(AB_intersection) / np.count_nonzero(AB_union)


# Databricks notebook source
from pyspark.sql import SparkSession
from pyspark.sql.functions import *

#COMMENTS -----------CREATING SPARK SESSION OBJECT
spark_sc=SparkSession.Builder().appName('Ex01').master('local[*]').getOrCreate()

# COMMAND ----------READ FILE FROM DATA BRICKS LOCATION SAVED FILE

read_data=spark_sc.read.format('csv').option('header',True).option('inferschema',True).load('/FileStore/tables/5000_Sales_Records.csv')

# COMMAND ----------DROPPING FEW UNWANTED COLUMNS FROM DATA

read_filter = read_data.drop('Region', 'Country', 'Order Priority', 'Ship Date', 'Total Profit', 'Total Cost', 'Unit Cost')

# COMMAND ----------RENAMING COLUMN NAMES BY REPLACING SPACES WITH UNDERSCORE AND USING LOWER CASES

df_1 = read_filter.withColumnRenamed('Order Id','order_id') \
.withColumnRenamed('Item Type','item_type') \
.withColumnRenamed('Sales Channel','sales_channel') \
.withColumnRenamed('Order Date','order_date') \
.withColumnRenamed('Units Sold','units_sold') \
.withColumnRenamed('Unit Price','unit_price') \
.withColumnRenamed('Total Revenue','total_revenue')

# COMMAND ----------CONVERTING DATA TYPES FOR COLUMNS

df_2 = df_1.withColumn('units_sold',col('units_sold').cast('float')) \
.withColumn('unit_price',col('unit_price').cast('float')) \
.withColumn('total_revenue',col('total_revenue').cast('float')) \
.withColumn('order_date',to_date(col('order_date'), 'M/d/yyyy'))

# COMMAND ----------CREATING TABLE IN DATABRICKS

df_2.repartition(3).write.mode('overwrite').saveAsTable('Table_Sales')


from inspect import getmro
from typing import Union, List, Dict, Any
import re
from dataclasses import fields

from sanic import response
from sanic.request import Request

from dataclasses_jsonschema import JsonSchemaMixin, SchemaType

from yrest.tree import Tree

class OpenApi():
  def v3(self):
    result = {"openapi": "3.0.1"}

    c_keys = list(self.config.keys())
    if "OA_INFO" in c_keys:
      result["info"] = self.config["OA_INFO"]

    if "OA_SERVER_DESCRIPTION" in c_keys:
      result["servers"] = [{"url": self.config["SERVER_NAME"], "description": self.config["OA_SERVER_DESCRIPTION"]}]

    result["paths"] = self._paths()

    schemas = self._correct_schemas(JsonSchemaMixin.all_json_schemas(schema_type = SchemaType.OPENAPI_3))
    result["components"] = {"x-root": self._root_model.__name__, "schemas": schemas}
    if hasattr(self, "_params"):
      result["components"]["parameters"] = self._params

    return result

  def _paths(self):
    regex = re.compile("\/new\/\w+$")
    regexsub = re.compile("\/create_\w+$")

    result = self._own_path()
    for name, data in self._introspection.items():
      paths = {}
      model = getattr(self._models, name)
      for e_name, endpoint in data.items():
        if e_name != "factories":
          for path, path_data in self._path(model, e_name, endpoint).items():
            if not regex.search(path) and not regexsub.search(path):
              for verb, verb_data in path_data.items():
                if path not in paths:
                  paths[path] = {}
                paths[path][verb] = verb_data

      if "factories" in data.keys():
        result.update(self._factories(model, data))

      if paths:
        result.update(paths)

    return result

  def _path(self, model: Tree, e_name: str, e_data: Dict[str, Union[str, Dict]]) -> Dict[str, Union[str, Dict]]:
    regex = re.compile("/{\w+_Path}")
    path = {}
    verb = e_data["verb"].lower()
    e_keys = e_data.keys()
    for url in e_data["urls"]:
      p = {}
      p[url] = {}
      p[url][verb] = {}

      if regex.match(url):
        p[url][verb]["operationId"] = f"{model.__name__}/{e_name}"
        p[url][verb]["parameters"] = self._parameters(model, url)
      else:
        p[url][verb]["operationId"] = f"Root/{e_name}"

      if "can_crash" in e_keys or "produces" in e_keys:
        p[url][verb]["responses"] = {}

        if "produces" in e_keys:
          p[url][verb]["responses"][200] = {}
          if "description" in e_data:
            p[url][verb]["responses"][200]["description"] = e_data["description"]

          p[url][verb]["responses"][200].update(self._content(e_data["produces"]))

        if "can_crash" in e_keys:
          for error in e_data["can_crash"].values():
            p[url][verb]["responses"][error["code"]] = {}
            if "description" in error:
              p[url][verb]["responses"][error["code"]]["description"] = error["description"]

            p[url][verb]["responses"][error["code"]].update(self._content(error["returns"]))

      if "consumes" in e_keys:
        p[url][verb]["requestBody"] = self._content(e_data["consumes"])

      path.update(p)

    return path

  def _factories(self, model: Tree, data):
    okResultContent = self._content(getattr(self._models, "OkResult"))["content"]
    errorMessageContent = self._content(getattr(self._models, "ErrorMessage"))["content"]

    urls = []
    if model == self._root_model:
      urls.append("/")

    if model != self._root_model or model.__name__ in data["factories"]:
      urls.append(f"/{{{model.__name__}_Path}}/")

    regex = re.compile("/{\w+_Path}")
    paths = {}
    for factory in data["factories"]:
      fact = factory.lower()
      for url in urls:
        path = f"{url}new/{fact}"
        paths[path] = {"post": {}}
        if regex.match(url):
          paths[path]["post"]["operationId"] = f"{model.__name__}/create_{fact}"
          paths[path]["post"]["parameters"] = self._parameters(model, url)
        else:
          paths[path]["post"]["operationId"] =  f"Root/create_{fact}"
        from pprint import pprint
        if f"create_{fact}" in data.keys():
          paths[path]["post"]["requestBody"] = self._content(data[f"create_{fact}"]["consumes"])
        else:
          paths[path]["post"]["requestBody"] = self._content(getattr(self._models, factory))

        paths[path]["post"]["responses"] = {
          200: {
            "description": f"Returns the data of the new {fact}",
            "content": okResultContent
          },
          400: {
            "description": f"Returns the errors if the {fact} can't be created with the provided data",
            "content": errorMessageContent
          },
          401: {
            "description": f"Returns Unauthorized if the actor is not allowed to perform the creation of the {fact}",
            "content": errorMessageContent
          },
          409: {
            "description": f"Returns an error if there is already a model with the same url",
            "content": errorMessageContent
          }
        }

    return paths

  def _own_path(self) -> Dict[str, Union[str, Dict]]:
    result = {
      "/openapi": {
        "get": {
          "responses": {
            "200": {
              "description": "Returns the app's OpenAPI definition",
              "content": {
                "application/json": {
                  "schema": {"type": "object"}
                }
              }
            }
          }
        }
      }
    }
    return result

  def _parameters(self, model: Tree, url: str):
    if not hasattr(self, "_params"):
      self._params = {}

    name = model.__name__
    param_name = f"{name}_Path"

    if param_name not in self._params.keys():
      path = {
        "name": param_name,
        "in": "path",
        "description": f"The URL of the {name} with out the first slash",
        "required": True,
        "schema": {"type": "string"}
      }

      self._params[param_name] = path

    return [self._ref(param_name, "parameters")]

  def _content(self, model: Tree, mime: str = "application/json"):
    content = {}
    content[mime] = {"schema": self._ref(model[1].__name__ if isinstance(model, tuple) else model.__name__)}
    return {"content": content}

  def _ref(self, model: Tree, context: str = "schemas"):
    return {"$ref": f"#/components/{context}/{model}"}

  def _correct_schemas(self, schemas):
    models = {model.__name__: model for model in JsonSchemaMixin.__subclasses__()}
    needed_props = {"maximum", "exclusiveMaximum", "minimum", "exclusiveMinimum", "maxLength", "minLength"}

    for schema in schemas.keys():
      if hasattr(models[schema], "__x_schema__"):
        schemas[schema].update({f"x-{key}": value for key, value in models[schema].__x_schema__.items()})
        schemas[schema][f"x-features"] = [feat.__name__ for feat in getmro(models[schema])]

      for field in fields(models[schema]):
        if hasattr(field, "metadata") and field.metadata :
          for prop in needed_props & set(field.metadata.keys()):
            schemas[schema]["properties"][field.name][prop] = field.metadata[prop]

          if "model" in field.metadata:
            schemas[schema]["properties"][field.name]["x-model"] = field.metadata["model"]

    return schemas

  def openapi(self, request: Request) -> Dict[str, str]:
    """Returns tha API's OpenAPI definition"""
    return response.json(self.v3())


#!/usr/bin/env python
# _*_ coding: utf-8 _*_
#luz maria calderon aguilera
#1-b
import matplotlib.pyplot as plt
import numpy as np
import math
x=np.linspace(-1,5,100)
g=2*x**2-8*x-11
plt.plot(g,x, linewidth=3,color='b',label='grafica')
plt.legend()
plt.title('$2x^2-8x-11$')
plt.xlabel('algo')
plt.ylabel('una funcion de algo')
plt.show()
plt.savefig('grafica.png')


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

# In[1062]:

import torch
import torch.nn as nn
import torch.nn.functional as F
import pandas as pd
import numpy as np
import cv2
# Preprocessing

from sklearn.model_selection import train_test_split

from sklearn.preprocessing import LabelEncoder, StandardScaler
from torch.utils.data import Dataset, TensorDataset
import torchvision.models as models
import torchvision.transforms as transforms

# In[1063]:

class CustomTensorDataset(Dataset):
    """TensorDataset with support of transforms.
    """
    def __init__(self, tensors, transform=None):
        #assert all(tensors[0].size(0) == tensor.size(0) for tensor in tensors)
        self.tensors = tensors
        self.transform = transform

    def __getitem__(self, index):
        x = self.tensors[0][index]

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

        y = self.tensors[1][index]

        return x, y

    def __len__(self):
        return self.tensors[0].size(0)

# In[1064]:

X = np.load('melspec_train.npy')
X = np.expand_dims(X, axis=1)
X = np.resize(X, (220, 1, 128, 216))
#X = np.resize(X, (220, 3, 128, 216))
print(X.shape)
y = np.load('y_train.npy')
scaler = StandardScaler()
X = scaler.fit_transform(X.reshape(-1, X.shape[1]*X.shape[2]*X.shape[3])).reshape(X.shape)
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2)
X_train, y_train = X, y
print(len(y_train))
print(len(y_val))
X_train.shape
X_train = torch.from_numpy(np.array(X_train)).float()
y_train = torch.from_numpy(np.array(y_train)).float()
X_val = torch.from_numpy(np.array(X_val)).float()
y_val = torch.from_numpy(np.array(y_val)).float()
X = CustomTensorDataset(tensors=(X_train, y_train))
Valid = CustomTensorDataset(tensors=(X_val, y_val))

# In[1065]:

X_test = np.load('melspec_test.npy')
X_test = np.expand_dims(X_test, axis=1)
X_test = np.resize(X_test, (15, 1, 128, 216))
#X_test = np.resize(X_test, (15, 3, 128, 216))
scaler = StandardScaler()

X_test = scaler.fit_transform(X_test.reshape(-1, X_test.shape[1]*X_test.shape[2]*X_test.shape[3])).reshape(X_test.shape)
X_test.shape
X_test = torch.from_numpy(np.array(X_test)).float()
y_test = torch.FloatTensor(X_test.shape[0])
Test = CustomTensorDataset(tensors=(X_test, y_test))

# In[1066]:

# LENet
# Model structure
cfg = [8, 16, 32, 32, 32]
#cfg = [4, 4]
class LENet(nn.Module):
    def __init__(self):
        super(LENet, self).__init__()
        self.features = self._make_layers(cfg)
        self.dropout = nn.Dropout(0.3)
        self.fc1 = nn.Linear(256, 64)
        self.fc2 = nn.Linear(64, 1)

    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size(0), -1)
        #print(x.shape)
        x = self.dropout(x)
        x = self.fc1(x)
        x = self.dropout(x)
        x = self.fc2(x)

        return x
    def _make_layers(self, cfg):
        layers = []
        in_channels = 1
        for x in cfg:
            layers += [nn.Conv2d(in_channels, x, kernel_size=3),
                        nn.BatchNorm2d(x),
                        nn.ReLU(inplace=True),
                        nn.MaxPool2d(kernel_size=2, stride=2)]
            in_channels = x
        return nn.Sequential(*layers)

# In[1067]:

trainLoader = torch.utils.data.DataLoader(X, batch_size=4, shuffle=True, num_workers=2)
valLoader = torch.utils.data.DataLoader(Valid, batch_size=1, shuffle=False, num_workers=2)
testLoader = torch.utils.data.DataLoader(Test, batch_size=1, shuffle=False, num_workers=2)

# In[1068]:

Conv_model = LENet()
"""
Conv_model = models.resnet50(pretrained=True)
for param in Conv_model.parameters():
    param.requires_grad = False

new_fc = nn.Sequential(*list(Conv_model.fc.children())[:-1] + [nn.Linear(2048, 1)])
Conv_model.fc = new_fc
"""
Conv_model = Conv_model.cuda()
# loss
criterion = nn.MSELoss(reduction='sum')
# optimizer
learning_rate = 1e-3
weight_decay = 0
optimizer = torch.optim.Adam(Conv_model.parameters(), lr = learning_rate, weight_decay=weight_decay)
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=200)

# In[1069]:

# GPU
device = 'cuda:0' if torch.cuda.is_available() else 'cpu'
print('GPU state:', device)

# In[1070]:

def val(valLoader, model):
    with torch.no_grad():
        model.eval()
        total_loss = 0
        for data in valLoader:
            inputs, label = data
            inputs, label = inputs.to(device), label.to(device)
            MLP_model = model.cuda()
            outputs = model(inputs)
            outputs = outputs[0][0]
            #print('label:', label)
            total_loss += np.abs(np.sum((label - outputs).cpu().numpy()))
        return total_loss

# In[1071]:

def train(model):
    validation_error = []
    patience = 100
    last_loss = 1e9
    trigger_times = 0
    total_epoch = 1000
    for epoch in range(total_epoch):
        running_loss = 0.0
        for times, data in enumerate(trainLoader, 0):
            inputs, labels = data
            inputs, labels = inputs.to(device), labels.to(device)

            #print(inputs.shape)
            # Zero the parameter gradients
            optimizer.zero_grad()

            # forward + backward + optimize
            outputs = model(inputs)
            outputs = outputs.reshape(-1)
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()

            # print statistics
            running_loss += loss.item()
            if times+1 == len(trainLoader):
                print('[%d/%d, %d/%d] loss: %.3f' % (epoch+1, total_epoch, times+1, len(trainLoader), running_loss))
        validation_error.append(val(valLoader, model))
        print('validation_error:', validation_error[-1])
        if validation_error[-1] > last_loss:
            trigger_times += 1
            print('trigger times:', trigger_times)
        else:
            trigger_times = 0
            print('trigger times: 0')
        if trigger_times >= patience:
            print('Early stopping!\nStart to test process.')
            break
        last_loss = validation_error[-1]
    print('Finished Training')

# In[1072]:

train(Conv_model)

# In[1073]:

PATH = './Conv_Net_melspec.pth'
torch.save(Conv_model.state_dict(), PATH)

# In[1074]:

PATH = './Conv_Net_melspec.pth'
net = LENet()
"""
net = models.resnet50(pretrained=True)
for param in net.parameters():
    param.requires_grad = False

new_fc = nn.Sequential(*list(net.fc.children())[:-1] + [nn.Linear(2048, 1)])
net.fc = new_fc
"""
net.load_state_dict(torch.load(PATH))
net = net.cuda()

# In[1075]:

# inference
predicted_res = []
with torch.no_grad():
    net.eval()
    for data in testLoader:
        input, label = data
        input = input.to(device)
        output = net(input)
        output = output.cpu().numpy()
        predicted_res.append(output[0][0])
submission_df = pd.read_csv('sample_submission.csv')
submission_df['score'] = predicted_res

#submission_df = submission_df.drop(['score'], axis=1)
#submission_df = submission_df.insert(1, "score", predicted_res)
submission_df.to_csv('submission/CNN_submission_melspec.csv', index=False)

# In[ ]:

get_ipython().system("jupyter nbconvert --to script 'music_regression_cnn.ipynb'")


import cv2
import numpy as np
from deepface import DeepFace
import matplotlib as plt

def detect_emotions(frame, face_cascade):
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))

    for (x, y, w, h) in faces:
        face_roi = frame[y:y + h, x:x + w]
        face = cv2.resize(face_roi, (152, 152))  # Resize to match the input shape of the model
        face = cv2.cvtColor(face, cv2.COLOR_BGR2GRAY)
        face = cv2.cvtColor(face, cv2.COLOR_GRAY2RGB)  # Convert grayscale to RGB
        face = np.expand_dims(face, axis=0)
        face = face.astype('float32') / 255.0

        # emotion_predictions = model.predict(face)[0, :]
        # emotion_index = np.argmax(emotion_predictions)
        # # emotion_label = emotion_labels[emotion_index]
        # print(emotion_index)
        # print("dekh")
        # print(emotion_predictions)

        # Perform race and gender detection
        detection = DeepFace.analyze(face_roi, actions=['race', 'gender', 'emotion'], enforce_detection=False)

        if len(detection) > 0:
            detection = detection[0]  # Access the first item in the list

            race_label = detection['dominant_race']
            gender_label = detection['dominant_gender']
            emotion = detection['dominant_emotion']
            print(detection)

            # Format the labels to display on the screen
            labels = f"A {gender_label} showing {emotion} emotion"

            cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
            cv2.putText(frame, labels, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2, cv2.LINE_AA)

    return frame