import datetime
import os
import shutil
from asyncio import constants
from glob import glob

import matplotlib.cm as cm
import matplotlib.colors as colors
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import plotly as py
import plotly.express as px
import plotly.graph_objects as go
import plotly.io as pio
from matplotlib.axis import YAxis
from matplotlib.colors import Normalize
from mpl_toolkits.mplot3d import Axes3D
from plotly.subplots import make_subplots

from plot_set import fig_init, fig_init_horizon_bar, fig_output, x_axis_scale

def get_latest_modified_file_path(dirname):
    target = os.path.join(dirname, "*")
    files = [(f, os.path.getmtime(f)) for f in glob(target)]
    latest_modified_file_path = sorted(files, key=lambda files: files[1])[-1]
    return latest_modified_file_path[0]

copy_base_dir = "G:/マイドライブ/Documents/University/lab/Research/FFGNSS/plot_result/"

# ここを設定
SEPARATION = 0
ISS = 0
IAR = 0
CALIBRATION = 0
RECEIVER = 0
FILTER = 0
PCV_METHOD = 0
COST_ACCURACY = 0
PCO = 0
REL_POS_BIAS = 0
ORBITS = 0
PCC_ERR = 1

log_base = copy_base_dir
separation_files = [
    "20230124_163016_100m",
    "20230124_165001_500m",
    "20230124_100149_1km",
    "20230124_161620_2km",
    "20230128_001743_3km",
    "20230124_170120_10km",  # 一つ抜けているのでなくしていいかも
    # "w_PCCerror/20230128_094542_100m_after_PCC",
    # "w_PCCerror/20230129_130455_500m_after_PCC",
    # "w_PCCerror/20230127_170520_WLS_PCC1cycle_1km",
    # "w_PCCerror/20230129_123418_2km_after_PCC",
    # "w_PCCerror/20230127_233258_3km_afterPCCestimation",
    # # "20230124_170120_10km",  # 一つ抜けているのでなくしていいかも
]
ISS_separation_files = [
    # "20230124_230233_WLS_postPCV_ISS_sep100m",
    # "20230124_232716_WLS_postPCV_ISS_sep500m",
    # "20230128_000212_ISS_900m_postPCO",
    # "20230130_134830_WLS_PCC1cycle1km_wo_PCO_horizon",
    "wo_PCC_estimation/20230129_142557_100m",
    "wo_PCC_estimation/20230129_144719_500m",
    "wo_PCC_estimation/20230129_140414_900m",
    # "wo_PCC_estimation/20230130_140933_wo_PCC_1km",
]
IAR_files = ["20230124_105907_wo_IAR_wo_PCCerror", "20230124_100149_w_IAR_wo_PCCerror"]
PCC_calibration_files = [
    "20230124_100149_w_IAR_wo_PCCerror",
    "20230126_160837_PCC1cycle_wo_PCC_error",
    # "20230123_110838_PCC_2cycle_1km",
]
receiver_files = [
    "20230123_081904_PCC1cycle_1km_Phoenix",
    "20230123_212716_PCC1cycle_OEM",
    "20230123_231352_PCC1cycle_SILVIA",
    "20230124_002738_PCC1cycle_TsinhuaSat",
]
filter_files = ["20230125_182712_EKF_w_IAR_w_PCCerror", "20230124_103810_AEKF_w_IAR_w_PCCerror"]
pcv_method_files = [
    "20230127_163104_wo_estimation",
    "20230127_170520_WLS_PCC1cycle",
    "20230127_171952_RES_PCC1cycle",
]
orbits_csv_files = ["dr_accuracies_all_SSO_wo2km.csv", "dr_accuracies_all_ISS.csv"]
cost_accuracy_files = [
    # "20230131_191315_WLS_10_PCC1cycle",
    # "20230130_145307_WLS_20_PCC1cycle",
    # "20230127_170520_WLS_40_PCC1cycle",
    # "20230130_150824_WLS_80_PCC1cycle",
    # "Residual/20230126_010656_RES_after2560",
    # "Residual/20230130_192307_RES_after4030",
    # "Residual/20230126_003114_RES_after_6970",
    "Residual/20230131_104331_RES_90deg_10800_after",
    "Residual/20230131_170713_RES_45deg_PCC1cycle",
    "Residual/20230131_174452_RES_30deg_PCC1cycle",
    "Residual/20230131_134355_RES_PCC1cycle_10800_15deg",
]
pco_files = [
    "20230127_163104_wo_estimation",
    "20230129_170121_only_PCO",
    "20230129_171707_only_PCO_rotate",
]
rel_pos_bias_files = [
    # "20230107_201550_after_PCV_WLS_w_rel_pos_bias_1cm_z",
    # "20230107_173154_after_PCV_WLS_w_rel_pos_bias_1cm_x",
    # "20230107_194024_after_PCV_WLS_w_rel_pos_bias_1cm_y",
    "20230107_204525_after_PCV_RES_w_rel_pos_bias_1cm_z",
    "20230107_174958_after_PCV_RES_w_rel_pos_bias_1cm_x",
    "20230107_195426_after_PCV_RES_w_rel_pos_bias_1cm_y",
]
rel_pos_bias_csv_files = ["accuracies_mean.csv", "accuracies_std.csv"]
pcc_error_files = [
    "20230316_212013_wo_calibration",
    "20230314_201311_true_PCC_wo_calibration",
]

if SEPARATION:
    log_base += "202301_thesis_separation/"
    files = separation_files
    legend_names = ["100m", "500m", "1km", "2km", "3km", "10km"]
elif ISS:
    log_base += "202301_thesis_ISS/"
    files = ISS_separation_files
    legend_names = ["100m", "500m", "900m"]
    # legend_names = ["w/o PCC estimation", "w/ PCC estimation"]
elif IAR:
    log_base += "202301_thesis_IAR/"
    files = IAR_files
    legend_names = ["w/o IAR", "w/ IAR"]
elif CALIBRATION:
    log_base += "202301_thesis_PCC_error_wo_PCCestimation/"
    files = PCC_calibration_files
    legend_names = ["w/o calibration", "1 cycle", "2 cycle"]
elif RECEIVER:
    log_base += "202301_thesis_receiver_performance/"
    files = receiver_files
    legend_names = ["Phoenix", "OEM", "NGPSR", "Tsinghua"]
elif FILTER:
    log_base += "202301_thesis_AKF/"
    files = filter_files
    legend_names = ["EKF", "AEKF"]
elif PCV_METHOD:
    log_base += "202301_thesis_1km_base_results/"
    files = pcv_method_files
    legend_names = ["w/o calibration", "Model", "Residual"]
elif ORBITS:
    log_base += "202301_thesis_orbits/"
    files = orbits_csv_files
    legend_names = [["100m", "500m", "1km", "3km"], ["100m", "500m", "900m"]]
    subplot_names = ["SSO", "ISS"]
elif COST_ACCURACY:
    log_base += "202301_thesis_computational_cost_accuracy/"
    files = cost_accuracy_files
    legend_names = ["900", "1800", "3600", "7200"]  # matrix size
    # legend_names = ["2560s", "4030s", "6970s"]  # residual time
    legend_names = ["90deg", "45deg", "30deg", "15deg"]  # residual bin size
elif PCO:
    log_base += "202301_thesis_PCO/"
    files = pco_files
    legend_names = ["w/o PCO estimation", "along-track: north", "along-track: east"]  # matrix size
elif REL_POS_BIAS:
    # log_base += "202301_thesis_relpos_performance/bias/"
    log_base += "20230130_220120_rel_pos_bias_RES/"
    files = rel_pos_bias_csv_files  # rel_pos_bias_files
    legend_names = ["radial", "tangential", "normal"]
    subplot_names = ["mean", "std"]
elif PCC_ERR:
    # log_base += "202301_thesis_PCO/"
    files = pcc_error_files
    legend_names = ["w/ error", "w/o error"]
else:
    print("false input!")
    abort()

log_bases = [log_base + each_dir + "/" for each_dir in files]  # fileを設定

output_path = "figure/"
os.makedirs(output_path, exist_ok=True)
dt_now = datetime.datetime.now()
copy_dir = copy_base_dir + dt_now.strftime("%Y%m%d_%H%M%S") + "/"
os.makedirs(copy_dir)
# shutil.copytree(s2e_log_dir, copy_dir, ignore=shutil.ignore_patterns("figure"))
accuracy_file = copy_dir + "accuracies.csv"

# accuracy_log = pd.DataFrame(columns=["name", "axis", "unit", "value"])  # ここに計算した精度を入れていく．
accuracy_log = pd.DataFrame(
    columns=["legend", "name", "axis", "unit", "mean", "std", "rms"]
)  # ここに計算した精度を入れていく．

# この二つはどっかからとってきたいな．
REDUCE_DYNAMIC = 1
GNSS_CH_NUM = 15
# SVG_ENABLE = 1
# PCV = 0
data_offset = 1000  # s 6580(WLS)
x_axis_scale = 1.0 / 3600  # sec -> hour

# true information
col_true_info = [
    "x_m_t",
    "y_m_t",
    "z_m_t",
    "t_m_t",
    "vx_m_t",
    "vy_m_t",
    "vz_m_t",
    "x_t_t",
    "y_t_t",
    "z_t_t",
    "t_t_t",
    "vx_t_t",
    "vy_t_t",
    "vz_t_t",
]
col_est_info = [
    "x_m_e",
    "y_m_e",
    "z_m_e",
    "t_m_e",
    "vx_m_e",
    "vy_m_e",
    "vz_m_e",
    "ar_m_e",
    "at_m_e",
    "an_m_e",
    "x_t_e",
    "y_t_e",
    "z_t_e",
    "t_t_e",
    "vx_t_e",
    "vy_t_e",
    "vz_t_e",
    "ar_t_e",
    "at_t_e",
    "an_t_e",
]
col_residual = [
    "res_pos_R_m",
    "res_pos_T_m",
    "res_pos_N_m",
    "res_vel_R_m",
    "res_vel_T_m",
    "res_vel_N_m",
    "res_pos_R_t",
    "res_pos_T_t",
    "res_pos_N_t",
    "res_vel_R_t",
    "res_vel_T_t",
    "res_vel_N_t",
]
col_ambiguity_main = ["N" + str(i + 1) + "_m_t" for i in range(GNSS_CH_NUM)] + [
    "N" + str(i + 1) + "_m_e" for i in range(GNSS_CH_NUM)
]
col_ambiguity_target = ["N" + str(i + 1) + "_t_t" for i in range(GNSS_CH_NUM)] + [
    "N" + str(i + 1) + "_t_e" for i in range(GNSS_CH_NUM)
]
col_ambiguity = col_ambiguity_main + col_ambiguity_target

col_MN_main = ["MN" + str(i + 1) + "_m" for i in range(GNSS_CH_NUM)]
col_MN_target = ["MN" + str(i + 1) + "_t" for i in range(GNSS_CH_NUM)]

col_M = (
    ["Mx_m", "My_m", "Mz_m", "Mt_m", "Mvx_m", "Mvy_m", "Mvz_m", "Mar_m", "Mat_m", "Man_m"]
    + col_MN_main
    + ["Mx_t", "My_t", "Mz_t", "Mt_t", "Mvx_t", "Mvy_t", "Mvz_t", "Mar_t", "Mat_t", "Man_t"]
    + col_MN_target
    + [
        "Mrr_m",
        "Mrt_m",
        "Mrn_m",
        "Mvr_m",
        "Mvt_m",
        "Mvn_m",
        "Mrr_t",
        "Mrt_t",
        "Mrn_t",
        "Mvr_t",
        "Mvt_t",
        "Mvn_t",
    ]
)

col_gnss_dir_main = ["azi" + str(i + 1) + "_m" for i in range(GNSS_CH_NUM)] + [
    "ele" + str(i + 1) + "_m" for i in range(GNSS_CH_NUM)
]
col_gnss_dir_target = ["azi" + str(i + 1) + "_t" for i in range(GNSS_CH_NUM)] + [
    "ele" + str(i + 1) + "_t" for i in range(GNSS_CH_NUM)
]
col_gnss_dir = col_gnss_dir_main + col_gnss_dir_target

col_pco = ["pco_x_m", "pco_y_m", "pco_z_m", "pco_x_t", "pco_y_t", "pco_z_t"]
col_ambiguity_flag = ["N" + str(i + 1) + "_m" for i in range(GNSS_CH_NUM)] + [
    "N" + str(i + 1) + "_t" for i in range(GNSS_CH_NUM)
]

data_col = (
    col_true_info
    + col_est_info
    + col_residual
    + col_ambiguity
    + col_M
    + ["sat_num_main", "sat_num_target", "sat_num_common"]
    + ["id_ch" + str(i + 1) + "_m" for i in range(GNSS_CH_NUM)]
    + ["id_ch" + str(i + 1) + "_t" for i in range(GNSS_CH_NUM)]
    + ["Qx_m", "Qy_m", "Qz_m", "Qt_m", "Qvx_m", "Qvy_m", "Qvz_m", "Qar_m", "Qat_m", "Qan_m"]
    + ["QN" + str(i + 1) + "_m" for i in range(GNSS_CH_NUM)]
    + ["Qx_t", "Qy_t", "Qz_t", "Qt_t", "Qvx_t", "Qvy_t", "Qvz_t", "Qar_t", "Qat_t", "Qan_t"]
    + ["QN" + str(i + 1) + "_t" for i in range(GNSS_CH_NUM)]
    + ["Rgr" + str(i + 1) + "_m" for i in range(GNSS_CH_NUM)]
    + ["Rgr" + str(i + 1) + "_t" for i in range(GNSS_CH_NUM)]
    + ["Rcp" + str(i + 1) for i in range(GNSS_CH_NUM)]
    + [
        "ax_m",
        "ay_m",
        "az_m",
        "ax_t",
        "ay_t",
        "az_t",
        "ax_dist_m",
        "ay_dist_m",
        "az_dist_m",
        "ax_dist_t",
        "ay_dist_t",
        "az_dist_t",
        "ar_dist_m",
        "at_dist_m",
        "an_dist_m",
        "ar_dist_t",
        "at_dist_t",
        "an_dist_t",
    ]
    + col_gnss_dir
    + col_pco
    + col_ambiguity_flag
    + [""]
)
acc_col = [
    "Mar_m",
    "Mat_m",
    "Man_m",
    "Mar_t",
    "Mat_t",
    "Man_t",
    "Qar_m",
    "Qat_m",
    "Qan_m",
    "Qar_t",
    "Qat_t",
    "Qan_t",
]

s2e_data_col = [
    "sat_position_i(X)[m]",
    "sat_position_i(Y)[m]",
    "sat_position_i(Z)[m]",
    "sat_acc_i_i(X)[m/s^2]",
    "sat_acc_i_i(Y)[m/s^2]",
    "sat_acc_i_i(Z)[m/s^2]",
    "sat_acc_rtn_rtn(X)[m/s^2]",
    "sat_acc_rtn_rtn(Y)[m/s^2]",
    "sat_acc_rtn_rtn(Z)[m/s^2]",
    "gnss_position_eci(X)[m]",
    "gnss_position_eci(Y)[m]",
    "gnss_position_eci(Z)[m]",
    "gnss_arp_true_eci(X)[m]",
    "gnss_arp_true_eci(Y)[m]",
    "gnss_arp_true_eci(Z)[m]",
]
s2e_data_col += [col + ".1" for col in s2e_data_col]

def find_log_data(log_base: str) -> list:
    """
    log_base: plotスクリプトを実行した後の一つのログフォルダパス
    return:
        [data, data_s2e]: 独自csvとs2e logのPandasDataFrameをまとめたリスト
    """
    sim_config_path = log_base + "readme.txt"
    log_path = log_base + "result.csv"
    s2e_log_dir = log_base
    s2e_csv_log_path = (
        s2e_log_dir
        + [file for file in os.listdir(s2e_log_dir) if file.endswith(".csv")][0]  # バグりそう．
    )
    # pcc_log_path = log_base + "pcc_1.csv"
    # pcv_log_path = log_base + "pcv_1.csv"

    data = pd.read_csv(log_path, header=None)
    if len(data.columns) != len(data_col):
        REDUCE_DYNAMIC = 0
        for name in acc_col:
            data_col.remove(name)
    data = data.set_axis(data_col, axis=1)

    # ログの頻度を合わせて回すこと！
    data_s2e = pd.read_csv(s2e_csv_log_path)

    return [data, data_s2e]

# 3drmsを含めてしまいたいが
def add_accuracy(
    precision: pd.DataFrame(), legend_name: str, name: str, axis: str, unit: str
) -> None:
    global accuracy_log
    accuracy_log = accuracy_log.append(
        {
            "legend": legend_name,
            "name": name,
            "axis": axis,
            "unit": unit,
            "mean": float("{:.3f}".format(precision.mean())),
            "std": float("{:.3f}".format(precision.std())),
            "rms": float("{:.3f}".format(np.sqrt(np.mean(precision**2)))),
        },
        ignore_index=True,
    )

def add_3d_rms(
    precision: pd.DataFrame(), legend_name: str, name: str, axes: list, unit: str
) -> None:
    global accuracy_log
    _3d_ms = 0
    for axis in axes:
        _3d_ms += np.mean(precision[axis] ** 2)
    _3d_rms = np.sqrt(_3d_ms)
    accuracy_log = accuracy_log.append(
        {
            "legend": legend_name,
            "name": name,
            "axis": "3d",
            "unit": unit,
            "rms": float("{:.3f}".format(_3d_rms)),
        },
        ignore_index=True,
    )

def get_suffix(m_t: str) -> str:
    if m_t == "m":
        return "main"
    elif m_t == "t":
        return "target"
    else:
        # print("ERROR: input error!")
        return ""

def DCM_from_eci_to_lvlh(base_pos_vel):
    r_i, v_i = base_pos_vel
    z_lvlh_i = -r_i / np.linalg.norm(r_i)
    x_lvlh_i = v_i / np.linalg.norm(v_i)
    y_lvlh_i = np.cross(z_lvlh_i, x_lvlh_i)
    x_lvlh_i = np.cross(y_lvlh_i, z_lvlh_i)
    DCM_from_eci_to_lvlh = np.array([x_lvlh_i, y_lvlh_i, z_lvlh_i])
    return DCM_from_eci_to_lvlh

def DCM_from_eci_to_rtn(base_pos_vel):
    r_i, v_i = base_pos_vel
    r_rtn_i = r_i / np.linalg.norm(r_i)
    t_rtn_i = v_i / np.linalg.norm(v_i)
    n_rtn_i = np.cross(r_rtn_i, t_rtn_i)
    t_rtn_i = np.cross(n_rtn_i, r_rtn_i)
    DCM_from_eci_to_rtn = np.array([r_rtn_i, t_rtn_i, n_rtn_i])
    return DCM_from_eci_to_rtn

def calc_relinfo(r_v_a, t_e, data):
    """
    Args:
        r_v_a: position or velocity or acceleration
        t_e: true or estimation
        data: data(PandasDataframe)
    """
    if r_v_a == "r":
        base_names = ["x", "y", "z"]
    elif r_v_a == "v":
        base_names = ["vx", "vy", "vz"]
    elif r_v_a == "a":
        base_names = ["ar", "at", "an"]
    else:
        print("false input")
        return

    frame_names = ["R", "T", "N"]
    col_names = ["d" + r_v_a + "_" + frame for frame in frame_names]
    names_main = [base_name + "_m_" + t_e for base_name in base_names]
    names_target = [base_name + "_t_" + t_e for base_name in base_names]
    base = pd.DataFrame()
    for i in range(len(base_names)):
        base[col_names[i]] = data[names_target[i]] - data[names_main[i]]
    return base

# 加速度の精度
def calc_a_precision(
    data: pd.DataFrame(), data_s2e_log: pd.DataFrame(), m_t: str, frame: str
) -> pd.DataFrame():
    if frame == "eci":
        a_base_names = ["ax", "ay", "az"]
        a_names = [base_name + "_" + m_t for base_name in a_base_names]
        a_t_names = [
            "sat_acc_i_i(X)[m/s^2]",
            "sat_acc_i_i(Y)[m/s^2]",
            "sat_acc_i_i(Z)[m/s^2]",
        ]  # 一旦べた書き
    elif frame == "rtn":
        a_base_names = ["ar", "at", "an"]
        a_names = [base_name + "_" + m_t + "_e" for base_name in a_base_names]
        a_t_names = [
            "sat_acc_rtn_rtn(X)[m/s^2]",
            "sat_acc_rtn_rtn(Y)[m/s^2]",
            "sat_acc_rtn_rtn(Z)[m/s^2]",
        ]
    else:
        return
    a_dist_names = [base_name + "_dist_" + m_t for base_name in a_base_names]
    a_e = pd.DataFrame()
    for i in range(3):
        a_e[a_base_names[i]] = data[a_names[i]] * 1e-3 + data[a_dist_names[i]] * 1e6  # um/s2

    if m_t == "t":
        a_t_names = [name + ".1" for name in a_t_names]
    a_t = pd.DataFrame()
    for i in range(3):
        a_t[a_base_names[i]] = data_s2e_log[a_t_names[i]] * 1e6  # um/s2
    a_t = a_t[1:].reset_index()  # ここはs2e_logとのindexずれがあるので補正している．

    M_names = ["M" + name + "_" + m_t for name in a_base_names]

    precision = pd.DataFrame()
    for i in range(3):
        precision[a_names[i]] = a_e[a_base_names[i]] - a_t[a_base_names[i]]
    # Mのデータも追加．
    for i in range(3):
        precision[M_names[i]] = data[M_names[i]] * (1e-3) ** 2  # um/s2 Mは2乗なので
        data[M_names[i]] = precision[M_names[i]]  # dataの方にもコピー
    return precision

red_list = [(103, 0, 13), (165, 15, 21), (203, 24, 29), (239, 59, 44), (251, 106, 74)]  # Reds

color_list = [
    "darkred",
    "tomato",
    "goldenrod",
    "chartreuse",
    "darkcyan",
    "darkblue",
    "darkmagenta",
    # "darkred",
    # "chartreuse",
    # "darkblue",
    # "darkmagenta",
    # "tomato",
    # "goldenrod",
    # "darkcyan",
]

class PlotSettings:
    def __init__(self, r_v_a: str, m_t: str, data_type: str):
        self.r_v_a = r_v_a
        self.m_t = m_t
        self.suffix = get_suffix(m_t)

        if data_type == "abs_rtn":
            self.init_abs_rtn()
        elif data_type == "rel_rtn":
            self.init_rel_rtn()
        else:
            print("false input!")

    # 使わない．
    # def init_abs_eci(self):
    #     if self.r_v_a == "r":
    #         self.base_names = ["x", "y", "z"]
    #         self.axis_names = base_names
    #         self.unit = "m"
    #         self.scale_param = 1
    #     elif self.r_v_a == "v":
    #         self.base_names = ["vx", "vy", "vz"]
    #         self.axis_names = ["v_x", "v_y", "v_z"]
    #         self.unit = "mm/s"
    #         self.scale_param = 1000
    #     elif self.r_v_a == "a":
    #         self.base_names = ["ax", "ay", "az"]
    #         self.axis_names = ["a_x", "a_y", "a_z"]
    #         self.unit = "um/s^2"
    #         self.scale_param = 1e-3
    #     else:
    #         print("false input")

    def init_abs_rtn(self):
        if self.r_v_a == "r":
            col_base_name = "res_pos_"
            self.unit = "m"
            self.scale_param = 1
            self.output_name = "position_rtn"
            self.M_names_base = ["Mrr", "Mrt", "Mrn"]
            self.y_range = 2.5
        elif self.r_v_a == "v":
            col_base_name = "res_vel_"
            self.unit = "mm/s"
            self.scale_param = 1000
            self.output_name = "velocity_rtn"
            self.M_names_base = ["Mvr", "Mvt", "Mvn"]
            self.y_range = 5.0
        elif self.r_v_a == "a":
            self.col_names = ["a_R", "a_T", "a_N"]
            self.unit = "um/s^2"
            self.scale_param = 1
            self.output_name = "a_rtn"
            self.M_names_base = ["Mar", "Mat", "Man"]
            self.y_range = 20.0  # ホンマはautoにしたい．
        else:
            print("false input")
            return

        self.frame_names = ["R", "T", "N"]
        # ちょっと気持ち悪いので統一したい．
        if self.r_v_a != "a":
            self.col_names = [
                col_base_name + frame_name + "_" + self.m_t for frame_name in self.frame_names
            ]
        self.base_name = self.r_v_a
        self.names = [self.base_name + "_" + frame for frame in self.frame_names]

    def init_rel_rtn(self):
        if self.r_v_a == "r":
            self.unit = "cm"
            self.scale_param = 100
            self.output_name = "relative_position"
            self.M_names = ["Mrr", "Mrt", "Mrn"]
            self.y_range = 0.14 * self.scale_param  # 0.18
        elif self.r_v_a == "v":
            self.unit = "mm/s"
            self.scale_param = 1000
            self.output_name = "relative_velocity"
            self.M_names = ["Mvr", "Mvt", "Mvn"]
            self.y_range = 1.2  # 3.5
        elif self.r_v_a == "a":
            self.unit = "um/s^2"
            self.scale_param = 1
            self.output_name = "relative_a"
            self.M_names = ["Mar", "Mat", "Man"]
            self.y_range = 0.07
        else:
            print("input error!")
            return

        self.frame_names = ["R", "T", "N"]
        self.base_name = "d" + self.r_v_a
        self.col_names = [self.base_name + "_" + frame_name for frame_name in self.frame_names]
        self.names = self.col_names

def plot_multiple_precision(r_v_a: str, m_t: str, data_type: str, datas: list) -> None:
    plot_set = PlotSettings(r_v_a, m_t, data_type)
    fig = fig_init(datas[0], plot_set.names, plot_set.unit)

    for i, data in enumerate(datas):
        if data_type == "abs_rtn":
            plot_precision_rtn(fig, data, plot_set, color_list[i], legend_name=legend_names[i])
        elif data_type == "rel_rtn":
            plot_differential_precision(fig, data, plot_set, color_list[i], legend_names[i])
    fig_output(fig, output_path + plot_set.output_name + "_precision_" + plot_set.suffix)

# 座標系に対しても統合したい．
def plot_precision_rtn(
    fig, data: pd.DataFrame(), plot_set: PlotSettings, color_str: str, legend_name: str
) -> None:

    data_for_plot = data * plot_set.scale_param
    # M_names = [M_name_base + "_" + m_t for M_name_base in M_names_base]

    for i in range(len(plot_set.names)):
        add_accuracy(
            data_for_plot.loc[data_offset:, plot_set.col_names[i]],
            legend_name,
            plot_set.base_name + "_" + plot_set.m_t,
            plot_set.frame_names[i],
            plot_set.unit,
        )
        RMS = np.sqrt(np.mean(data_for_plot.loc[data_offset:, plot_set.col_names[i]] ** 2))
        show_legend = False
        if i == 0:
            show_legend = True
        fig.add_trace(
            go.Scatter(
                mode="markers",
                x=data_for_plot.index * x_axis_scale,
                y=data_for_plot.loc[:, plot_set.col_names[i]],
                name=legend_name,
                legendgroup=str(i + 1),
                marker=dict(size=2, color=color_str),
                # marker=dict(
                #     size=2,
                # ),
                showlegend=show_legend,
            ),
            row=(i + 1),
            col=1,
        )
        # # 1 sigmaを計算してプロットする．
        # fig.add_trace(
        #     go.Scatter(
        #         x=data.index * x_axis_scale,
        #         y=np.sqrt(data[M_names[i]]) * scale_param,
        #         legendgroup=str(i),
        #         line=dict(width=1, color="black"),
        #         showlegend=False,
        #     ),
        #     row=(i + 1),
        #     col=1,
        # )
        # fig.add_trace(
        #     go.Scatter(
        #         x=data.index * x_axis_scale,
        #         y=-np.sqrt(data[M_names[i]]) * scale_param,
        #         legendgroup=str(i),
        #         line=dict(width=1, color="black"),
        #         showlegend=False,
        #     ),
        #     row=(i + 1),
        #     col=1,
        # )
        fig.update_yaxes(
            range=(-plot_set.y_range, plot_set.y_range),
            row=(i + 1),
            col=1,
        )
    add_3d_rms(
        data_for_plot.loc[data_offset:, :],
        legend_name,
        plot_set.base_name + "_" + plot_set.m_t,
        plot_set.col_names,
        plot_set.unit,
    )
    # fig_output(fig, output_path + output_name + "_precision_" + suffix)

def trans_eci_to_rtn(DCMs, precision_data):
    for i in range(len(precision_data)):
        DCM = DCMs[i]
        precision_data.iloc[i, :] = np.dot(DCM, precision_data.iloc[i, :])
    return precision_data

def plot_differential_precision(
    fig, precision_data: pd.DataFrame(), plot_set: PlotSettings, color_str: str, legend_name: str
) -> None:
    precision_data *= plot_set.scale_param
    # # eci -> rtnに変換
    # if input_frame == "ECI":
    #     for i in range(len(precision_data)):
    #         DCM = DCM_from_eci_to_rtn(
    #             (data.loc[i, "x_m_t":"z_m_t"], data.loc[i, "vx_m_t":"vz_m_t"])
    #         )
    #         precision_data.iloc[i, :] = np.dot(DCM, precision_data.iloc[i, :])

    for i in range(len(plot_set.names)):
        add_accuracy(
            precision_data.iloc[data_offset:, i],
            legend_name,
            plot_set.base_name,
            plot_set.frame_names[i],
            plot_set.unit,
        )
        RMS = np.sqrt(np.mean(precision_data.iloc[data_offset:, i] ** 2))
        show_legend = False
        if i == 0:
            show_legend = True
        fig.add_trace(
            go.Scatter(
                mode="markers",
                x=precision_data.index * x_axis_scale,
                y=precision_data.iloc[:, i],
                name=legend_name,
                legendgroup=str(i + 1),
                marker=dict(size=2, color=color_str),
                # marker=dict(size=2),
                showlegend=show_legend,
            ),
            row=(i + 1),
            col=1,
        )
        # 分散のところは絶対的な状態量から出しているもので正確ではないのでplotしない．
        fig.update_yaxes(
            range=(-plot_set.y_range, plot_set.y_range),
            row=(i + 1),
            col=1,
        )
    add_3d_rms(
        precision_data.loc[data_offset:, :],
        legend_name,
        plot_set.base_name,
        plot_set.col_names,
        plot_set.unit,
    )
    # fig_output(fig, output_path + output_name + "_precision")

def plot_multiple_bar(
    accuracy_data: pd.DataFrame(), categories: list, r_v_a: str, m_t: str, data_type: str
) -> None:
    plot_set = PlotSettings(r_v_a, m_t, data_type)
    precision_title = "$" + plot_set.base_name + "[\\text{" + plot_set.unit + "}]$"
    fig = fig_init_horizon_bar([accuracy_data], legend_names, precision_title)

    for i, category in enumerate(categories):
        fig = plot_accuracy_bar(
            fig, accuracy_data[accuracy_data["legend"] == category], category, color_list[i], 1
        )

    fig.update_layout(barmode="group")
    fig_output(fig, output_path + plot_set.output_name + "_precision_bar")

def plot_accuracy_bar(
    fig: go.Figure(), accuracy_data: pd.DataFrame(), category: str, color_str: str, col_num: int
) -> go.Figure():
    fig.add_trace(
        go.Bar(
            name=category,
            x=accuracy_data["axis"],
            y=accuracy_data["rms"],
            # text=accuracy_data["std"],
            texttemplate="%{y:.3f}",
            textposition="outside",
            textfont=dict(size=25),
            marker_color=color_str,
            legendgroup=str(col_num),
            # showlegend=False,
        ),
        row=1,
        col=col_num,
    )
    # mean, stdもプロットしたいときはsubplotごとにする．
    return fig

def plot_accuracy_comparison_w_subplot(
    r_v_a: str, m_t: str, data_type: str, datas: list, categories: list, subplot_names: list
) -> None:
    plot_set = PlotSettings(r_v_a, m_t, data_type)
    fig = fig_init_horizon_bar(datas, plot_set.names, plot_set.unit)

    for j, data in enumerate(datas):
        for i, category in enumerate(categories[j]):  # categories[j]
            fig = plot_accuracy_bar(
                fig, data[data["legend"] == category], category, color_list[i], j + 1
            )
        fig.update_xaxes(
            col=j + 1,
            title=dict(
                text=subplot_names[j],
                # standoff=2,
            ),
        )
    fig.update_traces(
        showlegend=True,
        row=1,
        col=1,
    )

    fig_output(fig, output_path + plot_set.output_name + "_precision_bar_all")

# pd.options.display.float_format = "{:.2f}".format
# pd.options.display.precision = 3
data_type_abs = "abs_rtn"
data_type_rel = "rel_rtn"

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
datas_list = []
for log_path in log_bases:
    datas_list.append(find_log_data(log_path))
datas, s2e_datas = list(zip(*datas_list))

dr_precisions = []
dv_precisions = []
da_precisions = []
# am_precisions = []
# at_precisions = []

# この辺の計算が重いからやっぱり一回csvに残しておきたいな．
DCMs = []  # 主衛星の軌道は変わらないので使いまわせる．
data = datas[0]
for i in range(len(data)):
    DCMs.append(
        DCM_from_eci_to_rtn((data.loc[i, "x_m_t":"z_m_t"], data.loc[i, "vx_m_t":"vz_m_t"]))
    )
for data, s2e_data in zip(datas, s2e_datas):
    dr_precision = calc_relinfo("r", "e", data) - calc_relinfo("r", "t", data)
    dr_precisions.append(trans_eci_to_rtn(DCMs, dr_precision))

    dv_precision = calc_relinfo("v", "e", data) - calc_relinfo("v", "t", data)
    dv_precisions.append(trans_eci_to_rtn(DCMs, dv_precision))

    # a_m_precision = calc_a_precision(data, s2e_data, "m", "rtn")
    # a_t_precision = calc_a_precision(data, s2e_data, "t", "rtn")
    # # plot_precision_rtn("a", "m", a_m_precision)
    # # plot_precision_rtn("a", "t", a_t_precision)
    # da_precision = calc_relinfo("a", "e", pd.concat([a_m_precision, a_t_precision], axis=1))
    # da_precisions.append(da_precision)
    # # plot_differential_precision(
    # #     data, a_t_precision.iloc[:, 0:3] - a_m_precision.iloc[:, 0:3], "a", "RTN"
    # # )

plot_multiple_precision("r", "m", data_type_abs, datas)
# plot_multiple_precision("r", "t", data_type_abs, datas)
plot_multiple_precision("v", "m", data_type_abs, datas)
# plot_multiple_precision("v", "t", data_type_abs, datas)

plot_multiple_precision("r", "", data_type_rel, dr_precisions)
plot_multiple_precision("v", "", data_type_rel, dv_precisions)
# plot_multiple_precision("a", "", data_type_rel, da_precisions)

# bar plot
plot_multiple_bar(
    # accuracy_log.query('name.str().contains("dr")'),  # engine="python"),
    accuracy_log[accuracy_log["name"] == "dr"],
    legend_names,
    "r",
    "",
    data_type_rel,
)
plot_multiple_bar(
    # accuracy_log.query('name.str().contains("dv")'),  # engine="python"),
    accuracy_log[accuracy_log["name"] == "dv"],
    legend_names,
    "v",
    "",
    data_type_rel,
)

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# accuracy_logs = [log_base + log for log in files]
# accuracy_datas = []
# for file in accuracy_logs:
#     accuracy_datas.append(pd.read_csv(file))

# plot_accuracy_comparison_w_subplot(
#     "r", "", data_type_rel, accuracy_datas, legend_names, subplot_names
# )

accuracy_log.to_csv(accuracy_file, sep=",", index=False)
# 最後に全グラフをまとめてコピー
# shutil.move(output_path, copy_dir + "figure/")
shutil.move(output_path, copy_dir)


#this file contains a representation for a Vehicle as specified by the assignment
#a Vehicle will have the following data-members:
# -id: a self-maintained data-member to uniquely distinguish
# -brand: indicates the brand of the car, type = str
# -model: indicates the model of the car, type = str
# -km: number of kilometers done so far, type = float
# -lastservice: datetime.date object representing the last service date
import datetime as dt
from copy import deepcopy

_IDgen = 0 #ID generator, increment by 1 for each Vehicle being constructed

class Vehicle(object):
    #constructor for Vehicle,
    #takes 2 mandatory parameters and 2 optional parameters:
    # -brand: mandatory and expected type = str, otherwise raise TypeError
    # -model: mandatory and expected type = str, otherwise raise TypeError
    # -km: optional and expected type = float or int, otherwise raise TypeError
    #   default value for km is 0
    #   absolute value will be taken so negative values will have no effect...
    # -lastservice: optional and expected type = datetime.date or str,
    #                                       otherwise raise TypeError
    #   default value for lastservice is "today's" date
    #   additional check to see if lastservice isn't in the future,
    #                                       otherwise raise ValueError
    def __init__(self, brand, model, km=0, lastservice=dt.datetime.now().date()):
        #type-checking...
        if type(brand) != str \
                or type(model) != str \
                or (type(km) != int and type(km) != float) \
                or not(type(lastservice) == dt.date or type(lastservice) == str):
            raise TypeError
        if type(lastservice) == str: #attempt to construct datetime.date object
            lastservice = lastservice.replace('/', '').replace('-', '')
            lastservice = dt.datetime.strptime(lastservice, "%d%m%Y").date()
        if lastservice > dt.datetime.now().date(): #value-check
            raise ValueError
        #start of actual initialization
        global _IDgen
        self._id = _IDgen #private variable, users should touch this...
        _IDgen += 1
        self._brand = brand.upper()
        self._model = model.upper()
        self._km = abs(float(km))
        self._lastservice = lastservice

    #implements what should happen when str() is called on "this" object
    def __str__(self):
        return "%s - %s with %.2fkm, last serviced at %s" % \
               (self._brand, self._model, self._km, self._lastservice.strftime("%d/%m/%Y"))

    #simple getter for the ID
    def GetID(self):
        return deepcopy(self._id) #return a copy to prevent accidental overwrite...

    #return "Brand - Model"
    def GetName(self):
        return self._brand + " - " + self._model

    def GetKM(self):
        return self._km

    def GetLSDstring(self):
        return self._lastservice.strftime("%d/%m/%Y")

    #methods to edit the number of kilometers,
    #expects 1 mandatory argument:
    # -km: represents the new number of kilometers,
    #       type is expected to be either str, int or float
    #return True if 'self._km' was successfully edited, False otherwise
    def EditKM(self, km):
        if type(km) == str:
            #do some checks to verify valid input...
            if km == "": return False
            km = km[1:] if km[0] == '-' else km #remove '-' sign if present...
            if km.replace('.','',1).isdigit():
                self._km = abs(float(km))
                return True
            else: return False
        elif type(km) == int or type(km) == float:
            self._km = abs(float(km)) #cast to float in case type(km) is int
            #otherwise float() will have no effect
            #but we still want abs() for the absolute value...
            return True
        else:
            return False

    #method to edit the last service date,
    #takes 1 optional argument:
    # -ls: represents the new last service date,
    #       type can either be str or datetime.date
    #   in case type = str, attempt to construct a datetime.date object
    #   in case type = datetime.date, only check if date is valid...
    #return True if 'self._lastservice' was successfully updated, False otherwise
    def EditLastServiceDate(self, ls=dt.datetime.now().date()):
        if type(ls) == str:
            ls = ls.replace("/", "").replace("-", "") #clean dashes&slashes
            try:
                ls = dt.datetime.strptime(ls, "%d%m%Y").date()
            except ValueError:
                return False #meaning a bad string was passed...
        #mind that if type(ls) was initially str and
        #if the value of 'ls' was valid, type(ls) now became dt.date
        if  type(ls) == dt.date:
            #if we get here, we're almost "safe"
            #just need to check if date is valid...
            if ls > dt.datetime.now().date(): return False
            #at this point, we're considered to be "safe"
            self._lastservice = ls
            return True
        else:
            return False

    #a method wich returns "this" Vehicle as a CSV row
    def toCSVrow(self):
        a,b,c = (self._brand, self._model, self._km)
        d = self._lastservice.strftime("%d/%m/%Y")
        return "{},{},{},{}".format(a,b,c,d)

if __name__ == "__main__":
    car1 = Vehicle("BMW", "M3", 150, dt.datetime(2017, 3, 17).date())
    print(car1)
    car1.EditLastServiceDate(dt.datetime(2018, 10, 26).date())


import os
import shutil
from git import Repo
from urllib.request import urlretrieve

from flask import current_app
from flask_script import Command
from flask_script import Manager

class VendorDownload(Command):
    """Download vendor libraries"""

    def _delete_path(self, path):
        if os.path.exists(path):
            if os.path.isfile(path):
                os.remove(path)
            else:
                shutil.rmtree(path)

    def _git_download(self, location, vendor_path):
        print('- assets: downloading ' + location)
        repo_name = location.rsplit('/', 1)[-1]
        destination_path = os.path.join(vendor_path, repo_name)
        self._delete_path(destination_path)
        Repo.clone_from(location, destination_path)

    def _file_download(self, location, vendor_path):
        print('- assets: downloading ' + location)
        file_name = location.rsplit('/', 1)[-1]
        file_path = os.path.join(vendor_path, file_name)
        self._delete_path(file_path)
        urlretrieve(location, file_path)

    def run(self):
        """
        Downloads the configured assets
        """

        from app.assets import ASSET_RESOURCES

        vendor_path = os.path.join(current_app.config['BASE_DIR'], 'app', 'assets', 'vendor')

        for resource in ASSET_RESOURCES:
            if resource['type'] == 'git':
                self._git_download(resource['location'], vendor_path)
            elif resource['type'] == 'file':
                self._file_download(resource['location'], vendor_path)

VendorManager = Manager(usage='Manages vendor libraries')
VendorManager.add_command('download', VendorDownload())


"""
CoinMarketCapService implements all the apis from CoinMarketCap to get the required data
"""

import requests

from tradesense.models.crypto import Crypto

class CoinMarketCapService:
    """
    CoinMarketCapService - Handles all the requests for CoinMarketCap
    """

    def __init__(self, crypto: Crypto):
        self.crypto = crypto

    def get_market_pairs(self):
        """
        Get all the market_pairs from different exchanges based on some filters
        We can set the currency, crypto name, limit results and sort on the key that
        we want

        We sort based on price on descending order because we want to make maximum returns
        :return:
        """
        url = (
            "https://api.coinmarketcap.com/data-api/v3/cryptocurrency/market-pairs/latest?slug={slug}"
            "&start=1&quoteCurrencyId={quote_currency_id}&limit={limit}&category=spot&centerType=all"
            "&sort={sort}&direction={direction}".format(
                slug=self.crypto.slug,
                quote_currency_id=self.crypto.quote_currency_id,
                limit=self.crypto.limit,
                sort=self.crypto.sort,
                direction=self.crypto.sort_direction,
            )
        )

        payload = {}
        headers = {
            "authority": "api.coinmarketcap.com",
            "accept": "application/json, text/plain, */*",
            "accept-language": "en-IN,en-US;q=0.9,en;q=0.8,hi-IN;q=0.7,hi;q=0.6,en-GB;q=0.5",
            "cache-control": "no-cache",
            "dnt": "1",
            "origin": "https://coinmarketcap.com",
            "platform": "web",
            "referer": "https://coinmarketcap.com/",
            "sec-ch-ua": '"Not/A)Brand";v="99", "Google Chrome";v="115", "Chromium";v="115"',
            "sec-ch-ua-mobile": "?0",
            "sec-ch-ua-platform": '"Windows"',
            "sec-fetch-dest": "empty",
            "sec-fetch-mode": "cors",
            "sec-fetch-site": "same-site",
            "sec-gpc": "1",
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
            "Chrome/115.0.0.0 Safari/537.36",
            "x-request-id": "0ceaf88618924507884ce85bec07e176",
        }

        response = requests.request("GET", url, headers=headers, data=payload)

        return response.json()["data"]["marketPairs"]


import snscrape.modules.twitter as sntwitter
import pandas as pd
from langdetect import detect

# Creando la lista donde se almacenaron los Tweets  de la keyword a buscar.
tweets_list = []
keywords = 'TopGunMaverick'

# Usando TwitterSearchScraper para hacer scrape data y agregar tweets a la lista
for i,tweet in enumerate(sntwitter.TwitterSearchScraper(f'{keywords} since:2022-05-25 until:2022-05-27').get_items()):
    if i>11700:
        break
    tweets_list.append([tweet.date, tweet.content, tweet.user])

# Creando el DataFrame con la lista de tweets
tweets_df = pd.DataFrame(tweets_list, columns=['Datetime', 'Text', 'Username'])
print(tweets_df)

#----LANGUAGE DETECTION-----

lang_list = []
for tweet in tweets_df.Text:
    lang = detect(tweet)
    lang_list.append(lang)

df = pd.DataFrame({'tweet': tweets_df.Text, 'lang': lang_list})
df_es = df.loc[df['lang'] == 'es']
df_en = df.loc[df['lang'] == 'en']

#----EXPORT TO CSV-----

df.to_csv(f'{keywords}.csv')
df_es.to_csv(f'{keywords}_ES.csv')
df_en.to_csv(f'{keywords}_EN.csv')


import time
start = time.time()
#PART EXERCISE 07
from sklearn.datasets import make_moons
X,y=make_moons(n_samples=10000, noise=0.4, random_state=42)
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2)
from sklearn.tree import DecisionTreeClassifier
param_grid={'max_depth':[3,5,7,10,15],'min_samples_leaf':[1,2,3]} #Run DecisionTreeClassifier for each combination of max_depth and min_sample_leaf
from sklearn.model_selection import GridSearchCV                     #Finds the best combination of hyperparameters using cross-vaidation
grid_search=GridSearchCV(DecisionTreeClassifier(random_state=42),
                        param_grid,cv=4,                             #Creates the function to find the best model for TreeClassifier using 4 folds
                        scoring='accuracy',n_jobs=1)                #n_jobs=-1: the number of jobs is set to the number of CPU cores
grid_search.fit(X_train,y_train)
print(grid_search.best_estimator_)
grid_search.best_estimator_.fit(X_train,y_train)                                     #Runs GridSearch
from sklearn.metrics import accuracy_score
y_pred = grid_search.best_estimator_.predict(X_test)
print(accuracy_score(y_test, y_pred))

#PART EXERCISE 08
#a Continuing the previous exercise, generate 1,000 subsets of the training
# set, each containing 100 instances selected randomly. Hint: you can use
# Scikit-Learn’s ShuffleSplit class for this.
from sklearn.model_selection import ShuffleSplit
#Yields indices to split data into training and test sets
mini_sets=[]
rs=ShuffleSplit(n_splits=1000,train_size=100,random_state=42)
#n_splits: numbers of re-shuffling and splittings
#train_size
for mini_train_index, mini_test_index in rs.split(X_train):
    X_mini_train = X_train[mini_train_index]
    y_mini_train = y_train[mini_train_index]
    mini_sets.append((X_mini_train, y_mini_train))

#b Train one Decision Tree on each subset, using the best hyperparameter
# values found above. Evaluate these 1,000 Decision Trees on the test set.
# Since they were trained on smaller sets, these Decision Trees will
# likely perform worse than the first Decision Tree, achieving only about
# 80% accuracy.
from sklearn.base import clone
forest=[clone(grid_search.best_estimator_) for _ in range(1000)]
#forest is a list of 1000 models, all the same best_estimator_
accuracy_scores=[]

for tree, (X_mini_train, y_mini_train) in zip(forest, mini_sets):
    tree.fit(X_mini_train, y_mini_train)                         #Train each model with the mini_sets
    y_pred = tree.predict(X_test)                                #Predict using the whole train_set
    accuracy_scores.append(accuracy_score(y_test, y_pred))       #Accuracy measurement for each model

import numpy as np
print(np.mean(accuracy_scores))

#c Now comes the magic. For each test set instance, generate the
# predictions of the 1,000 Decision Trees, and keep only the most
# frequent prediction (you can use SciPy’s mode() function for this).
# This gives you majority-vote predictions over the test set
Y_pred = np.empty([1000, len(X_test)], dtype=np.uint8)  #Creates the empty matrix to receive the predictions

for tree_index,tree in enumerate(forest):               #For each tree model
    Y_pred[tree_index]=tree.predict(X_test)             #Each model predict the output for the test_set

from scipy.stats import mode
y_pred_majority_votes,n_votes=mode(Y_pred, axis=0)      #Selects the most predicted output

#d Evaluate these predictions on the test set: you should obtain a
# slightly higher accuracy than your first model (about 0.5 to 1.5%
# higher).
print(accuracy_score(y_test, y_pred_majority_votes.reshape([-1])))

end = time.time()
print(end - start)


#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Get City's Weather Info

Agent agregateur #1

@author: jessica chambers
"""

# Python program to find current
# weather details of several cities
# using openweathermap api

# import required modules
import requests, json, string, datetime, time, sys, socket

def get_stats_city(api_key,city_name):

    #set up log file
    log = open("cities_weather.log","a+")
    out = str(datetime.datetime.now())
    out = out  + "\n"
    log.write(out)

    # base_url variable to store url
    base_url = "http://api.openweathermap.org/data/2.5/weather?"

    # complete_url variable to store
    # complete url address
    complete_url = base_url + "appid=" + api_key + "&q=" + city_name

    # get method of requests module
    # return response object
    response = requests.get(complete_url)

    # json method of response object
    # convert json format data into
    # python format data
    x = response.json()

    # Now x contains list of nested dictionaries
    # Check the value of "cod" key is equal to
    # "404", means city is found otherwise,
    # city is not found
    if x["cod"] != "404":

        # store the value of "main"
        # key in variable y
        y = x["main"]

        # store the value corresponding
        # to the "temp" key of y
        current_temperature = y["temp"] - 273.15

        # store the value corresponding
        # to the "pressure" key of y
        current_pressure = y["pressure"]

        # store the value corresponding
        # to the "humidity" key of y
        current_humidity = y["humidity"]

        res = {'temp':y["temp"]- 273.15,'pressure':y["pressure"], 'humidity':y["humidity"]}
        # store the value of "weather"
        # key in variable z
        z = x["weather"]

        # store the value corresponding
        # to the "description" key at
        # the 0th index of z
        weather_description = z[0]["description"]

        # print following values
        out = city_name.upper() + "\n Temperature (in Celsius) = " + \
                        str(current_temperature) + \
              "\n atmospheric pressure (in hPa unit) = " + \
                        str(current_pressure) + \
              "\n humidity (in percentage) = " + str(current_humidity) + "\n"
        log.write(out)
        log.close()
        return res

    else:
        out = "\n City Not Found "
        log.write(out)
        log.close()

#main

# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Connect the socket to the port where the server is listening
server_address = ('localhost', 10000)

while(True):

    print >>sys.stderr, 'connecting to %s port %s' % server_address
    sock.connect(server_address)

    #Bordeaux weather info
    bordeaux_info = get_stats_city("ddb93c9878aa673d01095952d2761353","bordeaux")
    #le havre weather info
    le_havre_info = get_stats_city("236dc0356af0cfcbe13dcf8cba1629e5","le havre")
    #Marseille weather info
    marseille_info = get_stats_city("e418c8436cdee1933bcc58c81786747f","marseille")
    try:
        # Send data
        message = [marseille_info, bordeaux_info, le_havre_info]
        print >>sys.stderr, 'sending data to server'
        sock.sendall(str(message))

    finally:
        # Clean up the connection
        print >>sys.stderr, 'closing socket'
        sock.close()
        sock = socket.socket()

    #wait one minute
    time.sleep(60)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
#************************************************************
#*                    Data Reduction                        *
#*          Salvador Ventura - Marcial Becerril             *
#************************************************************

import numpy as np
from matplotlib import pyplot as plt
from numpy import fft

import math
import glob
import os
import sys

from astropy.io import fits
from astropy.visualization import astropy_mpl_style
plt.style.use(astropy_mpl_style)
from astropy.utils.data import get_pkg_data_filename
from astropy.io import fits

from scipy import signal
from removeCR import remCosRay

class dataRed():

    # Getting the arrays  from the fits file in the path given
    def get_arrays_fits(self, path):
        data_fits = fits.getdata(path, ext=0)
        return data_fits

    def get_header_time_stream(self, path):
        hdul = fits.open(path)
        hdr = hdul[1].header

        I0 = hdr['IF0']
        Q0 = hdr['QF0']

        dqdf = hdr['DQDF']
        didf = hdr['DIDF']

        Fs = hdr['SAMPLERA']

        actual_temp = hdr['SAMPLETE']
        kid_number = hdr['TONE']
        input_att = hdr['INPUTATT']

        f0 = hdr["SYNTHFRE"]

        return I0,Q0,Fs,actual_temp,kid_number,input_att,didf,dqdf,f0

    def get_params_from_header(self, path):
        hdul = fits.open(path)
        hdr = hdul[1].header

        f0 = hdr["F0FOUND"]
        actual_temp = hdr['SAMPLETE']
        kid_number = hdr['TONE']
        input_att = hdr['INPUTATT']

        return f0,actual_temp,kid_number,input_att

    def get_vna_sweep(self,path):
        data_fits = self.get_arrays_fits(path)

        freqs = data_fits.field(0)
        I = data_fits.field(1)
        Q = data_fits.field(2)
        return freqs,I,Q

    """
    def get_sweep_hr(self,path):
        data_fits = self.get_arrays_fits(path)

        freqs_hr = data_fits.field(0)
        I_hr = data_fits.field(1)
        Q_hr = data_fits.field(2)

        return freqs_hr,I_hr,Q_hr
    """

    def get_full_vna(self,path):
        data_fits = self.get_arrays_fits(path)

        freq = data_fits.field(0)
        I = data_fits.field(1)
        Q = data_fits.field(2)

        mag = np.sqrt(I**2 + Q**2)

        return freq, mag, I, Q

    def smooth_IQ(self,I,Q):
        sI = savgol_filter(I,51,10)
        sQ = savgol_filter(Q,51,10)
       # fs21 = np.sqrt((fI**2)+(fQ**2))
        return sI,sQ

    def get_vna_sweep_parameters(self,freqs,I,Q,f0_fits):

        # FITS frequency
        f0_ind = np.argmin(np.abs(freqs - (f0_fits)))

        f0 = freqs[f0_ind]
        I0 = I[f0_ind]
        Q0 = Q[f0_ind]

        df = freqs[1]-freqs[0]

        try:
            #np.diff::::didf = (I[f0_ind + 1]-I[f0_ind])/(freqs[f0_ind + 1]-freqs[f0_ind])
            #np.gradient:::: (In+1 - In-1)/2df
            #didf = (I[f0_ind + 1]-I[f0_ind])/(freqs[f0_ind + 1]-freqs[f0_ind])
            #dqdf = (Q[f0_ind + 1]-Q[f0_ind])/(freqs[f0_ind + 1]-freqs[f0_ind])

            # Primero un filtro a la señal
            I = savgol_filter(I, 31, 3)
            Q = savgol_filter(Q, 31, 3)

            didf = np.gradient(I,freqs)[f0_ind]
            dqdf = np.gradient(Q,freqs)[f0_ind]

            #didf = (I[f0_ind + 1]-I[f0_ind])/(freqs[f0_ind + 1]-freqs[f0_ind])
            #dqdf = (Q[f0_ind + 1]-Q[f0_ind])/(freqs[f0_ind + 1]-freqs[f0_ind])

            check = True
        except:
            didf = 0
            dqdf = 0
            check = False

        return I0,Q0,didf,dqdf,check

    def df(self, I0,Q0,didf,dqdf,I,Q):
        vel = (didf**2)+(dqdf**2)
        df = [  ((( I0-I[i] ) * didf) + ( ( Q0-Q[i]) * dqdf )) / vel for i in range(len(I))  ]
        return df, vel

    def get_IQ_data_homo(self, path):
        data_fits = self.get_arrays_fits(path)

        I = [data_fits.field(2*i) for i in range(len(data_fits[0])/2)]
        Q = [data_fits.field(2*i+1) for i in range(len(data_fits[0])/2)]

        return I,Q

    def psd(self, df, Fs,isMean):
        psd = [signal.periodogram(df[i], Fs)[1]  for i in range(len(df))]
        freqs = signal.periodogram(df[0],Fs)[0]

        if isMean == True:
            psd_mean = 10*np.log10(np.average(psd,axis=0))
        else:
            psd_mean = 10*np.log10(np.median(psd,axis=0))

        return freqs, psd, psd_mean

    def get_homodyne_psd(self, path, didf, dqdf, check, sigma, cosRayFlag):

        I0,Q0,Fs,actual_temp,kid_number,input_att,didf_p,dqdf_p,f0 = self.get_header_time_stream(path)

        if check == False:
            didf = didf_p
            dqdf = dqdf_p

        step = 1/Fs
        I_old,Q_old = self.get_IQ_data_homo(path)

        time = np.arange(0,step*len(I_old[0]),step)

        I = []
        Q = []

        if cosRayFlag == True:
            # Remove Cosmic Ray
            cos_ray = remCosRay()
            for i in range(len(I_old)):

                time,n_I,flagRm_I = cos_ray.findCosmicRay(time,I_old[i],sigma)

                time,n_Q,flagRm_Q = cos_ray.findCosmicRay(time,Q_old[i],sigma)

                if flagRm_I == False and flagRm_Q == False:
                    I.append(n_I)
                    Q.append(n_Q)

        else:
            I = I_old
            Q = Q_old

        df,vel = self.df(I0,Q0,didf,dqdf,I,Q)

        freqs, psd, psd_mean = self.psd(df,Fs,cosRayFlag)

        df_avg = np.average(df,axis=0)
        I_avg = np.average(I,axis=0)
        Q_avg = np.average(Q,axis=0)

        time = np.linspace(0,step*len(I_avg),len(I_avg))

        return freqs, psd, psd_mean, time, I_avg, Q_avg, df_avg, kid_number, actual_temp, input_att, I,Q

    def validate_folder(self,path):
        if len(os.listdir(path) ) == 0:
            return False
        else:
            return True

    def get_sweep_psd_data(self, path, cosRayFlag):

        sweep_path, _, ONTemp, OFFTemp = self.get_each_path(path)

        content_flags = [sweep_path is not "",[True]*len(ONTemp),[True]*len(OFFTemp)]

        freq, sweep_i,sweep_q = [],[],[]
        freq_hr, sweep_i_hr, sweep_q_hr = [],[],[]
        psd, psd_low = [],[]
        psd_OFF, psd_low_OFF = [],[]
        f0_fits = 0
        params = []

        if content_flags[0]:
            freq, sweep_i, sweep_q = self.get_vna_sweep(os.path.join(path, sweep_path))
            f0_fits,actual_temp,kid_number,input_att = self.get_params_from_header(os.path.join(path, sweep_path))
            I0,Q0,didf,dqdf,check = self.get_vna_sweep_parameters(freq,sweep_i,sweep_q,f0_fits)
            params = [actual_temp,kid_number,input_att]

        if len(content_flags[1]) > 0:
            if len(content_flags[1]) > 1:
                path_on_up, path_on_low = self.split_array(ONTemp)

                #print "PSD LOW ON"
                psd_low = self.get_homodyne_psd(os.path.join(path, path_on_low),didf,dqdf,check,5,cosRayFlag)
            elif len(content_flags[1]) == 1:
                path_on_up = ONTemp[0][0]

            #print "PSD HIGH ON"
            psd = self.get_homodyne_psd(os.path.join(path, path_on_up),didf,dqdf,check,5,cosRayFlag)

        if len(content_flags[2]) > 0:
            if len(content_flags[2]) > 1:
                path_off_up, path_off_low = self.split_array(OFFTemp)

                #print "PSD LOW OFF"
                psd_low_OFF = self.get_homodyne_psd(os.path.join(path, path_off_low),didf,dqdf,check,5,cosRayFlag)
            elif len(content_flags[2]) == 1:
                path_off_up = OFFTemp[0][0]

            #print "PSD HIGH OFF"
            psd_OFF = self.get_homodyne_psd(os.path.join(path, path_off_up),didf,dqdf,check,5,cosRayFlag)

        return freq, sweep_i, sweep_q, psd, psd_low, psd_OFF, psd_low_OFF, f0_fits,params

    def get_sweep_hr(self, path):
        _,sweep_hr_path,_,_ = self.get_each_path(path)

        assert sweep_hr_path != "", "File of sweep at high resolution not founded"
        freq_hr, sweep_i_hr, sweep_q_hr = self.get_vna_sweep(os.path.join(path, sweep_hr_path))

        return freq_hr, sweep_i_hr, sweep_q_hr

    # Choose the newest version of the fits files
    def split_array(self, array):
        low = []
        up = []
        a1 = []
        a2 = []

        ref = array[0][1]

        for m in array:
            if m[1] == ref:
                a1.append(m)
            else:
                a2.append(m)

        if a1[0][1] >= a2[0][1]:
            up = a1
            low = a2
        else:
            up = a2
            low = a1

        aux = 0
        for n in low:
            if n[2] >= aux:
                aux = n[2]
                low_path = n[0]

        aux = 0
        for m in up:
            if m[2] >= aux:
                aux = m[2]
                up_path = m[0]

        return up_path, low_path

    # Get the data of the directory
    def get_each_path(self, diry):

        files = os.listdir(diry)

        sweep_path = ""
        sweep_hr_path = ""
        ONTemp = []
        OFFTemp = []

        for i in files:
            k = i.lower()
            if k == "sweep.fits":
                sweep_path = i
            elif k == "sweep_hr.fits":
                sweep_hr_path = i
            else:
                freq = ''
                mode = ''
                n = ''
                cnt = 0
                for j in k:
                    if j == '_':
                        cnt += 1
                    elif j == '.':
                        cnt = 0
                    elif cnt == 1:
                        freq = freq + j
                    elif cnt == 3:
                        mode = mode + j
                    elif cnt == 6:
                        n = n + j
                if n == '':
                    n = 0
                if mode == "on":
                    ONTemp.append([i,int(freq),int(n)])
                elif mode == "off":
                    OFFTemp.append([i,int(freq),int(n)])

        return sweep_path, sweep_hr_path, ONTemp, OFFTemp


# -*- encoding: utf-8 -*-
import timeit

import runez

from . import TestSettings

class BenchmarkedFunction(object):
    def __init__(self, name, function, iterations):
        self.name = name
        self.function = function
        self.iterations = iterations
        self.error = None
        self.seconds = None

    def __repr__(self):
        return self.report()

    def resolved_call(self):
        result = self.function()
        if isinstance(result, Exception):
            raise result

    def run(self):
        t = timeit.Timer(stmt=self.resolved_call)
        if TestSettings.stacktrace:
            self.seconds = t.timeit(self.iterations)
            return

        try:
            self.seconds = t.timeit(self.iterations)

        except Exception as e:
            self.error = e

    def report(self, fastest=None, indent=""):
        message = "%s%s: " % (indent, self.name)
        if self.error:
            return "%s%s" % (message, TestSettings.represented(self.error, size=-len(message)))

        if self.seconds is None:
            return "%s%s" % (message, runez.red("no result"))

        info = ""
        if fastest and self.seconds and fastest.seconds and self.seconds != fastest.seconds:
            info = runez.dim(" [x %.1f]" % (self.seconds / fastest.seconds))

        unit = u"μ"
        x = self.seconds / self.iterations * 1000000
        if x >= 999:
            x = x / 1000
            unit = "m"

        if x >= 999:
            x = x / 1000
            unit = "s"

        return "%s%s: %.3f %ss/i%s" % (indent, self.name, x, unit, info)

class BenchmarkRunner(object):
    def __init__(self, functions, target_name=None, iterations=100):
        self.benchmarks = []
        for name, func in functions.items():
            self.benchmarks.append(BenchmarkedFunction(name, func, iterations))

        self.target_name = target_name
        self.fastest = None

    def run(self, ):
        for bench in self.benchmarks:
            bench.run()
            if bench.seconds is not None:
                if self.fastest is None or self.fastest.seconds > bench.seconds:
                    self.fastest = bench

    def report(self):
        result = []
        indent = ""
        if self.target_name:
            indent = "  "
            result.append("%s:" % self.target_name)

        for bench in self.benchmarks:
            result.append(bench.report(fastest=self.fastest, indent=indent))

        return "\n".join(result)


import unittest
from typing import List, Type

import casadi as cs
import numpy as np
from parameterized import parameterized, parameterized_class
from scipy import io

from csnlp import Nlp, Solution, scaling, wrappers
from csnlp.multistart import ParallelMultistartNlp, StackedMultistartNlp
from csnlp.multistart.multistart_nlp import MultistartNlp

OPTS = {
    "expand": True,
    "print_time": False,
    "ipopt": {
        "max_iter": 500,
        "sb": "yes",
        # for debugging
        "print_level": 0,
        "print_user_options": "no",
        "print_options_documentation": "no",
    },
}
EXAMPLES_DATA_FILENAME = r"tests/examples_data.mat"
RESULTS = io.loadmat(EXAMPLES_DATA_FILENAME, simplify_cells=True)
# io.savemat(EXAMPLES_DATA_FILENAME, {**RESULTS, "multistart_nlp_fs": fs})

@parameterized_class("sym_type", [("SX",), ("MX",)])
class TestExamples(unittest.TestCase):
    def test__chain(self):
        N = 40
        m = 40 / N
        D = 70 * N / 2
        g = 9.81
        L = 1
        nlp = Nlp(sym_type=self.sym_type)
        p = nlp.variable("p", (2, N))[0]
        x, y = p[0, :], p[1, :]
        V = D * cs.sum2(
            (cs.sqrt(cs.diff(x) ** 2 + cs.diff(y) ** 2) - L / N) ** 2
        ) + g * m * cs.sum2(y)
        nlp.minimize(V)
        nlp.init_solver(OPTS)
        nlp.constraint("c1", p[:, 0], "==", [-2, 1])
        nlp.constraint("c2", p[:, -1], "==", [2, 1])
        nlp.constraint("c3", y, ">=", cs.cos(0.1 * x) - 0.5)
        nlp = nlp.copy()
        sol = nlp(vals0={"p": np.row_stack((np.linspace(-2, 2, N), np.ones(y.shape)))})
        np.testing.assert_allclose(sol.vals["p"], RESULTS["chain_p"])

    def test__multistart_nlp(self):
        def func(x):
            return (
                -0.3 * x**2
                - np.exp(-10 * x**2)
                + np.exp(-100 * (x - 1) ** 2)
                + np.exp(-100 * (x - 1.5) ** 2)
            )

        N = 3
        LB, UB = -0.5, 1.4
        x0s = [0.9, 0.5, 1.1]
        args = ([{"p0": 0, "p1": 1} for _ in x0s], [{"x": x0} for x0 in x0s])

        nlps: List[MultistartNlp] = [
            StackedMultistartNlp(starts=N, sym_type=self.sym_type),
            ParallelMultistartNlp(starts=N, n_jobs=N, sym_type=self.sym_type),
        ]
        sols = []
        for nlp in nlps:
            x = nlp.variable("x", lb=LB, ub=UB)[0]
            nlp.parameter("p0")
            nlp.parameter("p1")
            nlp.minimize(func(x))
            nlp.init_solver(OPTS)
            nlp = nlp.copy()

            best_sol: Solution = nlp.solve_multi(*args)
            all_sols: List[Solution] = nlp.solve_multi(*args, return_all_sols=True)
            fs = [all_sol.f for all_sol in all_sols]
            self.assertEqual(best_sol.f, min(fs))
            np.testing.assert_allclose(fs, RESULTS["multistart_nlp_fs"])

            all_sols.sort()
            sols.append(all_sols)

        for sol1, sol2 in zip(*sols):
            self.assertEqual(sol1.success, sol2.success)
            np.testing.assert_allclose(sol1.f, sol2.f)
            np.testing.assert_allclose(sol1.vals["x"], sol2.vals["x"])
            np.testing.assert_allclose(
                sol1.value(nlps[0].lam_lbx), sol2.value(nlps[1].lam_lbx), atol=1e-6
            )
            np.testing.assert_allclose(
                sol1.value(nlps[0].lam_ubx), sol2.value(nlps[1].lam_ubx), atol=1e-6
            )

    @parameterized.expand([("single",), ("multi",)])
    def test__optimal_ctrl(self, shooting: str):
        x = cs.MX.sym("x", 2)
        u = cs.MX.sym("u")
        ode = cs.vertcat((1 - x[1] ** 2) * x[0] - x[1] + u, x[0])
        f = cs.Function("f", [x, u], [ode], ["x", "u"], ["ode"])
        T = 10
        N = 20
        intg_options = {"simplify": True, "number_of_finite_elements": 4}
        dae = {"x": x, "p": u, "ode": f(x, u)}
        intg = cs.integrator("intg", "rk", dae, 0.0, T / N, intg_options)
        res = intg(x0=x, p=u)
        x_next = res["xf"]
        F = cs.Function("F", [x, u], [x_next], ["x", "u"], ["x_next"])
        mpc = wrappers.Mpc(
            nlp=Nlp(sym_type=self.sym_type),
            prediction_horizon=N,
            shooting=shooting,
        )
        u, _ = mpc.action("u", lb=-1, ub=+1)
        if shooting == "single":
            mpc.state("x", 2)
            mpc.set_dynamics(F)
            x = mpc.states["x"]  # only accessible after dynamics have been set
            mpc.constraint("c0", x, ">=", -0.2)
        else:
            x, _ = mpc.state("x", 2, lb=-0.2)  # must be created before dynamics
            mpc.set_dynamics(F)
        mpc.minimize(cs.sumsqr(x) + cs.sumsqr(u))
        mpc.init_solver(OPTS)
        mpc = mpc.copy()
        sol = mpc.solve(pars={"x_0": [0, 1]})
        u_opt = sol.vals["u"].full().flat
        np.testing.assert_allclose(
            u_opt, RESULTS["optimal_ctrl_u"], rtol=1e-6, atol=1e-6
        )

    def test__rosenbrock(self):
        nlp = Nlp(sym_type=self.sym_type)
        x = nlp.variable("x", (2, 1))[0]
        r = nlp.parameter("r")
        f = (1 - x[0]) ** 2 + (x[1] - x[0] ** 2) ** 2
        nlp.minimize(f)
        nlp.constraint("con1", cs.sumsqr(x), "<=", r)
        nlp.init_solver(OPTS)
        nlp = nlp.copy()
        r_values = np.linspace(1, 3, 25)
        f_values = []
        lam_values = []
        for r_value in r_values:
            sol = nlp.solve(pars={"r": r_value})
            f_values.append(sol.f)
            lam_values.append(sol.dual_vals["lam_h_con1"])
        f_values = np.asarray(f_values).squeeze()
        lam_values = np.asarray(lam_values).squeeze()
        np.testing.assert_allclose(f_values, RESULTS["rosenbrock_f"])
        np.testing.assert_allclose(lam_values, RESULTS["rosenbrock_lam"])

    def test__sensitivity(self):
        def z1(x, lam, p):
            return (x[1, :] ** p[1] - x[0, :]) * cs.exp(-10 * lam + p[0]) / p[1]

        def z2(x):
            return x[1, :] - x[0, :]

        def z3(x, p):
            return x[1, :] ** (1 / p[1]) - x[0, :]

        def z4(lam, p):
            return cs.exp(-10 * lam + p[0]) / p[1]

        nlp = wrappers.NlpSensitivity(Nlp(sym_type=self.sym_type))
        x = nlp.variable("x", (2, 1), lb=[[0], [-np.inf]])[0]
        p = nlp.parameter("p", (2, 1))
        nlp.minimize((1 - x[0]) ** 2 + p[0] * (x[1] - x[0] ** 2) ** 2)
        g = (x[0] + 0.5) ** 2 + x[1] ** 2
        nlp.constraint("c1", (p[1] / 2) ** 2, "<=", g)
        _, lam = nlp.constraint("c2", g, "<=", p[1] ** 2)
        opts = {"print_time": False, "ipopt": {"sb": "yes", "print_level": 0}}
        nlp.init_solver(opts)
        nlp = nlp.copy()
        Z = cs.blockcat(
            [
                [z1(x, lam, p) ** 2, z2(x)],
                [1 / (1 + z3(x, p)), z4(lam, p)],
                [z3(x, p) * (-1 - 10 * z1(x, lam, p)), z4(lam, p) / (1 + z2(x))],
            ]
        )
        z0, j0, h0 = [], [], []
        J, H = nlp.parametric_sensitivity(expr=Z, second_order=True)
        for p0 in (1.2, 1.45, 1.9):
            sol = nlp.solve(pars={"p": [0.2, p0]})
            z0.append(sol.value(Z))
            j0.append(sol.value(J))
            h0.append(sol.value(H))
        z0 = np.asarray(z0).squeeze()
        j0 = np.asarray(j0).squeeze()
        h0 = np.asarray(h0).squeeze()
        np.testing.assert_allclose(RESULTS["sensitivity_z"], z0, rtol=1e-6, atol=1e-7)
        np.testing.assert_allclose(RESULTS["sensitivity_j"], j0, rtol=1e-6, atol=1e-7)
        np.testing.assert_allclose(RESULTS["sensitivity_h"], h0, rtol=1e-6, atol=1e-7)

    @parameterized.expand([(StackedMultistartNlp,), (ParallelMultistartNlp,)])
    def test__scaling(self, multinlp_cls: Type):
        def get_dynamics(g: float, alpha: float, dt: float) -> cs.Function:
            x, u = cs.SX.sym("x", 3), cs.SX.sym("u")
            x_next = x + cs.vertcat(x[1], u / x[2] - g, -alpha * u) * dt
            return cs.Function("F", [x, u], [x_next], ["x", "u"], ["x+"])

        N = 100
        T = 100
        K = 3
        dt = T / N
        m0 = 500000
        yT = 100000
        g = 9.81
        alpha = 1 / (300 * g)
        seed = 69
        rng = np.random.default_rng(seed)
        kwargs = {"n_jobs": -1} if multinlp_cls is ParallelMultistartNlp else {}
        nlp = multinlp_cls(sym_type="SX", starts=K, **kwargs)

        y_nom = 1e5
        v_nom = 2e3
        m_nom = 3e5
        x_nom = cs.vertcat(y_nom, v_nom, m_nom)
        u_nom = 1e8
        scaler = scaling.Scaler()
        scaler.register("x", scale=x_nom)
        scaler.register("x_0", scale=x_nom)
        scaler.register("u", scale=u_nom)
        nlp = wrappers.NlpScaling(nlp, scaler=scaler)

        mpc = wrappers.Mpc(nlp, prediction_horizon=N)
        x, _ = mpc.state("x", 3, lb=cs.DM([-cs.inf, -cs.inf, 0]))
        y = x[0, :]
        m = x[2, :]
        u, _ = mpc.action("u", lb=0, ub=5e7)
        mpc.set_dynamics(get_dynamics(g, alpha, dt))
        x0 = cs.vertcat(0, 0, m0)
        mpc.constraint("yT", y[-1], "==", yT)
        mpc.minimize(m[0] - m[-1])
        mpc.init_solver(OPTS)
        mpc = mpc.copy()

        x_init = cs.repmat([0, 0, 1e5], 1, N + 1)

        pars = [{"x_0": x0}] * K
        vals0 = [
            {
                "x": x_init + rng.random(x_init.shape) * 1e4,
                "u": rng.random() * 1e8,
            }
            for _ in range(K)
        ]
        us, fs = [], []
        for i in range(K + 1):
            sol = mpc.solve(pars[i], vals0[i]) if i != K else mpc(pars, vals0)
            fs.append(sol.f)
            us.append(sol.value(u))
        us, fs = np.asarray(us).squeeze(), np.asarray(fs).squeeze()

        np.testing.assert_almost_equal(fs[-1], fs[:-1].min(), decimal=2)
        np.testing.assert_allclose(RESULTS["scaling_fs"], fs, rtol=1e-6, atol=1e-7)
        np.testing.assert_allclose(RESULTS["scaling_us"], us, rtol=1e-6, atol=1e-7)

if __name__ == "__main__":
    unittest.main()


"importe le module ArgumentParser"
from argparse import ArgumentParser

# Voici la représentation des Gobblets, n'hésitez pas à l'utiliser.
# 1 pour le joueur 1, 2 pour le joueur 2.
GOBBLET_REPRÉSENTATION = {
    1: ["▫", "◇", "◯", "□"],
    2: ["▪", "◆", "●", "■"],
}

def interpréteur_de_commande():
    "interprète la commande "
    parser = ArgumentParser()
    parser.add_argument('IDUL', help ='Idul du joueur')
    parser.add_argument('-l',dest = 'lister', help = 'lister les parties existantes')
    return parser.parse_args()

def formater_un_gobblet(gobblet):
    "formate un gobblet"
    if gobblet == []:
        return "   "

    return f" {((GOBBLET_REPRÉSENTATION[gobblet[0]])[gobblet[1]])} "

def formater_un_joueur(joueur):
    "formate un joeur"
    jo = joueur['nom']
    j = joueur['piles']
    return f"{jo}: {formater_un_gobblet(j[0])} {formater_un_gobblet(j[1])} {formater_un_gobblet(j[2])}"

def formater_plateau(plateau):
    "formate le plateau"
    lig = 4
    rep = ''
    for i in plateau[:-1] :
        lig -= 1
        listeligne = []
        for u in i:
            listeligne.append(formater_un_gobblet(u))
        rep += (f"{lig}{'|'.join(listeligne)}"+'\n'+' ───┼───┼───┼───'+'\n')

    if plateau[-1]:
        lig -= 1
        listeligne = []
        for u in plateau[-1]:
            listeligne.append(formater_un_gobblet(u))
        rep += (f"{lig}{'|'.join(listeligne)}"+'\n'+f"  {0}   {1}   {2}   {3} ")
    return rep

def formater_jeu(plateau, joueur):
    "formate le jeu"
    longueur = []
    for j in joueur:
        lm = len(j['nom'])
        longueur.append(lm)
    lmax = max(longueur)+3
    esp = max(longueur)

    nbr = ' '*(lmax)+"0   1   2 "+'\n'
    j0 = ' '*(esp-longueur[0])+f"{formater_un_joueur(joueur[0])}"+'\n'
    j1 = ' '*(esp-longueur[1])+f"{formater_un_joueur(joueur[1])}"+'\n'+'\n'
    grille = f"{formater_plateau(plateau)}"
    return nbr+j0+j1+grille

def formater_les_parties(parties):
    "formate les parties"
    rep = ''
    num = 0
    party = parties['parties']
    for dic in party:
        num += 1
        rep += f"{num} : {dic['date']}, {(dic['joueurs'])[0]} vs {(dic['joueurs'])[1]}"
        if dic['gagnant'] is not None:
            rep += f", gagnant:{dic['gagnant']}"
        rep += '\n'
    return rep

def récupérer_le_coup():
    "récupère le coup"
    orig =input('Donnez le numéro de la pile (p) ou la position sur le plateau (x,y):')
    if len(orig) <= 2 :
        origine = int(orig)
    else:
        origine = [int(orig[0]),int(orig[-1])]
    dest = input ('Où voulez-vous placer votre gobelet (x,y):')
    destination = [int(dest[0]),int(dest[-1])]
    return origine, destination


import os

from flask import Blueprint, Flask, render_template
from .sitemap import sitemap_blueprint
from flask_webpack import Webpack
from filters import filters

brigade = Blueprint('brigade', __name__)

def detect_webpack_manifest_path(expected_path):
    path = os.path.abspath(expected_path)
    if os.path.exists(path):
        return path
    else:
        raise Exception("Webpack Build Missing -- Make sure webpack is running. " \
                "Start it with `webpack --watch`")

def create_app():
    app = Flask(__name__, static_folder='build/public/', static_url_path='/assets')
    app.config['SECRET_KEY'] = 'sekrit!'
    app.config['WEBPACK_MANIFEST_PATH'] = detect_webpack_manifest_path('./brigade/build/manifest.json')

    webpack = Webpack()
    webpack.init_app(app)

    if 'SERVER_NAME' in os.environ:
        app.config['SERVER_NAME'] = os.environ['SERVER_NAME']
    if 'SITEMAP_URL_SCHEME' in os.environ:
        app.config['SITEMAP_URL_SCHEME'] = os.environ['SITEMAP_URL_SCHEME']
    app.config['SITEMAP_INCLUDE_RULES_WITHOUT_PARAMS'] = True

    app.register_blueprint(brigade)
    app.register_blueprint(filters)
    app.register_blueprint(sitemap_blueprint)

    @app.errorhandler(404)
    def page_not_found(e):
        return render_template('404.html'), 404

    return app

from . import views # noqa:E402


import parse_cards
import numpy as np
import wscreenshot
import time
import cv2
import os

INIT = 0
WAIT = 1
RUN = 2
END = 3
DEBUG = False
WINTEXT = '天天爱掼蛋'
CARDS = ['Joker', 'A', 'K', 'Q', 'J', '10', '9', '8', '7', '6', '5', '4', '3', '2']
CARD_NUMS = [8] * (len(CARDS))
CARD_NUMS[CARDS.index('Joker')] = 4

class DEBUGWS:
    def __init__(self):
        self.d = 'images5'
        img_files = os.listdir(self.d)
        self.img_files = sorted(img_files)
        # self.images = [cv2.imread(os.path.join(d, f)) for f in img_files]
        self.index = 0

    def screenshot(self):
        fname = os.path.join(self.d, self.img_files[self.index])
        img = cv2.imread(fname)
        self.index += 5
        self.index %= len(self.img_files)
        return fname.split('.')[0], img

class JiPaiQi:
    def __init__(self, is_debug=False, do_record=False):
        self.is_debug = is_debug
        self.do_record = do_record
        self.status = WAIT
        self.prev_who = None
        self.who = None
        self.ws = None
        self.my_cards = None
        self.remain_cards = None
        self.out_cards = [[0] * len(CARDS), [0] * len(CARDS), [0] * len(CARDS), [0] * len(CARDS)]
        self.start_timestamp = 'temp'

        self.init()

    def init(self):
        self.prev_who = None
        self.who = None
        self.ws = None
        self.my_cards = None
        self.remain_cards = CARD_NUMS.copy()

        if self.is_debug:
            self.ws = DEBUGWS()
            self.start_timestamp = self.ws.img_files[0].split('.')[0]
        else:
            while True:
                try:
                    self.ws = wscreenshot.Screenshot(WINTEXT)
                except Exception:
                    time.sleep(1)
                    continue
                print('ws created.')
                break
            self.start_timestamp = str(int(time.time() * 10))
        if self.do_record and not os.path.exists(self.start_timestamp):
            os.mkdir(self.start_timestamp)
        self.status = INIT
        print('-----------------init---------------')

    def run(self):
        if not DEBUG:
            timestamp = str(int(time.time()))
            img = self.ws.screenshot()
            if self.do_record:
                cv2.imwrite(os.path.join(self.start_timestamp, timestamp + '.png'), img)
            img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        else:
            timestamp, img = self.ws.screenshot()
            img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

        if self.status == INIT:
            is_game_start = parse_cards.parse_game_start(img_gray)
            if is_game_start:
                self.status = WAIT
                print(timestamp, 'game_start')
                return True
            else:
                time.sleep(0.01)
                return False
        elif self.status == WAIT:
            res = parse_cards.parse_clock(img_gray)
            if not res:
                time.sleep(0.01)
                return False
            else:
                direct_num, is_start_clock = res
                if not is_start_clock:
                    print(timestamp, 'error: is_start_clock False', timestamp)
                self.who = direct_num
                self.status = RUN
                self.my_cards = parse_cards.parse_big_cards(img_gray)
                self.my_cards = [x[2] for x in self.my_cards]
                self.my_cards = sorted(self.my_cards)
                for card in self.my_cards:
                    self.remain_cards[CARDS.index(card[1:])] -= 1
                print(timestamp, 'start_clock', self.my_cards, self.remain_cards)
                return True
        elif self.status == RUN:
            if parse_cards.parse_game_start(img_gray):
                self.init()
                return True
            res = parse_cards.parse_clock(img_gray)
            if not res:
                time.sleep(0.01)
                return False
            else:
                direct_num, is_start_clock = res
                self.prev_who, self.who = self.who, direct_num
                if self.prev_who != self.who:
                    # todo: "不出" 与解析失败的区别
                    cards = parse_cards.parse_small_cards(img_gray, self.prev_who)
                    cards = [x[2] for x in cards]
                    cards = sorted(cards)
                    for card in cards:
                        self.remain_cards[CARDS.index(card[1:])] -= 1
                        self.out_cards[self.prev_who][CARDS.index(card[1:])] += 1
                    print(timestamp, self.prev_who, cards, self.remain_cards)
                    return True
                else:
                    time.sleep(0.01)
                    return False
        else:
            return False

if __name__ == '__main__':
    jipaiqi = JiPaiQi()
    while True:
        jipaiqi.run()


import pandas as pd
from Bio import SearchIO
import os
import re
import sqlite3

conn = sqlite3.connect('NFixDB')
c = conn.cursor()

c.execute('CREATE TABLE IF NOT EXISTS nitrogenase_i3 (GenomeID varchar, SeqID varchar, EValue float, BitScore float, GeneName varchar, GTDB_Tax varchar, NCBI_TaxID number, NCBI_Tax varchar)')
conn.commit()

c.execute('CREATE TABLE IF NOT EXISTS nonNitrogenase_i3 (GenomeID varchar, SeqID varchar, EValue float, BitScore float, GeneName varchar, GTDB_Tax varchar, NCBI_TaxID number, NCBI_Tax varchar)')
conn.commit()
'''
df = pd.DataFrame(pd.read_table('/projects/raw_lab/databases/GTDB/ar53_metadata_r207.tsv'))
df2 = pd.DataFrame(pd.read_table('/projects/raw_lab/databases/GTDB/bac120_metadata_r207.tsv'))

frame = [df, df2]
complete_df = pd.concat(frame)

complete_df = complete_df[['gtdb_genome_representative', 'gtdb_taxonomy', 'ncbi_taxid', 'ncbi_taxonomy_unfiltered']].copy()
complete_df.columns = ['GenomeID', 'GTDB_Tax', 'NCBI_TaxID', 'NCBI_Tax']
complete_df.to_csv("complete_taxonomy.tsv", sep = "\t")
'''
#---------------------------------------------------------------------------------------------------------------------------------------------------------------------

complete_df = pd.DataFrame(pd.read_table('complete_taxonomy.tsv'))

result_target = []
query_id = []
hit_id = []
evalue = []
bitscore = []

#OOR stands for "Out Of Range", AKA the values that do not meet our E-value threshold
oor_target = []
oor_queryid = []
oor_hitid = []
oor_evalue = []
oor_bitscore = []

#parse through files in output directory
directory = 'bac120_ar53_results_i3'
for filename in os.listdir(directory):
    f = os.path.join(directory, filename)
    reg = r'^([\w]+_[\w]+.[\w])'
    regex = re.match(reg, filename).group()
    if os.path.isfile(f):
        #parse file using SearchIO/HmmerIO
        for result in SearchIO.parse(f, 'hmmer3-text'):
            for item in result.hits:
                reg2 = r'([a-zA-Z]+)_([a-zA-Z]+)-([a-zA-Z]+)_([a-zA-Z]+)'
                regex2 = re.match(reg2, result.id).group(2)
                #check the evalue cutoff and append the data to the corresponding lists
                if item.evalue < 9.9e-10:
                    result_target.append(regex)
                    query_id.append(regex2)
                    hit_id.append(item.id)
                    evalue.append(item.evalue)
                    bitscore.append(item.bitscore)
                #if it does not meet the evalue cutoff, append it to the OOR lists
                else:
                    oor_target.append(regex)
                    oor_queryid.append(regex2)
                    oor_hitid.append(item.id)
                    oor_evalue.append(item.evalue)
                    oor_bitscore.append(item.bitscore)

evalue_dict = {'GenomeID' : result_target, 'GeneName' : query_id, 'SeqID' : hit_id, 'EValue' : evalue, 'Bitscore' : bitscore}
evalue_df = pd.DataFrame(evalue_dict).sort_values('EValue')
evalue_df = pd.merge(evalue_df, complete_df, on = "GenomeID", how = "left")

oor_dict = {'GenomeID' : oor_target, 'GeneName' : oor_queryid, 'SeqID' : oor_hitid, 'EValue' : oor_evalue, 'Bitscore' : oor_bitscore}
oor_df = pd.DataFrame(oor_dict).sort_values('EValue')
oor_df = pd.merge(oor_df, complete_df, on = "GenomeID", how = "left")

evalue_df.to_csv("evalue_taxonomy_i3.tsv", sep = "\t")
evalue_df.to_sql('nitrogenase_i3', conn, if_exists = 'replace')

oor_df.to_csv("oor_taxonomy_i3.tsv", sep = "\t")
oor_df.to_sql('nonNitrogenase_i3', conn, if_exists = 'replace', index = False)

'''
c.execute("SELECT * FROM nitrogenase")
for row in c.fetchall():
    print(row)

c.execute("SELECT * FROM nonNitrogenase")
for row in c.fetchall():
    print(row)

print(evalue_df)
print()
print(oor_df)'''


from ctypes import c_ssize_t
import nltk
nltk.download('popular')
from nltk.stem import WordNetLemmatizer
lemmatizer = WordNetLemmatizer()
import pickle
import numpy as np
from autocorrect import Speller
spell = Speller(lang='en')
from keras.models import load_model
model = load_model('model.h5')
import json
import random
import itertools
from flask import Flask, render_template, request
intents = json.loads(open('data.json',encoding="utf8").read())
words = pickle.load(open('texts.pkl','rb'))
classes = pickle.load(open('labels.pkl','rb'))

def clean_up_sentence(sentence):
    # tokenize the pattern - split words into array
    sentence_words = nltk.word_tokenize(sentence)
    # stem each word - create short form for word
    sentence_wordsL = [lemmatizer.lemmatize(word.lower()) for word in sentence_words]
    if "and" in sentence_words:
        sentence_wordsL = [lemmatizer.lemmatize(spell(word.lower())) for word in sentence_words]
        i=sentence_words.index("and")
        sentence_words1=sentence_wordsL[:i]
        sentence_words2=sentence_wordsL[i+1:]
        return (sentence_words1,sentence_words2)
    else :
        return sentence_wordsL

# return bag of words array: 0 or 1 for each word in the bag that exists in the sentence
def bow(sentence, words, show_details=True):
    # tokenize the pattern
    sentence_words = clean_up_sentence(sentence)
    if str(type(sentence_words))=='<class \'list\'>':
    # bag of words - matrix of N words, vocabulary matrix
        bag = [0]*len(words)
        for s in sentence_words:
            for i,w in enumerate(words):
                if w == s:
                    # assign 1 if current word is in the vocabulary position
                    bag[i] = 1
                    if show_details:
                        print ("found in bag: %s" % w)
        return np.array(bag)
    else :
        bag1 = [0]*len(words)
        bag2 = [0]*len(words)
        for (s,p) in zip(sentence_words[0],sentence_words[1]):
            for i,w in enumerate(words):
                if w == s:
                    # assign 1 if current word is in the vocabulary position
                    bag1[i] = 1
                    if show_details:
                        print ("found in bag: %s" % w)
                if w == p :
                     bag2[i] = 1
        return (np.array(bag1) , np.array(bag2))

def predict_class(sentence, model):
    # filter out predictions below a threshold
    p = bow(sentence, words,show_details=False)
    if str(type(p)) == '<class \'numpy.ndarray\'>':
        res = model.predict(np.array([p]))[0]
        ERROR_THRESHOLD = 0.25
        results = [[i,r] for i,r in enumerate(res) if r>ERROR_THRESHOLD]
        # sort by strength of probability
        results.sort(key=lambda x: x[1], reverse=True)
        return_list = []
        for r in results:
            return_list.append({"intent": classes[r[0]], "probability": str(r[1])})
        return return_list
    elif str(type(p)) == '<class \'tuple\'>' :
        res1 = model.predict(np.array([p[0]]))[0]
        ERROR_THRESHOLD = 0.25
        results1 = [[i1,r1] for i1,r1 in enumerate(res1) if r1>ERROR_THRESHOLD]
        # sort by strength of probability
        results1.sort(key=lambda x: x[1], reverse=True)
        return_list1 = []
        for r1 in results1:
            return_list1.append({"intent": classes[r1[0]], "probability": str(r1[1])})
        res2 = model.predict(np.array([p[1]]))[0]
        ERROR_THRESHOLD = 0.25
        results2 = [[i2,r2] for i2,r2 in enumerate(res2) if r2>ERROR_THRESHOLD]
        # sort by strength of probability
        results2.sort(key=lambda x: x[1], reverse=True)
        return_list2 = []
        for r2 in results2:
            return_list2.append({"intent": classes[r2[0]], "probability": str(r2[1])})
        return (return_list1 , return_list2)

def getResponse(ints, intents_json):
 if str(type(ints))=='<class \'list\'>':
  try:
    tag = ints[0]['intent']
    list_of_intents = intents_json['intents']
    for i in list_of_intents:
        if(tag == i['tag']):
            result = random.choice(i['responses'])
  except IndexError:
    result ='Sorry i can\'t understand you '
 elif str(type(ints))=='<class \'tuple\'>':
      try :
        tag1 = ints[0][0]['intent']
        tag2 = ints[1][0]['intent']
        list_of_intents = intents_json['intents']
    #result=str(ints)
    #return result

        for i in list_of_intents:
            if(tag1==i['tag']):
                result1 = random.choice(i['responses'])

        for i in list_of_intents:
            if(tag2==i['tag']):
                result2 = random.choice(i['responses'])
        result= result1 + " and " + result2
      except IndexError:
        result ='Sorry i can\'t understand your question '
 return result

def chatbot_response(msg):
    ints = predict_class(msg, model)
    res = getResponse(ints, intents)
    return res

app = Flask(__name__)
app.static_folder = 'static'

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

@app.route("/get")
def get_bot_response():
    userText = request.args.get('msg')
    return chatbot_response(userText)

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


# from periods.period import TimeInterval as Period
from django.urls import path
from django.shortcuts import redirect

from directory.views import forms, list, remote_search, working_calendar

urlpatterns = [
    path('remote_search/<str:model_name>/', remote_search.RemoteSearch.as_view(), name='remote_search'),

    path('mlm_agent/', list.ModelList.as_view(), name='mlm_agent_list', kwargs=dict(model_name='agent')),
    path('working_calendar/', working_calendar.WorkingCalendarView.as_view(), name='working_calendar'),

    path('<str:model_name>/', list.ModelList.as_view(), name='model_list'),
    path('<str:model_name>/<int:pk>/', list.ModelDetail.as_view(), name='model_detail'),
    path('<str:parent_model_name>/<int:parent_pk>/relation/<str:related_name>/',
         list.ModelList.as_view(), name='model_relation_list'),

    # path('<str:parent_name>/<int:parent_id>/<str:model_name>/list', views.ListTemplate.as_view(),
    #      name='child_model_list'),

    # path('<str:parent_name>/<str:parent_id>/<str:model_name>/action/<str:action>',
    #      views_forms.ModelActions.as_view(), name='model_action'),

    path('<str:model_name>/<str:action>/', forms.ModelActions.as_view(), name='model_action'),
    path('<str:model_name>/<str:action>/<int:pk>/', forms.ModelActions.as_view(), name='model_instance_action'),

    path('', lambda request: redirect('directory:model_list', model_name='person'), name='directory_index'),
]


#!/usr/bin/env python
import numpy as np
import matplotlib.pyplot as plt

def GetMuTilde(buf, buf_idx, a, sigma):
    result = sum([a[ii]*buf[(buf_idx+len(buf)-ii-1)%len(buf)] for ii in range(len(a))]) \
            + sigma*np.random.normal()
    return result
mu = 0.142
a = [0.783, 0.116]
sigma = 0.0148
# sigma = 0.
buf = [0]*3
buf_idx = 0

data = []
for ii in range(200):
    mu_tilde = GetMuTilde(buf, buf_idx, a, sigma)
    # data.append(mu + mu_tilde)
    # buf[buf_idx] = mu_tilde
    data.append(mu_tilde)
    buf_idx = (buf_idx+1) % (len(a)+1)
data = np.array(data)
plt.figure()
plt.plot(data, '-x')
plt.figure()
plt.specgram(data, Fs=44100.)
plt.show()


#Immediate type casting
""" here we are coverting the data at the run time"""
import os
import datetime

os.system("cls")

today = datetime.date.today()
year = today.year
age = int(input("Please enter your age, we will show the year you are born :"))
BirthYear = year-age
print(BirthYear)


"""Demonstrates peculiarities of if, for, while and other statements.
"""

#%%
def demonstrate_branching():
    """Details and peculiarities of if statements.
    - is compares id()'s, == compares contents
    - id()'s are the same for equal strings and numbers, but not for lists, user class instances,...
    - the condition of an if-statement need not necessarily be a boolean
    - there can be more than one elif after if (no switch statement, use multiple elif instead)
    """

    from datetime import date
    d1 = date(1942, 6, 18)
    d2 = date.today()
    d3 = date(1942, 6, 18)

    if d1 == d3:
        print(True)
    else:
        print(False)

    if id(d1) == id(d3):
        print(True)
    else:
        print(False)

    print()

    a = 1
    b = 1
    if id(a) == id(b):
        print(True)
    else:
        print(False)

    print()

    if 'Paul':
        print(True)
    else:
        print(False)
    print()

    i = int(input('Enter an int: '))
    if i > 5:
        print('\ni > 5')
    elif i > 7:
        print('\ni > 7')
    elif i > 8:
        print('\ni > 8')
    else:
        print('\ni < 5')
    print()

    return

#%%

# Test demonstrate_branching()
demonstrate_branching()

#%%

def demonstrate_loops():
    """Different kinds of loops. Also break and continue.
    - it is not necessary to iterate through all elements of an iterable
    - step in range()
    - unimportant counter (_)
    - break and continue
    - while loop
    """

    from random import seed, randint
    seed(12)
    l = []
    for i in range(100):
        l.append(randint(10, 20))
    for i in range(10, 20, 2):
        print(i, l[i])
    print()

    for _ in range(5):
        print('Paul McCartney')
    print()

    return

#%%
# Test demonstrate_loops()
demonstrate_loops()


from django.contrib.auth import get_user_model

from rest_framework import serializers

from apps.chat.models import Message, Room

User = get_user_model()

class UserSerializer(serializers.ModelSerializer):
    """Сериализатор пользователя"""
    class Meta:
        model = User
        fields = ["id", "username"]

class MessageSerializer(serializers.ModelSerializer):
    """Сериализатор сообщения"""
    user = UserSerializer()
    read_count = serializers.SerializerMethodField()
    members_count = serializers.SerializerMethodField()

    class Meta:
        model = Message
        fields = [
            "id", "text", "user", "created_at", "read_count", "members_count"
        ]

    def get_read_count(self, obj: Message):
        return obj.read_users.count()

    def get_members_count(self, obj: Message):
        return obj.room.current_users.count()

class RoomDetailSerializer(serializers.ModelSerializer):
    """Сериализатор комнаты"""
    room_messages = MessageSerializer(many=True)

    class Meta:
        model = Room
        fields = ["id", "name", "room_messages", "current_users"]

    def to_representation(self, instance):
        data = super().to_representation(instance)
        data['user'] = self.context["request"].user.id
        return data

class RoomSerializer(serializers.ModelSerializer):
    """Сериализатор комнат"""
    messages = MessageSerializer(many=True, read_only=True)

    class Meta:
        model = Room
        fields = ["id", "name", "host", "messages", "current_users"]
        read_only_fields = ["id", "messages", "host", "current_users"]

    def create(self, validated_data):
        validated_data["host"] = self.context["request"].user
        return super().create(validated_data)


from tensorflow import keras
import losses, train, models
import tensorflow_addons as tfa
import os

# basic_model = models.buildin_models("ResNet101V2", dropout=0.4, emb_shape=512, output_layer="E")
# basic_model = models.buildin_models("ResNest50", dropout=0.4, emb_shape=512, output_layer="E")
# basic_model = models.buildin_models('EfficientNetB4', dropout=0, emb_shape=256, output_layer="GDC")
# basic_model = mobile_facenet.mobile_facenet(256, dropout=0, name="mobile_facenet_256")
# basic_model = mobile_facenet.mobile_facenet(256, dropout=0, name="se_mobile_facenet_256", use_se=True)
#basic_model = models.buildin_models("MobileNet", dropout=0, emb_shape=256, output_layer="GDC")
model_name = "binarydensenet"
basic_model = models.buildin_models(model_name, dropout=0, emb_shape=256, output_layer="GDC")
dataset_name = 'ms1m-retinaface-t1'
data_path = os.path.join('.','datasets',dataset_name)
eval_paths = [os.path.join(data_path,bin_file) for bin_file in ['lfw.bin','cfp_fp.bin','agedb_30.bin']]

tt = train.Train(data_path, save_path='keras_'+model_name+'_'+dataset_name+'.h5', eval_paths=eval_paths,
                basic_model=basic_model, lr_base=0.1, batch_size=128, random_status=2)
#optimizer = tfa.optimizers.AdamW(weight_decay=5e-5)
optimizer = tfa.optimizers.SGDW(learning_rate=0.1, weight_decay=5e-4, momentum=0.9)

sch = [
  #{"loss": keras.losses.CategoricalCrossentropy(label_smoothing=0.1), "centerloss": 0.01, "optimizer": optimizer, "epoch": 20},
  #{"loss": keras.losses.CategoricalCrossentropy(label_smoothing=0.1), "centerloss": 0.1, "epoch": 20},
  #{"loss": keras.losses.CategoricalCrossentropy(label_smoothing=0.1), "centerloss": 0.5, "epoch": 20},
  #{"loss": losses.ArcfaceLoss(), "epoch": 20, "triplet": 64, "alpha": 0.3},
  #{"loss": losses.ArcfaceLoss(), "epoch": 20, "triplet": 64, "alpha": 0.25},
  {"loss": losses.ArcfaceLoss(scale=64), "epoch": 50,"optimizer":optimizer},
]
tt.train(sch, 0)