"""
Compare regional feedbacks.

Be sure to adjust data_dir5 and data_dir6 and pl_path.
"""

#%% imports
import os
import sys
import glob
import copy
import time
import numpy as np
import pylab as pl
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.colors as colors
from matplotlib import gridspec
from mpl_toolkits.axes_grid1.axes_divider import make_axes_locatable
import cartopy
import cartopy.util as cu
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from netCDF4 import Dataset
from matplotlib import cm
from scipy.stats import ttest_ind
from scipy.stats import linregress as lr
from scipy.stats import pearsonr as pears_corr
from scipy import interpolate
from scipy import signal
import progressbar as pg
import dask.array as da
import time as ti

#%% set scripts directory and import self-written functions
direc = "../"
os.chdir(direc)
# needed for console
sys.path.append(direc)

from Functions.Func_Region_Mean import region_mean
from Functions.Func_Extract_Geographic_Region import extract_region
from Functions.Func_RunMean import run_mean
from Functions.Func_APRP import simple_comp, a_cs, a_oc, a_oc2, plan_al
from Functions.Func_Convert_To_Europe_Centric import eu_centric
from Functions.Func_Lat_Mean import lat_mean
from Functions.Func_Glob_Mean import glob_mean
from Functions.Func_AnMean import an_mean
from Functions.Func_Climatology import climatology
from Functions.Func_SeasonalMean import sea_mean
from Functions.Func_Round import r2, r3, r4
from Functions.Func_Regrid_Data_RectBiVSpline import remap
from Functions.Func_Regrid_Data import remap as remap2
from Functions.Func_Prep_Fb_Barplot import prep_fb_bars
from Functions.Func_Set_ColorLevels import set_levs_norm_colmap
from Classes.Class_MidpointNormalize import MidpointNormalize

#%% set model groups
# models1 = ["CanESM5", "CMCC-ESM2", "CNRM-CM6-1", "E3SM-1-0", "MPI-ESM1-2-LR", "UKESM1-0-LL"]
# models2 = ["NorESM1_M", "ACCESS-ESM1-5", "EC-Earth3", "FGOALS-g3", "INM-CM4-8"]
models1 = ["IPSL_CM5A_LR", "CanESM5", "CMCC-ESM2", "CNRM-CM6-1", "E3SM-1-0", "MPI-ESM1-2-LR", "UKESM1-0-LL"]
models2 = ["BCC_CSM1_1", "BCC_CSM1_1_M", "GFDL_CM3", "GISS_E2_H", "NorESM1_M", "BCC-CSM2-MR", "EC-Earth3", "FGOALS-g3",
           "INM-CM4-8"]

models = {"G1":models1, "G2":models2}
g_cols = {"G1":"blue", "G2":"red"}

#%% set the region
### --> Subpolar North Atlantic (SPNA) in Bellomo et al. (2021):  50-70N, 80W-10E

# 2: mid-latitude North Atlantic
x1 = [300]
x2 = [350]
y1 = [40]
y2 = [60]

x1 = [145]
x2 = [160]
y1 = [35]
y2 = [45]

x1 = [178]
x2 = [182]
y1 = [42]
y2 = [47]

# 6: excluding northern extra-tropics
x1, x2 = [0], [360]
y1, y2 = [-90], [30]

# 7: northern extra-tropics
# x1, x2 = [0], [360]
# y1, y2 = [30], [90]

# Bellomo et al. (2021)
# x1 = [280]
# x2 = [10]
# y1 = [50]
# y2 = [70]

# set the region name
reg_name = "6"
reg_name_title = {"1":"Barents-Norwegian-Greenland Sea", "2":"Mid-latitude North Atlantic",
                  "3":"Western Pacific", "4":"Central Mid-Latitude North Pacific", "5":"Eastern Japanese Coast",
                  "6":"Excl. Northern Extra-tropics", "7":"Northern Extra-tropics"}
reg_name_fn = {"1":"BNG_Sea", "2":"MLNA", "3":"NWP", "4":"CMLP", "5":"EJC", "6":"ExNExTr", "7":"NExTr"}

#%% set up some initial dictionaries and lists --> NEEDED FOR CSLT !!!

# kernels names for keys
# k_k = ["Sh08", "So08", "BM13", "H17", "P18"]
kl = "Sh08"
k_k = [kl]

# kernel names for plot titles etc.
k_n = {"Sh08":"Shell", "So08":"Soden", "BM13":"Block&Mauritsen", "H17":"Huang", "P18":"Pendergrass"}
k_p = {"Sh08":"Shell_etal_2008", "So08":"Soden_etal_2008", "BM13":"Block_Mauritsen_2013", "H17":"Huang_etal_2017",
       "P18":"Pendergrass_etal_2018"}

#%% choose the threshold year; if this is set to 0, the "year of maximum feedback change" will be taken from the below
#   dictionary
thr_yr = 20

thr_min = 15
thr_max = 75

#%% add a a plot name suffix for excluded models

all_mod = np.array(['ACCESS1.0', 'ACCESS1.3', 'BCC-CSM1.1', 'BCC-CSM1.1(m)', 'BNU-ESM', 'CanESM2', "CCSM4", 'CNRM-CM5',
                    "FGOALS-s2", 'GFDL-CM3', "GFDL-ESM2G", 'GFDL-ESM2M', 'GISS-E2-H', 'GISS-E2-R', 'HadGEM2-ES',
                    "INMCM4", 'IPSL-CM5A-LR', 'IPSL-CM5B-LR', 'MIROC5', "MIROC-ESM", 'MPI-ESM-LR', 'MPI-ESM-MR',
                    'MPI-ESM-P', 'MRI-CGCM3', 'NorESM1-M',
                    'ACCESS-CM2', 'ACCESS-ESM1.5', 'AWI-CM-1.1-MR', 'BCC-CSM2-MR', 'BCC-ESM1', 'CAMS-CSM1.0',
                    'CanESM5', "CAS-ESM2.0", "CESM2", "CESM2-FV2", "CESM2-WACCM", "CESM2-WACCM-FV2", "CIESM",
                    'CMCC-CM2-SR5', "CMCC-ESM2", 'CNRM-CM6.1', "CNRM-CM6.1-HR", 'CNRM-ESM2.1', 'E3SM-1.0', 'EC-Earth3',
                    "EC-Earth3-AerChem", 'EC-Earth3-Veg', 'FGOALS-f3-L', 'FGOALS-g3', "FIO-ESM2.0", 'GFDL-CM4',
                    'GFDL-ESM4', 'GISS-E2.1-G', 'GISS-E2.1-H', 'GISS-E2.2-G', 'HadGEM3-GC31-LL', 'HadGEM3-GC31-MM',
                    "IITM-ESM",  'INM-CM4.8', 'INM-CM5', 'IPSL-CM6A-LR', "KACE-1.0-G", "KIOST-ESM", 'MIROC-ES2L',
                    'MIROC6', 'MPI-ESM1.2-HAM', 'MPI-ESM1.2-HR', 'MPI-ESM1.2-LR', 'MRI-ESM2.0', "NESM3", 'NorCPM1',
                    "NorESM2-LM", "NorESM2-MM", 'SAM0-UNICON', 'TaiESM1', 'UKESM1.0-LL'])

#%% load model lists to check if a particular model is a member of CMIP5 or 6
import Namelists.Namelist_CMIP5 as nl5
import Namelists.Namelist_CMIP6 as nl6
import Namelists.CMIP_Dictionaries as cmip_dic
data_dir5 = ""  # SETS BASIC DATA DIRECTORY
data_dir6 = ""  # SETS BASIC DATA DIRECTORY

a4x5 = "abrupt4xCO2"
a4x6 = "abrupt-4xCO2"

cmip5_list = nl5.models
cmip6_list = nl6.models

pl_path = "/MultModPlots/G1_G2_Regional_Comparison_piC_a4x/"

# generate the plot path
os.makedirs(pl_path + "/PDF/", exist_ok=True)
os.makedirs(pl_path + "/PNG/", exist_ok=True)

#%% loop over the groups and collect their data to compare later

# set up dictionaries to collect the data
mods_d = dict()

pl_add = ""
tl_add = ""

lr_fb_e_d = dict()
lr_fb_l_d = dict()
lr_fb_d_d = dict()
c_fb_e_d = dict()
c_fb_l_d = dict()
c_fb_d_d = dict()
c_lw_fb_e_d = dict()
c_lw_fb_l_d = dict()
c_lw_fb_d_d = dict()
c_sw_fb_e_d = dict()
c_sw_fb_l_d = dict()
c_sw_fb_d_d = dict()

for g12, group in zip(["G1", "G2"], [models1, models2]):

    mods = []
    mod_count = 0

    # set up arrays to store all the feedback values --> we need this to easily calculate the multi-model mean
    lr_fb_e_l = []
    lr_fb_l_l = []
    lr_fb_d_l = []
    c_fb_e_l = []
    c_fb_l_l = []
    c_fb_d_l = []
    c_lw_fb_e_l = []
    c_lw_fb_l_l = []
    c_lw_fb_d_l = []
    c_sw_fb_e_l = []
    c_sw_fb_l_l = []
    c_sw_fb_d_l = []

    for i, mod_d in enumerate(group):
        if mod_d in cmip5_list:
            data_dir = data_dir5
            cmip = "5"
            mod = cmip_dic.mod_dict[cmip][mod_d]
            mod_pl = nl5.models_pl[mod]
            mod_n = nl5.models_n[mod]
            mod_dir = nl5.models[mod]
            b_time = nl5.b_times[mod_d]
            a4x = "abrupt4xCO2"
            si_varn = "sic"
        elif mod_d in cmip6_list:
            data_dir = data_dir6
            cmip = "6"
            mod = cmip_dic.mod_dict[cmip][mod_d]
            mod_pl = nl6.models_pl[mod]
            mod_n = nl6.models_n[mod]
            mod_dir = nl6.models[mod]
            b_time = nl6.b_times[mod_d]
            a4x = "abrupt-4xCO2"
            si_varn = "siconc"
        # end if

        # set start and end index for the piControl experiment depending on the branch year
        bst = b_time * 12
        ben = bst + 150*12

        # load nc files
        fb_nc = Dataset(glob.glob(data_dir + f"Outputs/Feedbacks_Local/Kernel/{a4x}/{k_p[kl]}/tas_Based/*{mod_d}.nc")[0])

        #% get lat and lon
        lat = fb_nc.variables["lat"][:]
        lon = fb_nc.variables["lon"][:]
        olat = lat + 90
        olon = lon + 0

        # extract region
        lr_fb_e = region_mean(fb_nc.variables["LR_fb_e"][0, :, :], x1, x2, y1, y2, lat, lon, test_plt=False,
                              plot_title="LR")
        lr_fb_l = region_mean(fb_nc.variables["LR_fb_l"][0, :, :], x1, x2, y1, y2, lat, lon, test_plt=False,
                              plot_title="LR")
        lr_fb_d = region_mean(fb_nc.variables["LR_dfb"][:, :], x1, x2, y1, y2, lat, lon, test_plt=False,
                              plot_title="LR")
        c_fb_e = region_mean(fb_nc.variables["C_fb_e"][0, :, :], x1, x2, y1, y2, lat, lon, test_plt=False,
                             plot_title="C")
        c_fb_l = region_mean(fb_nc.variables["C_fb_l"][0, :, :], x1, x2, y1, y2, lat, lon, test_plt=False,
                             plot_title="C")
        c_fb_d = region_mean(fb_nc.variables["C_dfb"][:, :], x1, x2, y1, y2, lat, lon, test_plt=False,
                             plot_title="C")
        clw_fb_e = region_mean(fb_nc.variables["C_lw_fb_e"][0, :, :], x1, x2, y1, y2, lat, lon, test_plt=False,
                               plot_title="C")
        clw_fb_l = region_mean(fb_nc.variables["C_lw_fb_l"][0, :, :], x1, x2, y1, y2, lat, lon, test_plt=False,
                               plot_title="C")
        clw_fb_d = region_mean(fb_nc.variables["C_lw_dfb"][:, :], x1, x2, y1, y2, lat, lon, test_plt=False,
                               plot_title="C")
        csw_fb_e = region_mean(fb_nc.variables["C_sw_fb_e"][0, :, :], x1, x2, y1, y2, lat, lon, test_plt=False,
                               plot_title="C")
        csw_fb_l = region_mean(fb_nc.variables["C_sw_fb_l"][0, :, :], x1, x2, y1, y2, lat, lon, test_plt=False,
                               plot_title="C")
        csw_fb_d = region_mean(fb_nc.variables["C_sw_dfb"][:, :], x1, x2, y1, y2, lat, lon, test_plt=False,
                               plot_title="C")

        lr_fb_e_l.append(lr_fb_e)
        lr_fb_l_l.append(lr_fb_l)
        lr_fb_d_l.append(lr_fb_d)
        c_fb_e_l.append(c_fb_e)
        c_fb_l_l.append(c_fb_l)
        c_fb_d_l.append(c_fb_d)
        c_lw_fb_e_l.append(clw_fb_e)
        c_lw_fb_l_l.append(clw_fb_l)
        c_lw_fb_d_l.append(clw_fb_d)
        c_sw_fb_e_l.append(csw_fb_e)
        c_sw_fb_l_l.append(csw_fb_l)
        c_sw_fb_d_l.append(csw_fb_d)

        print(g12 + " " + str(i) + ": " + mod_pl)

        mods.append(mod_pl)

        mod_count += 1
    # end for i, mod_d

    print("\n")

    # print(f"{g12} shape: {np.shape(cre_lw_pic)}")

    print("\n\n")
    # store everything in dictionaries
    lr_fb_e_d[g12] = np.array(lr_fb_e_l)
    lr_fb_l_d[g12] = np.array(lr_fb_l_l)
    lr_fb_d_d[g12] = np.array(lr_fb_d_l)
    c_fb_e_d[g12] = np.array(c_fb_e_l)
    c_fb_l_d[g12] = np.array(c_fb_l_l)
    c_fb_d_d[g12] = np.array(c_fb_d_l)
    c_lw_fb_e_d[g12] = np.array(c_lw_fb_e_l)
    c_lw_fb_l_d[g12] = np.array(c_lw_fb_l_l)
    c_lw_fb_d_d[g12] = np.array(c_lw_fb_d_l)
    c_sw_fb_e_d[g12] = np.array(c_sw_fb_e_l)
    c_sw_fb_l_d[g12] = np.array(c_sw_fb_l_l)
    c_sw_fb_d_d[g12] = np.array(c_sw_fb_d_l)

    mods_d[g12] = np.array(mods)

# end for g12

#%% t-test
lr_e_ttest = ttest_ind(lr_fb_e_d["G1"], lr_fb_e_d["G2"], axis=0)
lr_l_ttest = ttest_ind(lr_fb_l_d["G1"], lr_fb_l_d["G2"], axis=0)
lr_d_ttest = ttest_ind(lr_fb_d_d["G1"], lr_fb_d_d["G2"], axis=0)
c_e_ttest = ttest_ind(c_fb_e_d["G1"], c_fb_e_d["G2"], axis=0)
c_l_ttest = ttest_ind(c_fb_l_d["G1"], c_fb_l_d["G2"], axis=0)
c_d_ttest = ttest_ind(c_fb_d_d["G1"], c_fb_d_d["G2"], axis=0)
c_lw_e_ttest = ttest_ind(c_lw_fb_e_d["G1"], c_lw_fb_e_d["G2"], axis=0)
c_lw_l_ttest = ttest_ind(c_lw_fb_l_d["G1"], c_lw_fb_l_d["G2"], axis=0)
c_lw_d_ttest = ttest_ind(c_lw_fb_d_d["G1"], c_lw_fb_d_d["G2"], axis=0)
c_sw_e_ttest = ttest_ind(c_sw_fb_e_d["G1"], c_sw_fb_e_d["G2"], axis=0)
c_sw_l_ttest = ttest_ind(c_sw_fb_l_d["G1"], c_sw_fb_l_d["G2"], axis=0)
c_sw_d_ttest = ttest_ind(c_sw_fb_d_d["G1"], c_sw_fb_d_d["G2"], axis=0)

#%% print values
print(f"G1 LR early: {r2(np.mean(lr_fb_e_d['G1']))} +/- {r2(np.std(lr_fb_e_d['G1']))}")
print(f"G1 LR late: {r2(np.mean(lr_fb_l_d['G1']))} +/- {r2(np.std(lr_fb_l_d['G1']))}")
print(f"G1 LR change: {r2(np.mean(lr_fb_d_d['G1']))} +/- {r2(np.std(lr_fb_d_d['G1']))}")
print(f"G1 C early: {r2(np.mean(c_fb_e_d['G1']))} +/- {r2(np.std(c_fb_e_d['G1']))}")
print(f"G1 C late: {r2(np.mean(c_fb_l_d['G1']))} +/- {r2(np.std(c_fb_l_d['G1']))}")
print(f"G1 C change: {r2(np.mean(c_fb_d_d['G1']))} +/- {r2(np.std(c_fb_d_d['G1']))}\n")

print(f"G2 LR early: {r2(np.mean(lr_fb_e_d['G2']))} +/- {r2(np.std(lr_fb_e_d['G2']))}")
print(f"G2 LR late: {r2(np.mean(lr_fb_l_d['G2']))} +/- {r2(np.std(lr_fb_l_d['G2']))}")
print(f"G2 LR change: {r2(np.mean(lr_fb_d_d['G2']))} +/- {r2(np.std(lr_fb_d_d['G2']))}")
print(f"G2 C early: {r2(np.mean(c_fb_e_d['G2']))} +/- {r2(np.std(c_fb_e_d['G2']))}")
print(f"G2 C late: {r2(np.mean(c_fb_l_d['G2']))} +/- {r2(np.std(c_fb_l_d['G2']))}")
print(f"G2 C change: {r2(np.mean(c_fb_d_d['G2']))} +/- {r2(np.std(c_fb_d_d['G2']))}")

#%% plot group means
fig, axes = pl.subplots(ncols=2, nrows=1, figsize=(10, 6), sharey=True)

ax00 = axes[0].twinx()
ax01 = axes[1].twinx()

axes[0].errorbar(0, np.mean(lr_fb_e_d["G1"]), yerr=np.std(lr_fb_e_d["G1"]), c="blue", label="G1", fmt="o", zorder=101,
                linewidth=1, capsize=3.5, markersize=8)
axes[0].errorbar(0, np.mean(lr_fb_e_d["G2"]), yerr=np.std(lr_fb_e_d["G2"]), c="red", label="G2", fmt="o", zorder=101,
                linewidth=1, capsize=3.5, markersize=8)
axes[0].errorbar(1, np.mean(lr_fb_l_d["G1"]), yerr=np.std(lr_fb_l_d["G1"]), c="blue", fmt="o", zorder=101,
                linewidth=1, capsize=3.5, markersize=8)
axes[0].errorbar(1, np.mean(lr_fb_l_d["G2"]), yerr=np.std(lr_fb_l_d["G2"]), c="red", fmt="o", zorder=101,
                linewidth=1, capsize=3.5, markersize=8)
axes[0].errorbar(2, np.mean(lr_fb_d_d["G1"]), yerr=np.std(lr_fb_l_d["G1"]), c="blue", fmt="o", zorder=101,
                linewidth=1, capsize=3.5, markersize=8)
axes[0].errorbar(2, np.mean(lr_fb_d_d["G2"]), yerr=np.std(lr_fb_l_d["G2"]), c="red", fmt="o", zorder=101,
                linewidth=1, capsize=3.5, markersize=8)

ax00.scatter(0, lr_e_ttest.pvalue, c="gray")
ax00.scatter(1, lr_l_ttest.pvalue, c="gray")
ax00.scatter(2, lr_d_ttest.pvalue, c="gray")
ax00.set_ylim((0, 0.1))
ax00.set_yticks([0, 0.025, 0.05, 0.075, 0.1])

axes[0].set_ylim(-3.5, 3.5)

axes[0].axhline(y=0, c="gray", linewidth=1.5, zorder=102)

axes[0].legend(loc="upper left")

axes[0].set_xticks([0, 1, 2])
axes[0].set_xticklabels(["early", "late", "change"])

axes[0].set_ylabel("Feedback in Wm$^{-1}$K$^{-2}$")
axes[0].set_title("Lapse-rate feedback")

axes[1].errorbar(0, np.mean(c_fb_e_d["G1"]), yerr=np.std(lr_fb_e_d["G1"]), c="blue", fmt="o", zorder=101,
                linewidth=1, capsize=3.5, markersize=8)
axes[1].errorbar(0, np.mean(c_fb_e_d["G2"]), yerr=np.std(lr_fb_e_d["G2"]), c="red", fmt="o", zorder=101,
                linewidth=1, capsize=3.5, markersize=8)
axes[1].errorbar(1, np.mean(c_fb_l_d["G1"]), yerr=np.std(lr_fb_l_d["G1"]), c="blue", fmt="o", zorder=101,
                linewidth=1, capsize=3.5, markersize=8)
axes[1].errorbar(1, np.mean(c_fb_l_d["G2"]), yerr=np.std(lr_fb_l_d["G2"]), c="red", fmt="o", zorder=101,
                linewidth=1, capsize=3.5, markersize=8)
axes[1].errorbar(2, np.mean(c_fb_d_d["G1"]), yerr=np.std(lr_fb_l_d["G1"]), c="blue", fmt="o", zorder=101,
                linewidth=1, capsize=3.5, markersize=8)
axes[1].errorbar(2, np.mean(c_fb_d_d["G2"]), yerr=np.std(lr_fb_l_d["G2"]), c="red", fmt="o", zorder=101,
                linewidth=1, capsize=3.5, markersize=8)

ax01.scatter(0, c_e_ttest.pvalue, c="gray")
ax01.scatter(1, c_l_ttest.pvalue, c="gray")
ax01.scatter(2, c_d_ttest.pvalue, c="gray")
ax01.set_ylim((0, 0.1))
ax01.set_yticks([0, 0.025, 0.05, 0.075, 0.1])
# ax01.set_xticklabels(["early", "late", "change"])

axes[1].axhline(y=0, c="gray", linewidth=1.5, zorder=102)

axes[1].set_xticks([0, 1, 2])
axes[1].set_xticklabels(["early", "late", "change"])
axes[1].set_title("Cloud feedback")

fig.suptitle(f"{reg_name_title[reg_name]} " +
             f"({y1[0]}$-${y2[0]}$\degree$N, {x1[0]}$-${x2[0]}$\degree$E)")
fig.subplots_adjust(top=0.89, wspace=0.3)

pl.savefig(pl_path + f"/PDF/{reg_name_fn[reg_name]}_LR_C_Fb_G1_G2_Comp.pdf", bbox_inches="tight", dpi=250)
pl.savefig(pl_path + f"/PNG/{reg_name_fn[reg_name]}_LR_C_Fb_G1_G2_Comp.png", bbox_inches="tight", dpi=250)

pl.show()
pl.close()

#%% plot group means
fig, axes = pl.subplots(ncols=2, nrows=1, figsize=(10, 6), sharey=True)

ax00 = axes[0].twinx()
ax01 = axes[1].twinx()

axes[0].errorbar(0, np.mean(c_lw_fb_e_d["G1"]), yerr=np.std(c_lw_fb_e_d["G1"]), c="blue", label="G1", fmt="o",
                 zorder=101, linewidth=1, capsize=3.5, markersize=8)
axes[0].errorbar(0, np.mean(c_lw_fb_e_d["G2"]), yerr=np.std(c_lw_fb_e_d["G2"]), c="red", label="G2", fmt="o",
                 zorder=101, linewidth=1, capsize=3.5, markersize=8)
axes[0].errorbar(1, np.mean(c_lw_fb_l_d["G1"]), yerr=np.std(c_lw_fb_l_d["G1"]), c="blue", fmt="o", zorder=101,
                linewidth=1, capsize=3.5, markersize=8)
axes[0].errorbar(1, np.mean(c_lw_fb_l_d["G2"]), yerr=np.std(c_lw_fb_l_d["G2"]), c="red", fmt="o", zorder=101,
                linewidth=1, capsize=3.5, markersize=8)
axes[0].errorbar(2, np.mean(c_lw_fb_d_d["G1"]), yerr=np.std(c_lw_fb_l_d["G1"]), c="blue", fmt="o", zorder=101,
                linewidth=1, capsize=3.5, markersize=8)
axes[0].errorbar(2, np.mean(c_lw_fb_d_d["G2"]), yerr=np.std(c_lw_fb_l_d["G2"]), c="red", fmt="o", zorder=101,
                linewidth=1, capsize=3.5, markersize=8)

ax00.scatter(0, c_lw_e_ttest.pvalue, c="gray")
ax00.scatter(1, c_lw_l_ttest.pvalue, c="gray")
ax00.scatter(2, c_lw_d_ttest.pvalue, c="gray")
ax00.set_ylim((0, 0.1))
ax00.set_yticks([0, 0.025, 0.05, 0.075, 0.1])

axes[0].set_ylim(-3.5, 3.5)

axes[0].axhline(y=0, c="gray", linewidth=1.5, zorder=102)

axes[0].legend(loc="upper left")

axes[0].set_xticks([0, 1, 2])
axes[0].set_xticklabels(["early", "late", "change"])

axes[0].set_ylabel("Feedback in Wm$^{-1}$K$^{-2}$")
axes[0].set_title("Long-wave cloud feedback")

axes[1].errorbar(0, np.mean(c_sw_fb_e_d["G1"]), yerr=np.std(c_sw_fb_e_d["G1"]), c="blue", fmt="o", zorder=101,
                linewidth=1, capsize=3.5, markersize=8)
axes[1].errorbar(0, np.mean(c_sw_fb_e_d["G2"]), yerr=np.std(c_sw_fb_e_d["G2"]), c="red", fmt="o", zorder=101,
                linewidth=1, capsize=3.5, markersize=8)
axes[1].errorbar(1, np.mean(c_sw_fb_l_d["G1"]), yerr=np.std(c_sw_fb_l_d["G1"]), c="blue", fmt="o", zorder=101,
                linewidth=1, capsize=3.5, markersize=8)
axes[1].errorbar(1, np.mean(c_sw_fb_l_d["G2"]), yerr=np.std(c_sw_fb_l_d["G2"]), c="red", fmt="o", zorder=101,
                linewidth=1, capsize=3.5, markersize=8)
axes[1].errorbar(2, np.mean(c_sw_fb_d_d["G1"]), yerr=np.std(c_sw_fb_l_d["G1"]), c="blue", fmt="o", zorder=101,
                linewidth=1, capsize=3.5, markersize=8)
axes[1].errorbar(2, np.mean(c_sw_fb_d_d["G2"]), yerr=np.std(c_sw_fb_l_d["G2"]), c="red", fmt="o", zorder=101,
                linewidth=1, capsize=3.5, markersize=8)

ax01.scatter(0, c_sw_e_ttest.pvalue, c="gray")
ax01.scatter(1, c_sw_l_ttest.pvalue, c="gray")
ax01.scatter(2, c_sw_d_ttest.pvalue, c="gray")
ax01.set_ylim((0, 0.1))
ax01.set_yticks([0, 0.025, 0.05, 0.075, 0.1])
# ax01.set_xticklabels(["early", "late", "change"])

axes[1].axhline(y=0, c="gray", linewidth=1.5, zorder=102)

axes[1].set_xticks([0, 1, 2])
axes[1].set_xticklabels(["early", "late", "change"])
axes[1].set_title("Short-wave cloud feedback")

fig.suptitle(f"{reg_name_title[reg_name]} " +
             f"({y1[0]}$-${y2[0]}$\degree$N, {x1[0]}$-${x2[0]}$\degree$E)")
fig.subplots_adjust(top=0.89, wspace=0.3)

pl.savefig(pl_path + f"/PDF/{reg_name_fn[reg_name]}_LW_SW_C_Fb_G1_G2_Comp.pdf", bbox_inches="tight", dpi=250)
pl.savefig(pl_path + f"/PNG/{reg_name_fn[reg_name]}_LW_SW_C_Fb_G1_G2_Comp.png", bbox_inches="tight", dpi=250)

pl.show()
pl.close()


from flask import Blueprint, jsonify, make_response
from sqlalchemy import text
from ..utils import db

bp = Blueprint("countries", __name__, url_prefix="/countries")

@bp.route("/")
def countries():
    conn = db.get_db()

    rows = conn.execute(text("SELECT * FROM Country")).all()

    countries = []
    for r in rows:
        countries.append(r._asdict())

    return jsonify(countries)

@bp.route("/<country>")
def country_population(country):
    conn = db.get_db()

    try:
        row = conn.execute(text(f"SELECT * FROM Country WHERE cname = '{country}'")).one()
        return row._asdict()
    except:
        return make_response({"status": "failure", "message": "No such country"}, 404)


import os
import pandas as pd
from detect_delimiter import detect
from utils import load_json

def check_dir_files_type(baseaddr):
    all_folder = None

    for f in os.listdir(baseaddr):
        if os.path.isfile(os.path.join(baseaddr, f)):
            if all_folder == True:
                raise Exception('directory can not have both directories and files')
            all_folder = False
        else:
            if all_folder == False:
                raise Exception('directory can not have both directories and files')
            all_folder = True

    if all_folder:
        extension = ''
    else:
        f = os.listdir(baseaddr)[0]
        extension = os.path.splitext(f)[1].lower()

    return extension

def load_data(baseaddr, existing_column_names):
    data = None
    extension = check_dir_files_type(baseaddr)

    if extension == '.txt':
        data = handle_text_data(baseaddr, existing_column_names)
    elif extension == '.json':
        data = handle_json_data(baseaddr, existing_column_names)
    elif extension in ['.csv', '.xlsx']:
        data = handle_excel_data(baseaddr, existing_column_names)
    elif extension == '':
        data = handle_dir_data(baseaddr, existing_column_names)

    return data

def handle_text_data(baseaddr, existing_column_names):
    for filename in os.listdir(baseaddr):
        filename_without_extension = os.path.splitext(filename)[0]
        result = {
            'collection_name': filename_without_extension,
            'rows': []
        }
        if filename_without_extension == 'columns_format':
            continue
        elif filename_without_extension in existing_column_names:
            yield result
            continue

        f = open(os.path.join(baseaddr, filename), 'r', encoding='utf8')
        lines = f.read().strip('\n').split('\n')
        delimiter = detect(lines[0], whitelist=['\t', ',', ' '])

        for line in lines:
            row_list = line.split(delimiter)
            for i in range(len(row_list)):
                if row_list[i] == '':
                    row_list[i] = None
            result['rows'].append(row_list)

        yield result

def handle_json_data(baseaddr, existing_column_names):
    for filename in os.listdir(baseaddr):
        filename_without_extension = os.path.splitext(filename)[0]
        result = {
            'collection_name': filename_without_extension,
            'rows': []
        }
        if filename_without_extension == 'columns_format':
            continue
        elif filename_without_extension in existing_column_names:
            yield result
            continue

        d = load_json(os.path.join(baseaddr, filename))
        for i in range(len(d)):
            for key in d[i]:
                if d[i][key] == '':
                    d[i][key] = None
            result['rows'].append(list(d[i].values()))

        yield result

def handle_excel_data(baseaddr, existing_column_names):
    for filename in os.listdir(baseaddr):
        filename_without_extension = os.path.splitext(filename)[0]
        result = {
            'collection_name': filename_without_extension,
            'rows': []
        }
        if filename_without_extension == 'columns_format':
            continue
        elif filename_without_extension in existing_column_names:
            yield result
            continue

        filename_extension = os.path.splitext(filename)[1]
        if filename_extension == '.xlsx':
            df = pd.read_excel(os.path.join(baseaddr, filename))
        else:
            df = pd.read_csv(os.path.join(baseaddr, filename))
        result['rows'] = df.values.tolist()
        yield result

def handle_dir_data(baseaddr, existing_column_names):
    for collection_name in os.listdir(baseaddr):
        if collection_name == 'columns_format.json':
            continue
        elif collection_name in existing_column_names:
            yield False

        result = {
            'collection_name': collection_name,
            'rows': []
        }
        for filename_id in os.listdir(os.path.join(baseaddr, collection_name)):
            for filename in os.listdir(os.path.join(baseaddr, collection_name, filename_id)):
                if filename == f'{filename_id}.txt':
                    data = handle_text_data(
                        os.path.join(baseaddr, collection_name, filename_id, filename), existing_column_names)
                    row = data['rows'][0]
                    break
                elif filename == f'{filename_id}.json':
                    data = handle_json_data(
                        os.path.join(baseaddr, collection_name, filename_id, filename), existing_column_names)
                    row = data['rows'][0]
                    break
                elif filename in [f'{filename_id}.csv', f'{filename_id}.xlsx']:
                    data = handle_excel_data(
                        os.path.join(baseaddr, collection_name, filename_id, filename), existing_column_names)
                    row = data['rows'][0]
                    break

            result['rows'].append(row)

        yield result


import sqlite3
import numpy as np

def dict_factory(cursor, row):
    d = {}
    for idx, col in enumerate(cursor.description):
        d[col[0]] = row[idx]
    return d

conn = sqlite3.connect('mux.db')
conn.row_factory = dict_factory
    #sqlite3.Row

cur = conn.cursor()
cur.execute('select out from mux WHERE out=40')
pinout=cur.fetchone()

cur.execute('select A0, A1, A2, A3, A4, CS1, CS2, CS3 from mux ')
row = cur.fetchone()

print(pinout)
print(row)
print

# cur.execute("select 1 as A")
# print(cur.fetchone()['A'])


from app.tweet.adapters.repository import PostgresTweetAggregateRepository
from app.tweet.domain.model import Tweet
from uuid import uuid4

import pytest

class TestSave:
    @pytest.mark.asyncio
    async def test_save(self, postgres_session):
        repo = PostgresTweetAggregateRepository(postgres_session)
        aggregate = Tweet.new("Hello", uuid4())

        await repo.save(aggregate)

        print(await repo.find_by_id(aggregate.id))

class TestFindById:
    @pytest.mark.asyncio
    async def test_not_found(self, postgres_session):
        repo = PostgresTweetAggregateRepository(postgres_session)

        result = await repo.find_by_id(uuid4())
        assert result is None


from django.conf import settings
from adjuntos.models import Attachment

class Command(BaseCommand):

    def handle(self, *args, **options):

        for a in Attachment.objects.filter(probema__isnull=False):
            print(f'*** {settings.ALLOWED_HOSTS} ***')
            print(a.id, a.problema)
            print('')


# -*- coding: utf-8 -*-
"""
Created on Sat Jun 26 15:19:29 2021

@author: mob
"""

import torch
import os
import tifffile as tiff
from torch.utils.data import Dataset
from torch.utils.data import DataLoader
from torchvision.transforms import functional as F
from random import randint
import torchvision.transforms as transforms

class lungTrainDataset(Dataset):
    def __init__(self,folder):
        self.folder = folder
        self.image_folder = self.folder+"\\2d_images\\train\\"
        self.mask_folder = self.folder+"\\2d_masks\\train\\"
        self.file_list = os.listdir(self.image_folder)
        self.length = len(self.file_list)

    def __len__(self):
        return self.length
    def __getitem__(self,idx):
        img = torch.tensor(tiff.imread(self.image_folder+self.file_list[idx]))
        mask = torch.tensor(tiff.imread(self.mask_folder+self.file_list[idx]))
        img = img.float()
        mask = mask.float()
        img = img.unsqueeze(0)
        mask = mask.unsqueeze(0)
        img = transforms.Resize(256)(img)
        mask = transforms.Resize(256)(mask)
        return data_aug(img,mask)

class lungValDataset(Dataset):
    def __init__(self,folder):
        self.folder = folder
        self.image_folder = self.folder+"\\2d_images\\val\\"
        self.mask_folder = self.folder+"\\2d_masks\\val\\"
        self.file_list = os.listdir(self.image_folder)
        self.length = len(self.file_list)

    def __len__(self):
        return self.length
    def __getitem__(self,idx):
        img = torch.tensor(tiff.imread(self.image_folder+self.file_list[idx]))
        mask = torch.tensor(tiff.imread(self.mask_folder+self.file_list[idx]))
        img = img.float()
        mask = mask.float()
        img = img.unsqueeze(0)
        mask = mask.unsqueeze(0)
        img = transforms.Resize(256)(img)
        mask = transforms.Resize(256)(mask)
        return img,mask

def data_aug(img,mask):
    i = randint(1,4)
    if i==1:
        img = F.vflip(img)
        mask = F.vflip(mask)
    elif i==2:
        img = F.hflip(img)
        mask = F.hflip(mask)
    elif i==3:
        img = F.hflip(img)
        img = F.vflip(img)
        mask = F.hflip(mask)
        mask = F.vflip(mask)
    else:
        None
    return img,mask

def getDataLoader(dataset):
    return DataLoader(dataset,batch_size=16,shuffle=True)


# -*- coding: utf-8 -*-
#!/usr/bin/python2.6

import sys
import os
import csv
import pymongo
import json
from datetime import datetime
from copy import deepcopy
from pprint import pprint

path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
sys.path.insert(0, path)
sys.path.insert(0, path + "/sefaria")
from texts import *

parashiot_file = "/var/data/Sefaria-Data/misc/parshiot.csv"

def parse_span(ref):
	ref = ref.split(" | ")[0]
	ref = ref.replace(" - ", "-")
	return ref

def parse_haftara(ref):
	ref = parse_span(ref)
	refs = ref.split("; ")
	for i in range(len(refs)):
		if refs[i][0] in ["1", "2", "3", "4", "5", "6", "7", "8", "9"]:
			refs[i] = parse_ref(refs[i-1])["book"] + " " + refs[i]

	return refs

def parse_shabbat_name(ref):
	ref = ref.split(" | ")
	return ref[1] if len(ref) > 1 else None

p = []
with open(parashiot_file, 'rb') as csvfile:
	parashiot = csv.reader(csvfile)
	parashiot.next()
	parasha = {"date": None}
	for row in parashiot:
		if not len(row): continue

		# Continuation
		if datetime.strptime(row[0], "%d-%b-%Y") == parasha["date"]:
			if row[2] == "Haftara":
				parasha["haftara"] = parse_haftara(row[3])
				parasha["shabbat_name"] = parse_shabbat_name(row[3])
			else:
				parasha["aliyot"].append( parse_span(row[3]) )

		# New Parasha
		else:
			if parasha["date"] is not None:
				# clean up last object
				start = parse_ref(parasha["aliyot"][0])
				end   = parse_ref(parasha["aliyot"][7])
				start["toSections"] = end["toSections"]
				parasha["ref"] = make_ref(start)
				p.append(deepcopy(parasha))

			parasha = {
				"date": datetime.strptime(row[0], "%d-%b-%Y"),
				"parasha": row[1],
				"aliyot": [ parse_span(row[3]) ]
			}

db.parshiot.remove()
for parasha in p:
	db.parshiot.save(parasha)
db.parshiot.ensure_index("date")


"""prepare calibration dataset for quantization"""
import numpy as np
import torch as pt
from transformers import DistilBertTokenizer
from transformers.data.processors.squad import SquadV1Processor
from utils.onnx_bridge import OnnxBridge
from utils.image_dir import ImageDir

def prepare_dataset_images(dataset_path, path_ob):
    """prepare dataset images"""
    ob = OnnxBridge(path_ob)
    dims = ob.get_inputs()

    image_dims = tuple(dims[0])

    images = ImageDir(dataset_path, image_dims)
    _images = []
    if dims[1:] != []:
        pt.manual_seed(20)
        for im_idx in range(len(images)):
            rand_inp = [images[im_idx]]
            for el in dims[1:]:
                rand_inp.append(10 * pt.randn(tuple(el)).numpy())
            _images.append(rand_inp)
        images = _images  # [0]
    if len(images) != 0:
        print("Using Calibration set with", len(images), "sample images")
    else:
        print("Using Calibration set with randomly generated input")
        images = []
        for i in range(3):
            images.append(np.random.normal(size=tuple(dims[0])).astype(np.float32))

    return images

def calibration_equal_size(size_text, size_input):
    size_equals_size_input = True
    for k in size_text:
        if k != size_input:
            size_equals_size_input = False
    return size_equals_size_input

def prepare_dataset_text(dataset_path, size_input=384):
    """Choose 3 samples from the validation dataset for calibration
    best performance is if we choose text which is similar in length to the model's input size"""
    processor = SquadV1Processor()
    tokenizer = DistilBertTokenizer.from_pretrained('distilbert-base-uncased-distilled-squad')
    examples = processor.get_dev_examples(dataset_path, filename="dev-v1.1.json")
    qid_to_example_index = {example.qas_id: i for i, example in enumerate(examples)}
    qid_to_has_answer = {example.qas_id: bool(example.answers) for example in examples}
    answer_qids = [qas_id for qas_id, has_answer in qid_to_has_answer.items() if has_answer]
    size_text = np.array([0, 0, 0])
    text = np.array([None, None, None])
    if len(answer_qids) >= 3:
        for i in range(3):
            question = examples[qid_to_example_index[answer_qids[i]]].question_text
            context = examples[qid_to_example_index[answer_qids[i]]].context_text
            inputs = tokenizer.encode_plus(question, context, return_tensors='pt')
            size = dict(inputs)['input_ids'][0].size()[0]
            text[i] = inputs
            size_text[i] = size

        for i in range(len(answer_qids)):

            if calibration_equal_size(size_text, size_input):
                return text
            question = examples[qid_to_example_index[answer_qids[i]]].question_text
            context = examples[qid_to_example_index[answer_qids[i]]].context_text
            inputs = tokenizer.encode_plus(question, context, return_tensors='pt')
            size = dict(inputs)['input_ids'][0].size()[0]
            if abs(size - size_input) < np.max(abs(size_text - size_input)):
                j = np.argmax(abs(size_text - size))
                if size > size_input:
                    input_ids = dict(inputs)['input_ids'][0, :size_input]
                    attention_mask = dict(inputs)['attention_mask'][0, : size_input]
                else:
                    input_ids = pt.cat([dict(inputs)['input_ids'][0],
                                        pt.zeros(size_input - size, dtype=pt.int64)])
                    attention_mask = pt.cat([dict(inputs)['attention_mask'][0],
                                             pt.zeros(size_input - size, dtype=pt.int64)])
                inputs = [np.array(pt.reshape(input_ids, (1, size_input), )),
                          np.array(pt.reshape(attention_mask, (1, size_input)))]
                text[j] = inputs
                size_text[j] = size

        print("Created a Calibration set with", len(text), "text samples of lengths", size_text)
    else:
        text = []
        for i in range(3):
            input_ids = np.random.randint(20000, size=(1, size_input), dtype=np.int64)
            attention_mask = np.ones((1, size_input), dtype=np.int64)
            text.append((input_ids, attention_mask))
    return text


from rest_framework import serializers
from .models import midi_data

class firstappSerializer(serializers.ModelSerializer):
    user = serializers.PrimaryKeyRelatedField(
    read_only=True,
    default=serializers.CurrentUserDefault()
    )
    class Meta:
        model = midi_data
        fields = ('user', 'description', 'completed')


import pygame
import sys
#custom object for copys of walls
class bckgrnd1(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        img = pygame.image.load("invade.png")
        self.image = pygame.transform.scale(img, (1000, 700))
        self.mask  = pygame.mask.from_surface(self.image)
        self.rect = self.image.get_rect(topleft=(0,0))


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

import pygame
import math
import random

REWARD_RADIUS = 20
CAR_SPEED = 10
CAR_TURN = 30

def normalize(x, xmin, xmax):
    return ((x-xmin)/(xmax-xmin))

class pyGame(object):
    def __init__(self, width=1280, height=1024, fps=60, caption="PyGame", verbose = True, carX = 640, carY = 512, parkX = 640, parkY = 512):
        self.width = width
        self.height = height
        self.verbose = verbose

        #clock
        self.clock = pygame.time.Clock()
        self.fps = fps
        self.playtime = 0.0

        self.car = Car(carX,carY,0)
        self.env = Environment(parkX,parkY,0)

        #screen init
        if self.verbose:
            pygame.init()
            pygame.display.set_caption(caption)
            self.screen = pygame.display.set_mode((self.width, self.height), pygame.DOUBLEBUF)
            #frame init
            self.background = pygame.Surface(self.screen.get_size()).convert()
            self.background.fill((0,0,0)) # fill background black
            #font
            self.font = pygame.font.SysFont('mono', 14, bold=True)

    def reset(self, rX = False, rY = False, rD = False):
        self.car.reset(rX, rY, rD)
        self.env.reset(rX, rY, rD)
        return self.state()

    def state(self):
        return [normalize(self.car.rearAxis.x,0,self.width), normalize(self.car.rearAxis.y,0,self.height), \
              normalize(self.car.frontAxis.x,0,self.width), normalize(self.car.frontAxis.y,0,self.height), \
              normalize(self.env.parkEnd.x,0,self.width),  normalize(self.env.parkEnd.y,0,self.height), \
              normalize(self.env.parkFront.x,0,self.width), normalize(self.env.parkFront.y,0,self.height)]

    def draw(self):
        # draw functions here
        self.background.fill((0,0,0))
        self.background = self.background.convert()

    def flip(self):
        self.screen.blit(self.background, (0,0))
        pygame.display.flip()

    def __del__(self):
        #desctructor
        pygame.quit()
        print("Total play time {:.2f} seconds".format(self.playtime))

    def draw_text(self, text, x, y ):
        """Center text in window
        """
        surface = self.font.render(text, True, (0, 255, 0))
        # // makes integer division in python3
        self.background.blit(surface, (x, y))

    def reward(self):
        if math.fabs(self.car.rearAxis.x - self.env.parkEnd.x) < REWARD_RADIUS and math.fabs(self.car.rearAxis.y - self.env.parkEnd.y) < REWARD_RADIUS and \
           math.fabs(self.car.frontAxis.x - self.env.parkFront.x) < REWARD_RADIUS and math.fabs(self.car.frontAxis.y - self.env.parkFront.y < REWARD_RADIUS):
           if self.car.speed == 0:
               return 5000
           else:
                return 1000
        else:
           if self.car.speed == 0:
               return int( - (math.pow(self.car.rearAxis.x - self.env.parkEnd.x,2) + math.pow(self.car.rearAxis.y - self.env.parkEnd.y,2))/2000-100)
           else:
               return int( - (math.pow(self.car.rearAxis.x - self.env.parkEnd.x,2) + math.pow(self.car.rearAxis.y - self.env.parkEnd.y,2))/2000)

    def done(self):
        if (self.car.rearAxis.x>self.width) or (self.car.rearAxis.x<0) or \
        (self.car.rearAxis.y >self.height) or (self.car.rearAxis.y<0):
            return True
        #elif math.fabs(self.car.rearAxis.x - self.env.parkEnd.x) < REWARD_RADIUS and math.fabs(self.car.rearAxis.y - self.env.parkEnd.y) < REWARD_RADIUS and \
        #   math.fabs(self.car.frontAxis.x - self.env.parkFront.x) < REWARD_RADIUS and math.fabs(self.car.frontAxis.y - self.env.parkFront.y < REWARD_RADIUS):
        #    return True
        else:
            return False

    def step(self, action):
        #self.milliseconds = self.clock.tick(self.fps)  # milliseconds passed since last frame
        #self.seconds = self.milliseconds / 1000.0
        #self.playtime += self.seconds
        self.car.act(action)

        # all movement here
        #self.car.move(self.seconds, self.width, self.height)
        self.car.move()

        if self.verbose:
            # all render here
            self.draw()
            self.car.draw(self.background)
            self.env.draw(self.background)
            #self.draw_text("FPS {:.1f}".format(self.clock.get_fps()), 10, 10)
            self.draw_text("Action: {} speed: {} turn: {} Reward {}".format(action,self.car.speed,self.car.turnAngle, self.reward()),10, 10)
            self.flip()

        return self.state(), self.reward(), self.done(), 0

    def run(self):
        mainloop = True

        while mainloop:
            # count time
            self.milliseconds = self.clock.tick(self.fps)  # milliseconds passed since last frame
            self.seconds = self.milliseconds / 1000.0
            self.playtime += self.seconds

            # check for events
            self.car.speed = 0
            self.car.turnAngle = 0
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    mainloop = False # pygame window closed by user
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        mainloop = False # user pressed ESC
                    if event.key == pygame.K_r:
                        self.env.renewPark()

            pressed = pygame.key.get_pressed()
            if pressed[pygame.K_w]:
                self.car.speed = CAR_SPEED
            if pressed[pygame.K_s]:
                self.car.speed = -CAR_SPEED
            if pressed[pygame.K_a]:
                self.car.turnAngle = -CAR_TURN
            if pressed[pygame.K_d]:
                self.car.turnAngle = CAR_TURN

            # all movement here
            #self.car.move(self.seconds, self.width, self.height)
            self.car.move(1)

            # all render here
            self.draw()
            self.car.draw(self.background)
            self.env.draw(self.background)
            self.draw_text("speed: {} turn: {} Reward {}".format(self.car.speed,self.car.turnAngle, self.reward()),10, 10)
            self.flip()

class Point(object):
    def __init__(self, x = 0, y = 0):
        self.x = x
        self.y = y

    def xy(self):
        return self.x, self.y

    def xyI(self):
        return int(self.x), int(self.y)

    def rotate(self, px = 0, py = 0, angle = 0):
        self.x = px + self.x  * math.cos(math.radians(angle)) - self.y  * math.sin(math.radians(angle))
        self.y = py + self.x  * math.sin(math.radians(angle)) + self.y  * math.cos(math.radians(angle))

    def translate(self, lenght, angle, p = 0):
        if p == 0:
            self.x += lenght * math.cos(math.radians(angle))
            self.y += lenght * math.sin(math.radians(angle))
        else:
            self.x = p.x + lenght * math.cos(math.radians(angle))
            self.y = p.y + lenght * math.sin(math.radians(angle))

    def random(self, xmin, xmax, ymin, ymax):
        self.x = random.randrange(xmin, xmax)
        self.y = random.randrange(ymin, ymax)

    def copy(self, p):
        self.x = p.x
        self.y = p.y

class graphicCalculations():
    def findLocation(self,centerPointX, centerPointY, deltaX,deltaY, angle):
        # find location from center of object and apply rotation by given angle
        centerPoint = Point(centerPointX, centerPointY)
        delta = Point(deltaX, deltaY)
        return self.findLocation(centerPoint, delta, angle)

    def findLocation(self,centerPoint, delta, angle):
        # find location from center of object and apply rotation by given angle
        out = Point()
        out.x = int(centerPoint.x + delta.x  * math.cos(math.radians(angle)) - delta.y  * math.sin(math.radians(angle)))
        out.y = int(centerPoint.y + delta.x  * math.sin(math.radians(angle)) + delta.y  * math.cos(math.radians(angle)))
        return out

class Environment(object):
    def __init__(self, parkEndStartX = 400, parkEndStartY = 240, directionStart = 0 ):
        self.parkEndStart = Point()
        self.parkEndStart.x = parkEndStartX
        self.parkEndStart.y = parkEndStartY
        self.random = random
        self.parkEnd = Point()
        self.parkFront = Point()
        self.parkLenght = 50
        self.directionStart = 0
        self.direction = 30
        self.points = 0
        self.reset()

    def draw(self,surface):
        # center of the parking space
        pygame.draw.line(surface, (150,150,150), self.parkEnd.xy(), self.parkFront.xy())

        # circle to aroung front and back point
        pygame.draw.circle(surface, (100,100,100), self.parkEnd.xyI(),2,1)
        #pygame.draw.circle(surface, (100,0,100), self.parkFront.xyI(),30,1)

        # outlines of the parking space
        rl = graphicCalculations().findLocation(self.parkEnd,  Point(-20,-20),self.direction)
        rr = graphicCalculations().findLocation(self.parkEnd,  Point(-20, 20),self.direction)
        fr = graphicCalculations().findLocation(self.parkFront,Point( 20, 20),self.direction)
        fl = graphicCalculations().findLocation(self.parkFront,Point( 20,-20),self.direction)

        pygame.draw.polygon(surface, (150,150,150), (rl.xyI(),rr.xyI(),fr.xyI(),fl.xyI()), 1)

    def reset(self, rX = False, rY = False, rD = False):
        if rX:
            self.parkEnd.x = random.randrange(200,1000) #self.parkEndStart.x
        else:
            self.parkEnd.x = self.parkEndStart.x
        if rY:
            self.parkEnd.y = random.randrange(200,800) #self.parkEndStart.y
        else:
            self.parkEnd.y = self.parkEndStart.y
        if rD:
            self.direction = random.randrange(0,360) #self.directionStart
        else:
            self.direction = self.directionStart

        self.parkFront.translate(self.parkLenght, self.direction, self.parkEnd)

    def renewPark(self):
        self.parkEnd.random(100,540,100,220)
        self.direction = random.randrange(0,360)
        self.parkFront.translate(self.parkLenght, self.direction, self.parkEnd)

class Car(object):
    def __init__(self,startX = 100, startY = 140, directionStart = 0):
        self.rearAxisStart = Point()
        self.rearAxisStart.x = startX
        self.rearAxisStart.y = startY
        self.directionStart = directionStart
        self.direction = self.directionStart
        self.random = random
        self.carLenght = 50
        self.carWidth = 30
        self.wheelSize = 16
        self.rearAxis = Point()
        self.direction = 0 # angle of the car 0-360
        self.color = (255,0,0)
        self.turnAngle = 0 # turning angle 0-360
        self.speed = 0

        # point to turn around
        self.turnPoint = Point()
        self.frontAxis = Point()
        self.reset()
        #action 0 - stop, 1-forward, 2-backward, 3 forward + right, 4 forward + left, 5 - backward + rigth, 6 backward + left
        self.actSpeed = {
            0: 0,
            1: CAR_SPEED,
            2: -CAR_SPEED,
            3: CAR_SPEED,
            4: CAR_SPEED,
            5: -CAR_SPEED,
            6: -CAR_SPEED
        }
        self.actTurn = {
            0: 0,
            1: 0,
            2: 0,
            3: CAR_TURN,
            4: -CAR_TURN,
            5: CAR_TURN,
            6: -CAR_TURN
        }

    def act(self, action):
        self.speed = self.actSpeed[action]
        self.turnAngle = self.actTurn[action]
        #print("Action: ",action, "\tSpeed: ", self.speed, "\tTurn: ", self.turnAngle)

    def reset(self, rX = False, rY = False, rD = False):
        if rX:
            self.rearAxis.x = random.randrange(200,1000) #self.rearAxisStart.x
        else:
            self.rearAxis.x = self.rearAxisStart.x

        if rY:
            self.rearAxis.y = random.randrange(200,800) #self.rearAxisStart.y
        else:
            self.rearAxis.y = self.rearAxisStart.y

        if rD:
            self.direction = random.randrange(0,360) #self.directionStart
        else:
            self.direction = self.directionStart

        #update front axis
        self.frontAxis.translate(self.carLenght, self.direction, self.rearAxis)

    def move(self):

        #update front axis
        self.frontAxis.translate(self.carLenght, self.direction, self.rearAxis)

        if self.turnAngle != 0:
            turnRadius = self.carLenght / math.sin(math.radians(self.turnAngle))
            angleSpeed = ( self.speed / turnRadius )

            # calculate turn point
            self.turnPoint.x = self.frontAxis.x + self.carLenght * math.sin(math.radians(-self.direction-self.turnAngle)) / math.sin(math.radians(self.turnAngle))
            self.turnPoint.y = self.frontAxis.y + self.carLenght * math.cos(math.radians(-self.direction-self.turnAngle)) / math.sin(math.radians(self.turnAngle))

            # update direction
            self.direction += math.degrees(angleSpeed)
            if self.direction >= 360:
                self.direction -= 360
            if self.direction <=0:
                self.direction += 360;

            # rotate rear axis
            #self.rearAxis.rotate(self.turnPoint.x, self.turnPoint.y, self.angleSpeed)
            self.rearAxis.x = ((self.rearAxis.x - self.turnPoint.x) * math.cos(angleSpeed) - (self.rearAxis.y - self.turnPoint.y) * math.sin(angleSpeed) + self.turnPoint.x)
            self.rearAxis.y = ((self.rearAxis.x - self.turnPoint.x) * math.sin(angleSpeed) + (self.rearAxis.y - self.turnPoint.y) * math.cos(angleSpeed) + self.turnPoint.y)
        else:
            self.rearAxis.x += self.speed * math.cos(math.radians(self.direction))
            self.rearAxis.y += self.speed * math.sin(math.radians(self.direction))
            self.turnPoint.x = 0
            self.turnPoint.y = 0

    def findLocation(self,dx,dy):
        # find location from rearAxis centre, after appling direction
        outcome = Point()
        outcome.x = int(self.rearAxis.x + dx  * math.cos(math.radians(self.direction)) - dy  * math.sin(math.radians(self.direction)))
        outcome.y = int(self.rearAxis.y + dx  * math.sin(math.radians(self.direction)) + dy  * math.cos(math.radians(self.direction)))
        return outcome

    def drawLine(self,surface, x1,y1,x2,y2): # fro drawing a car (before rotation)
        pygame.draw.line(surface, self.color, self.findLocation(x1,y1).xy(),self.findLocation(x2,y2).xy())

    def draw(self, surface):
        #pygame.draw.circle(surface,(0,70,0), (150,100), 20)
        # draw main line
        self.drawLine(surface, 0, 0, self.carLenght, 0)

        #draw Axis
        self.drawLine(surface, 0, -self.carWidth/2, 0, self.carWidth/2)
        self.drawLine(surface, self.carLenght,  -self.carWidth/2, self.carLenght,  self.carWidth/2)

        #draw wheels
        #back
        self.drawLine(surface, -self.wheelSize/2, -self.carWidth/2, self.wheelSize/2, -self.carWidth/2)
        self.drawLine(surface, -self.wheelSize/2,  self.carWidth/2, self.wheelSize/2,  self.carWidth/2)
        #front
        #fl = Point(0,0)
        fl1 = Point( self.wheelSize/2,0)
        fl2 = Point(-self.wheelSize/2,0)
        fl1.rotate(0,0, self.turnAngle)
        fl2.rotate(0,0, self.turnAngle)
        self.drawLine(surface, self.carLenght + fl1.x, -self.carWidth/2 + fl1.y, self.carLenght+fl2.x, -self.carWidth/2 + fl2.y)
        self.drawLine(surface, self.carLenght + fl1.x,  self.carWidth/2 + fl1.y, self.carLenght+fl2.x,  self.carWidth/2 + fl2.y)

        # draw turn point (center of turning) and radius
        if self.turnPoint.x != 0 and self.turnPoint.y != 0:
            pygame.draw.circle(surface, (100,0,0), (int(self.turnPoint.x), int(self.turnPoint.y)), 2)
            pygame.draw.line(surface, (0,50,0), (int(self.frontAxis.x), int(self.frontAxis.y)), (int(self.turnPoint.x), int(self.turnPoint.y)))

if __name__ == '__main__':
    g = pyGame()
    g.run()


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

# In[1]:

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

# In[2]:

data=pd.read_csv("https://raw.githubusercontent.com/Mounika-Kajjam/Datasets/master/claimants.csv")
data.head()

# In[3]:

data.drop(['CASENUM'],axis=1,inplace=True)
data

# In[4]:

data.isnull().sum()

# In[5]:

def fill_na(col):
    col.fillna(col.value_counts().index[0],inplace=True)
    return col
data.apply(lambda col:fill_na(col))

# In[6]:

data.isnull().sum()

# In[7]:

X = data.iloc[:,1:]
X.head()

# In[8]:

y=data.ATTORNEY
y.head()

# In[9]:

from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.3,random_state=2)

# In[10]:

# Training Data
from  sklearn.linear_model import LogisticRegression
reg=LogisticRegression()
reg.fit(X_train,y_train)

# In[11]:

y_train_pred = reg.predict(X_train)
y_train_pred

# In[12]:

from sklearn.metrics import confusion_matrix,accuracy_score
conf = confusion_matrix(y_train,y_train_pred)
conf

# In[13]:

sns.heatmap(confusion_matrix(y_train,y_train_pred),annot=True,fmt='3.0f',annot_kws={'size':'20'})

# In[14]:

# Testing Data
from  sklearn.linear_model import LogisticRegression
reg=LogisticRegression()
reg.fit(X_test,y_test)

# In[15]:

y_test_pred = reg.predict(X_test)
y_test_pred

# In[16]:

from sklearn.metrics import confusion_matrix,accuracy_score
conf = confusion_matrix(y_test,y_test_pred)
conf

# In[17]:

sns.heatmap(confusion_matrix(y_test,y_test_pred),annot=True,fmt='3.0f',annot_kws={'size':'20'})

# In[18]:

from sklearn.metrics import classification_report
# Syntax: classification_report(actualValues,predictedValues)
print(classification_report(y_train,y_train_pred))
print(classification_report(y_test,y_test_pred))

# In[19]:

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
# Scaling for training data
scaled_X_train = pd.DataFrame(scaler.fit_transform(X_train),columns=X_train.columns)
scaled_X_train

# In[20]:

scaled_X_test = pd.DataFrame(scaler.fit_transform(X_test),columns=X_test.columns)
scaled_X_test

# In[21]:

from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
scores =[]
for k in range(1,20):
    knn_model = KNeighborsClassifier(n_neighbors=k)#,metric='euclidean')
    knn_model.fit(scaled_X_train,y_train)
    pred_test = knn_model.predict(scaled_X_test)
    scores.append(accuracy_score(y_test,pred_test))
scores

# In[22]:

plt.plot(range(1,20),scores,marker='o',markerfacecolor='r',linestyle='--')

# In[23]:

final_model = KNeighborsClassifier(n_neighbors=7,metric='euclidean')
final_model.fit(scaled_X_train,y_train)

# In[24]:

final_train_pred = final_model.predict(scaled_X_train)
final_train_pred

# In[25]:

from sklearn.metrics import confusion_matrix
sns.heatmap(confusion_matrix(y_train,final_train_pred),annot=True,fmt='d')

# In[27]:

print(classification_report(y_train,final_train_pred))

# In[28]:

# Prediction on Test Data
final_test_pred = final_model.predict(scaled_X_test) #y_test
final_test_pred

# In[29]:

sns.heatmap(confusion_matrix(y_test,final_test_pred),annot=True,fmt='d')

# In[30]:

print(classification_report(y_test,final_test_pred))

# In[31]:

y_test_prob=final_model.predict_proba(scaled_X_test)
y_test_prob=pd.DataFrame(y_test_prob)
y_test_prob

# In[32]:

# Logistic Regression
y_test_prob1=reg.predict_proba(X_test)
y_test_prob1=pd.DataFrame(y_test_prob1)
y_test_prob1

# In[33]:

y_test

# In[34]:

from sklearn.metrics import roc_auc_score,roc_curve
m_prob = final_model.predict_proba(scaled_X_test)[:,1]
#m_prob
fpr,tpr,threshold = roc_curve(y_test,m_prob,pos_label=1)
print(fpr)
print(tpr)
print(threshold)
print(pd.DataFrame(threshold))

# In[35]:

# Logistic Regression
m_prob1 = reg.predict_proba(scaled_X_test)[:,1]
fpr1,tpr1,threshold1 = roc_curve(y_test,m_prob1,pos_label=1)

# In[36]:

plt.plot(fpr,tpr)

# In[37]:

# Logistic Regression
plt.plot(fpr1,tpr1)

# In[38]:

roc_auc_score(y_test,m_prob)

# In[39]:

# Logistic Regression
roc_auc_score(y_test,m_prob1)

# In[ ]:


from direct.showbase.ShowBase import ShowBase   # Para usar panda
from direct.actor.Actor import Actor
from direct.gui.OnscreenImage import OnscreenImage
from direct.gui.OnscreenText import OnscreenText, Point3, Vec3
from direct.interval.MetaInterval import Parallel, Sequence
from panda3d.core import PandaNode, NodePath, Camera, TextNode
import sys

# Función para añadir Instrucciones a la pantala
def addInstructions(pos, msg):
    return OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), scale=.05,
                        shadow=(0, 0, 0, 1), parent=base.a2dTopLeft,
                        pos=(0.08, -pos - 0.04), align=TextNode.ALeft)

class Parcial(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        self.disableMouse()

        # Instrucciones en pantalla
        self.Salir = addInstructions(.06, "[ESC]: Para Salir")
        self.Camara = addInstructions(.12, "[A]: Para Mover Cabeza")
        self.CabezaL = addInstructions(.18, "[S]: Para Mover Brazo Derecho")
        self.CabezaL = addInstructions(.24, "[D]: Para Mover Brazo Izquierdo")
        self.CaderaL = addInstructions(.30, "[F]: Para Mover Cadera")
        self.CaderaL = addInstructions(.36, "[G]: Para Mover Tronco")
        self.CaderaL = addInstructions(.42, "[H]: Para Girar")
        self.CaderaL = addInstructions(.48, "[Z]: Cabeza Cadera")
        self.CaderaL = addInstructions(.54, "[X]: Brazos")
        self.CaderaL = addInstructions(.60, "[C]: Giro Tronco")
        self.CaderaL = addInstructions(.66, "[V]: Todos a la vez")

        # Carga de un Actor
        self.Ralph = Actor("models/ralph",
                                {"run": "models/ralph-run",
                                 "walk": "models/ralph-walk"})

        self.Ralph.setScale(.5, .5, .5)
        self.Ralph.setPos(0, 10, -1)        #(x   -IZQ  +DER   ,y   PROFUNDIDAD  ,z   +ARRIBA -ABAJO   )
        self.Ralph.reparentTo(self.render)

        # Giro de ralph
        self.GiroTotal = self.Ralph.hprInterval(1.5, Point3(0,359,0))

        # Declaración de partes del cuerpo
        self.Cabeza = self.Ralph.controlJoint(None, 'modelRoot', 'Neck')
        self.BrazoDerecho = self.Ralph.controlJoint(None, 'modelRoot', 'RightShoulder')
        self.BrazoIzquierdo = self.Ralph.controlJoint(None, 'modelRoot', 'LeftShoulder')
        self.CaderaDerecha = self.Ralph.controlJoint(None, 'modelRoot', 'RightHip')
        self.CaderaIzquierda = self.Ralph.controlJoint(None, 'modelRoot', 'LeftHip')
        self.Tronco = self.Ralph.controlJoint(None, 'modelRoot', 'Chest')

        # Movimiento de Cabeza
        self.CabezaAbajo = self.Cabeza.hprInterval(0.5, Point3(0, 0, 0))
        self.CabezaArriba = self.Cabeza.hprInterval(0.5, Point3(20, 0, 0))

        # Movimientos de brazo derecho
        self.BrazoDerechoAbajo = self.BrazoDerecho.hprInterval(1.0, Point3(72.2059, 106.186, -45))
        self.BrazoDerechoArriba = self.BrazoDerecho.hprInterval(1.0, Point3(72.2059, 76.186, 6.02231))

        # Movimientos de brazo izquierdo
        self.BrazoIzquierdoAbajo = self.BrazoIzquierdo.hprInterval(1.0, Point3(160.1401, -22.1706, 6.55722))
        self.BrazoIzquierdoArriba = self.BrazoIzquierdo.hprInterval(1.0, Point3(80.1401, -52.1706, 6.55722))

        # Movimientos de cadera derecha
        self.CaderaDerechaDerecha = self.CaderaDerecha.hprInterval(0.5, Point3(4.9762, 0, 120))
        self.CaderaDerechaNormal = self.CaderaDerecha.hprInterval(0.5, Point3(4.9762, 0, 90))

        # Movimientos de cadera derecha
        self.CaderaIzquierdaIzquierda = self.CaderaIzquierda.hprInterval(0.5, Point3(5.02118, -0.862563, 62.9857))
        self.CaderaIzquierdaNormal = self.CaderaIzquierda.hprInterval(0.5, Point3(5.02118, -0.862563, 92.9857))

        # Movimientos del tronco
        #self.Tronco.setHpr(0, 50, 0)
        self.TroncoIzquierda = self.Tronco.hprInterval(0.5, Point3(0, 50, 0))
        self.TroncoDerecha = self.Tronco.hprInterval(0.5, Point3(0, -50, 0))
        self.TroncoNormal = self.Tronco.hprInterval(0.5, Point3(0, 0, 0))

        # Secuencias de movimientos
        self.MoverCabeza = Sequence(self.CabezaArriba, self.CabezaAbajo)
        self.MoverBrazoDerecho = Sequence(self.BrazoDerechoAbajo, self.BrazoDerechoArriba)
        self.MoverBrazoIzquierdo = Sequence(self.BrazoIzquierdoAbajo, self.BrazoIzquierdoArriba)
        self.MoverCaderaDerechaIzquierda = Sequence(self.CaderaDerechaDerecha, self.CaderaDerechaNormal,
                                                    self.CaderaIzquierdaIzquierda, self.CaderaIzquierdaNormal)
        self.MoverTronco = Sequence( self.TroncoDerecha, self.TroncoNormal, self.TroncoIzquierda)
        self.Giro = Sequence(self.GiroTotal)

        # Paralelos
        self.CaderaCabeza = Parallel(self.MoverCabeza, self.MoverCaderaDerechaIzquierda)
        self.Brazos = Parallel(self.MoverBrazoDerecho, self.MoverBrazoIzquierdo)
        self.GiroTronco = Parallel(self.Giro, self.MoverTronco)
        self.Todos = Parallel(self.MoverCabeza, self.MoverCaderaDerechaIzquierda, self.MoverBrazoDerecho, self.MoverBrazoIzquierdo, self.Giro, self.MoverTronco)

        self.accept("escape", sys.exit)
        self.accept("a", self.eCabeza)
        self.accept("s", self.eBrazoDerecho)
        self.accept("d", self.eBrazoIzquierdo)
        self.accept("f", self.eCadera)
        self.accept("g", self.eTronco)
        self.accept("h", self.eGiro)
        self.accept("z", self.eCadCab)
        self.accept("x", self.eBrazos)
        self.accept("c", self.eGiroT)
        self.accept("v", self.eTodos)

    def eCabeza(self):
        self.MoverCabeza.start()

    def eBrazoDerecho(self):
        self.MoverBrazoDerecho.start()

    def eBrazoIzquierdo(self):
        self.MoverBrazoIzquierdo.start()

    def eCadera(self):
        self.MoverCaderaDerechaIzquierda.start()

    def eTronco(self):
        self.MoverTronco.start()

    def eGiro(self):
        self.Giro.start()

    def eCadCab(self):
        self.CaderaCabeza.start()

    def eBrazos(self):
        self.Brazos.start()

    def eGiroT(self):
        self.GiroTronco.start()

    def eTodos(self):
        self.Todos.loop()

app = Parcial()
app.run()


""" Advisory exclusive DAV-style locks for content objects.

When a resource is locked, it is presumed that its SDI UI will display a
warning to users who do not hold the lock.  The locking service can also be
used by add-ons such as DAV implementations.
"""

import datetime
import uuid
import pytz

from zope.interface import implementer

from persistent import Persistent

import colander
import deform.widget

from pyramid.location import lineage
from pyramid.security import has_permission
from pyramid.threadlocal import get_current_registry
from pyramid.traversal import resource_path

from substanced.interfaces import (
    ILock,
    ILockService,
    WriteLock,
    UserToLock,
    )
from substanced.content import (
    content,
    service
    )
from substanced.folder import (
    _AutoNamingFolder,
    Folder,
    )
from substanced.objectmap import (
    reference_target_property,
    reference_targetid_property,
    )
from substanced.property import PropertySheet
from substanced.util import (
    find_objectmap,
    find_service,
    get_oid,
    )
from substanced.schema import Schema
from substanced._compat import INT_TYPES

class LockingError(Exception):
    def __init__(self, lock):
        self.lock = lock

class LockError(LockingError):
    """ Raised when a lock cannot be created due to a conflicting lock.

    Instances of this class have a ``lock`` attribute which is a
    :class:`substanced.locking.Lock` object, representing the conflicting
    lock.
    """

class UnlockError(LockingError):
    """ Raised when a lock cannot be removed

    This may be because the owner suplied in the unlock request does not
    match the owner of the lock, or becaues the lock no longer exists.

    Instances of this class have a ``lock`` attribute which is a
    :class:`substanced.locking.Lock` object, representing the conflicting lock,
    or ``None`` if there was no lock to unlock.
    """

def now():
    return datetime.datetime.utcnow().replace(tzinfo=pytz.UTC)

class LockOwnerSchema(colander.SchemaNode):
    title = 'Owner'
    schema_type = colander.Int

    @property
    def widget(self):
        context = self.bindings['context']
        principals = find_service(context, 'principals')
        if principals is None:
            values = [] # fbo dump/load
        else:
            values = [(get_oid(group), name) for name, group in
                      principals['users'].items()]
        return deform.widget.Select2Widget(values=values)

    def validator(self, node, value):
        context = self.bindings['context']
        objectmap = find_objectmap(context)
        if not value in objectmap.objectid_to_path:
            raise colander.Invalid(node, 'Not a valid userid %r' % value)

class LockResourceSchema(colander.SchemaNode):
    title = 'Resource Path'
    schema_type = colander.String
    widget = deform.widget.TextInputWidget()
    missing = colander.null

    def preparer(self, value):
        context = self.bindings['context']
        request = self.bindings['request']
        objectmap = find_objectmap(context)
        if value is colander.null:
            return colander.null
        try:
            resource = objectmap.object_for(tuple(value.split('/')))
        except ValueError:
            return None
        if not has_permission('sdi.lock', resource, request):
            return False
        return resource

    def validator(self, node, value):
        if value is None:
            raise colander.Invalid(node, 'Resource not found')
        if value is False:
            raise colander.Invalid(
                node,
                'You do not have permission to lock this resource'
                )

class LockSchema(Schema):
    ownerid = LockOwnerSchema()
    timeout = colander.SchemaNode(
        colander.Int(),
        validator=colander.Range(0),
        default=3600,
        title='Timeout (secs)',
        )
    infinite = colander.SchemaNode(
        colander.Boolean(),
        default=False,
        missing=False,
        title='Infinite?',
        description='Locks all descendants',
        )
    last_refresh = colander.SchemaNode(
        colander.DateTime(),
        title='Last Refresh',
        default=now(),
        )
    comment = colander.SchemaNode(
        colander.String(),
        validator=colander.Length(max=255),
        missing=None,
        title='Comment',
        )
    resource = LockResourceSchema()

class LockPropertySheet(PropertySheet):
    schema = LockSchema()

    def get(self):
        result = PropertySheet.get(self)
        resource = result.get('resource')
        if resource is None:
            resource = colander.null
        else:
            resource = resource_path(resource)
        result['resource'] = resource
        return result

    def set(self, appstruct):
        resource = appstruct.get('resource')
        if resource is colander.null:
            appstruct['resource'] = None
        return PropertySheet.set(self, appstruct)

@content(
    'Lock',
    icon='glyphicon glyphicon-lock',
    add_view='add_lock',
    )
@implementer(ILock)
class Lock(Persistent):
    """ A persistent object representing a lock.
    """
    owner = reference_target_property(UserToLock)
    resource = reference_target_property(WriteLock)
    ownerid = reference_targetid_property(UserToLock)
    resourceid = reference_targetid_property(WriteLock)

    def __init__(self,
                 infinite=False,
                 timeout=3600,
                 comment=None,
                 last_refresh=None,
                ):
        self.timeout = timeout
        self.comment=comment
        self.infinite = infinite
        # last_refresh must be a datetime.datetime object with a UTC tzinfo,
        # if provided
        if last_refresh is None:
            last_refresh = now()
        self.last_refresh = last_refresh

    def refresh(self, timeout=None, when=None): # "when" is for testing
        """ Refresh the lock.

        If the timeout is not None, set the timeout for this lock too.
        """
        if timeout is not None:
            self.timeout = timeout
        if when is None: # pragma: no cover
            when = now()
        self.last_refresh = when

    def expires(self):
        """ Return the future datetime at which this lock will expire.

        For invalid locks, the returned value indicates the point in the past
        at which the lock expired.
        """
        if self.timeout is None:
            return None
        return self.last_refresh + datetime.timedelta(seconds=self.timeout)

    def is_valid(self, when=None):
        """ Return True if the lock has not expired and its resource exists.
        """
        objectmap = find_objectmap(self)
        if objectmap is not None:
            # might be None if we're not yet seated
            if self.resourceid is None:
                return False
        if when is None: # pragma: no cover
            when = now()
        expires = self.expires()
        if expires is None:
            return True
        return expires >= when

    @property
    def depth(self):
        return 'infinity' if self.infinite else '0'

    def commit_suicide(self):
        """ Remove this lock from the lock service.
        """
        del self.__parent__[self.__name__]

@service(
    'Lock Service',
    icon='glyphicon glyphicon-briefcase',
    service_name='locks',
    add_view='add_lock_service',
    )
@implementer(ILockService)
class LockService(Folder, _AutoNamingFolder):
    __sdi_addable__ = ('Lock',)

    def next_name(self, subobject):
        lock_id = str(uuid.uuid4())
        return lock_id

    def _get_ownerid(self, owner_or_ownerid):
        ownerid = get_oid(owner_or_ownerid, None)
        if ownerid is None:
            ownerid = owner_or_ownerid
        if not isinstance(ownerid, INT_TYPES):
            raise ValueError(
                'Bad value for owner_or_ownerid %r' % owner_or_ownerid
                )
        return ownerid

    def borrow_lock(
        self,
        resource,
        owner_or_ownerid,
        locktype=WriteLock,
        ):
        """ Search for an existing, avlid lock on resource.

        If not found, return None.

        If owned by 'owner_or_ownerid', return it.

        Otherwise, raise LockError.
        """
        objectmap = find_objectmap(self)
        ownerid = self._get_ownerid(owner_or_ownerid)
        locks = objectmap.targets(resource, locktype)
        for lock in locks:
            if lock.is_valid():
                if lock.ownerid == ownerid:
                    return lock
                else:
                    raise LockError(lock)
            else:
                lock.commit_suicide()
                break

    def lock(
        self,
        resource,
        owner_or_ownerid,
        timeout=None,
        comment=None,
        locktype=WriteLock,
        infinite=False,
        ):
        # NB: callers should ensure that the user has 'sdi.lock' permission
        # on the resource before calling

        lock = self.borrow_lock(resource, owner_or_ownerid, locktype)
        if lock is not None:
            when = now()
            lock.refresh(timeout, when)
            return lock

        registry = get_current_registry()
        lock = registry.content.create('Lock',
                                       )
        self.add_next(lock) # NB: must add before setting ownerid/resource
        lock.ownerid = self._get_ownerid(owner_or_ownerid)
        lock.resource = resource
        lock.timeout = timeout
        lock.comment = comment
        lock.infinite = infinite
        return lock

    def unlock(
        self,
        resource,
        owner_or_ownerid,
        locktype=WriteLock,
        ):

        # NB: callers should ensure that the user has 'sdi.lock' permission
        # on the resource before calling
        objectmap = find_objectmap(self)
        ownerid = self._get_ownerid(owner_or_ownerid)
        locks = objectmap.targets(resource, locktype)
        lock = None
        for lock in locks:
            if not lock.is_valid():
                lock.commit_suicide()
            elif lock.ownerid == ownerid:
                lock.commit_suicide()
                break
        else: # nobreak
            raise UnlockError(lock)

    def unlock_token(
        self,
        token,
        owner_or_ownerid,
        ):

        # NB: callers should ensure that the user has 'sdi.lock' permission
        # on the resource before calling
        ownerid = self._get_ownerid(owner_or_ownerid)
        lock = self.get(token)
        if lock is None:
            raise UnlockError(None)
        if not lock.is_valid():
            lock.commit_suicide()
            raise UnlockError(None)
        if lock.ownerid != ownerid:
            raise UnlockError(lock)
        lock.commit_suicide()

    def discover(self, resource,
                 include_invalid=False,
                 include_lineage=True,
                 locktype=WriteLock):
        objectmap = find_objectmap(self)
        valid = []
        if include_lineage:
            resources = lineage(resource)
        else:
            resources = [resource]
        for res in resources:
            locks = objectmap.targets(res, locktype)
            for lock in locks:
                if include_invalid or lock.is_valid():
                    valid.append(lock)
        return valid

def _get_lock_service(resource):
    locks = find_service(resource, 'locks')
    if locks is None:
        raise ValueError('No lock service in lineage')
    return locks

def lock_resource(
    resource,
    owner_or_ownerid,
    timeout=None,
    comment=None,
    locktype=WriteLock,
    infinite=False,
    ):
    """ Lock a resource using the lock service.

    If the resource is already locked by the owner supplied as
    owner_or_ownerid, refresh the lock using ``timeout``.

    If the resource is not already locked by another user, create a new lock
    with the given values.

    If the resource is already locked by a different user, raise a
    :class:`substanced.locking.LockError`

    If a Lock Service does not already exist in the lineage, a
    :exc:`ValueError` will be raised.

    .. warning::

       Callers should assert that the owner has the ``sdi.lock`` permission
       against the resource before calling this function to ensure that a user
       can't lock a resource he is not permitted to.

    """
    locks = _get_lock_service(resource)
    return locks.lock(
        resource,
        owner_or_ownerid,
        timeout=timeout,
        comment=comment,
        locktype=locktype,
        infinite=infinite,
        )

def could_lock_resource(
    resource,
    owner_or_ownerid,
    locktype=WriteLock,
    ):
    """ Check that a given owner could lock a resource using the lock service.

    If the resource is already locked by the owner supplied as
    owner_or_ownerid, calling this function will *not* refresh the lock.

    If the resource is not already locked by another user, calling this
    function will *not* create a new lock.

    If the resource is already locked by a different user, raise a
    :class:`substanced.locking.LockError`.

    If a Lock Service does not already exist in the lineage, a
    :exc:`ValueError` will be raised.

    .. warning::

       Callers should assert that the owner has the ``sdi.lock`` permission
       against the resource before calling this function to ensure that a user
       can't lock a resource he is not permitted to.
    """
    locks = _get_lock_service(resource)
    locks.borrow_lock(
        resource,
        owner_or_ownerid,
        locktype=locktype,
        ) # may raise LockError
    return True

def unlock_resource(
    resource,
    owner_or_ownerid,
    locktype=WriteLock,
    ):
    """ Unlock a resource using the lock service.

    If the resource is already locked by a user other than the owner supplied
    as ``owner_or_ownerid`` or the resource isn't already locked with this
    lock type, raise a :class:`substanced.locking.UnlockError` exception.

    Otherwise, remove the lock.

    If a Lock Service does not already exist in the lineage, a
    :exc:`ValueError` will be raised.

        .. warning::

           Callers should assert that the owner has the ``sdi.lock`` permission
           against the resource before calling this function to ensure that a
           user can't lock a resource he is not permitted to.

    """

    locks = _get_lock_service(resource)
    return locks.unlock(
        resource,
        owner_or_ownerid,
        locktype=locktype
        )

def unlock_token(
    resource,
    token,
    owner_or_ownerid,
    ):
    """ Remove a lock from the lock service based on its token.

    If the lock is owned by a user user other than the owner supplied as
    ``owner_or_ownerid`` or ``token`` doesn't identfiy a valid lock,
    raise a :class:`substanced.locking.UnlockError` exception.

    Otherwise remove the lock indicated by ``token``.

    If a Lock Service does not already exist in the lineage, a
    :exc:`ValueError` will be raised.

        .. warning::

           Callers should assert that the owner has the ``sdi.lock`` permission
           against the resource before calling this function to ensure that a
           user can't lock a resource he is not permitted to.

    """

    locks = _get_lock_service(resource)
    return locks.unlock_token(
        token,
        owner_or_ownerid,
        )

def discover_resource_locks(
    resource,
    include_invalid=False,
    include_lineage=True,
    locktype=WriteLock,
    ):
    """ Return locks related to ``resource`` for the given ``locktype``.

    Return a sequence of :class:`substanced.locking.Lock` objects.

    By default, only valid locks are returned.

    Invalid locks for the resource may exist, but they are not
    returned unless ``include_invalid`` is ``True``.

    Under normal circumstances, the length of the sequence returned will be
    either 0 (if there are no locks) or 1 (if there is any lock).

    In some special circumstances, however, when the
    :class:`substanced.locking.lock_resource` API is not used to create locks,
    there may be more than one lock of the same type related to a resource.
    """
    locks = _get_lock_service(resource)
    return locks.discover(
        resource,
        include_invalid=include_invalid,
        include_lineage=include_lineage,
        locktype=locktype
        )

def includeme(config): # pragma: no cover
    config.add_permission('sdi.lock')
    config.add_propertysheet('', LockPropertySheet, ILock)
    config.include('.views')
    config.include('.evolve')


from __future__ import annotations

import uuid

from aiogram import Router
from aiogram.types import CallbackQuery
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from likeinterface import Interface
from likeinterface.exceptions import LikeInterfaceError
from likeinterface.methods import AddGame
from redis.asyncio.client import Redis

from callback_data import CreateGameCallbackData
from enums import Game
from filters import As
from keyboards import join_inline_keyboard_builder
from logger import logger
from schemas import Settings

router = Router()

async def create_texas_holdem_poker(
    callback_query: CallbackQuery,
    redis: Redis,
    interface: Interface,
    settings: Settings,
    scheduler: AsyncIOScheduler,
) -> None:
    access = uuid.uuid4().hex
    redis_callback_data_key = uuid.uuid4().hex

    await redis.set(name=redis_callback_data_key, value=access)

    try:
        await interface.request(
            method=AddGame(
                access=access,
                sb_bet=settings.small_blind,
                bb_bet=settings.small_blind * 2,
                bb_mult=settings.big_blind_multiplication,
                min_raise=settings.small_blind * 2,
            ),
        )
    except LikeInterfaceError as e:
        logger.exception(e)

        return await callback_query.answer(text="Failed to create game")

    await callback_query.bot.edit_message_text(
        inline_message_id=callback_query.inline_message_id,
        text=f"Texas Holdem Poker\n\n"
        f"Stack: {settings.small_blind * 2 * settings.big_blind_multiplication}\n\n"
        f"SB/BB: {settings.small_blind}/{settings.small_blind * 2}",
        reply_markup=join_inline_keyboard_builder(
            bot=callback_query.bot,
            redis_callback_data_key=redis_callback_data_key,
            game=Game.TEXAS_HOLDEM_POKER.value,
        ).as_markup(),
    )
    return None

@router.callback_query(
    CreateGameCallbackData.filter(),
    As(Settings, "settings"),
)
async def create_game_handler(
    callback_query: CallbackQuery,
    callback_data: CreateGameCallbackData,
    redis: Redis,
    interface: Interface,
    settings: Settings,
    scheduler: AsyncIOScheduler,
) -> None:
    if callback_data.game == Game.TEXAS_HOLDEM_POKER.value:
        return await create_texas_holdem_poker(
            callback_query=callback_query,
            redis=redis,
            interface=interface,
            settings=settings,
            scheduler=scheduler,
        )

    return await callback_query.answer(text="Sorry, Game Not Supported Yet!")


import datetime as dt
import pytest
from .config import OUTCOMES_ATTR
from .common import (
    PytestExperimentsError,
    PytestOutcome,
    PytestReportPhase,
    ExperimentOutcome,
)
from .store import StorageManager, ExperimentModel

class Experiment:
    def __init__(self, request: pytest.FixtureRequest) -> None:
        self.context = request
        self.store = StorageManager(experiments_db_uri(self.context))
        self.created_at = dt.datetime.utcnow()
        self.completed_at = None
        self.outcome = ExperimentOutcome.not_reported
        self.data = {}

    def record(self, **kwargs):
        """Record data about this experiment.

        As this data will be serialized as JSON, keys *must* be strings. This
        is enforced by the stricter requirement that keys be valid python
        identifiers.
        """
        self.data.update(**kwargs)

    @property
    def test_fn(self) -> pytest.Function:
        """The test function."""
        return self.context.node

    @property
    def name(self) -> str:
        """The full qualified name of the test."""
        return self.test_fn.nodeid

    @property
    def parameters(self) -> dict:
        """The input parameters of the test.

        This will contain the closure of inputs supplied to the test,
        some of which we do not care about.
        """
        return dict(
            filter(self._ignore_funcargs_items, self.test_fn.funcargs.items())
        )

    def _ignore_funcargs_items(self, item) -> bool:
        """Ignores some funcarg items that we do not care about."""
        _, v = item
        if v is self:
            return False
        if isinstance(v, pytest.FixtureRequest):
            return False
        return True

    def get_reports(self) -> dict:
        """Returns the reports dict if it exists.

        The reports dict is populated by our custom hook and is *only*
        available after the test has run.
        """
        reports = getattr(self.context.node, OUTCOMES_ATTR, None)
        if reports is None:
            raise ExperimentError(
                "Could not find a `reports` attribute. "
                "This method may only be called after the test has run."
            )
        return reports

    def post_process(self):
        """Inspect the context for test outcome.

        The method may only be run *after* the test has completed.
        """
        self.completed_at = dt.datetime.utcnow()
        self.outcome = to_experiment_outcome(self.get_reports())

    def to_model(self) -> ExperimentModel:
        """Render the experiment into its database model."""
        return ExperimentModel(
            name=self.name,
            start_time=self.created_at,
            end_time=self.completed_at,
            outcome=self.outcome.name,
            parameters=self.parameters,
            data=self.data,
        )

    def save(self):
        """Save this experiment to the database."""
        self.store.record_experiment(self.to_model())

    def finish(self):
        """Post process the experiment and save to the database."""
        self.post_process()
        self.save()

def experiments_db_uri(request: pytest.FixtureRequest) -> str:
    """Retrieve the URI of the database used to store experiment results."""
    return request.config.option.experiments_database_uri

def to_experiment_outcome(reports: dict) -> ExperimentOutcome:
    """Return an ExperimentOutcome from the pytest reports"""
    if reports[PytestReportPhase.setup] is PytestOutcome.failed:
        return ExperimentOutcome.error
    test_outcome = reports.get(PytestReportPhase.call)
    if test_outcome is None:
        return ExperimentOutcome.not_reported
    return ExperimentOutcome[test_outcome.name]

class ExperimentError(PytestExperimentsError):
    pass


"""empty message

Revision ID: 16897dd3b599
Revises: 43001c492ce3
Create Date: 2017-11-10 20:58:53.972981

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '16897dd3b599'
down_revision = '43001c492ce3'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('groups', sa.Column('short_name', sa.String(length=128), nullable=True))
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_column('groups', 'short_name')
    # ### end Alembic commands ###


import numpy as np
from sklearn.metrics import ndcg_score
from src.constants import lm

def hit_att(ascore, labels, ps = [100, 150]):
	res = {}
	for p in ps:
		hit_score = []
		for i in range(ascore.shape[0]):
			a, l = ascore[i], labels[i]
			a, l = np.argsort(a).tolist()[::-1], set(np.where(l == 1)[0])
			if l:
				size = round(p * len(l) / 100)
				a_p = set(a[:size])
				intersect = a_p.intersection(l)
				hit = len(intersect) / len(l)
				hit_score.append(hit)
		res[f'Hit@{p}%'] = np.mean(hit_score)
	return res

def ndcg(ascore, labels, ps = [100, 150]):
	res = {}
	for p in ps:
		ndcg_scores = []
		for i in range(ascore.shape[0]):
			a, l = ascore[i], labels[i]
			labs = list(np.where(l == 1)[0])
			if labs:
				k_p = round(p * len(labs) / 100)
				try:
					hit = ndcg_score(l.reshape(1, -1), a.reshape(1, -1), k = k_p)
				except Exception as e:
					return {}
				ndcg_scores.append(hit)
		res[f'NDCG@{p}%'] = np.mean(ndcg_scores)
	return res


import boto3

# getting the dynamodb resource
dynamodb = boto3.resource('dynamodb')

table_name = 'songs'
# resource representing a dynamodb table
table = dynamodb.Table(table_name)

song_id = '5'

def update_item():
    print('Updating item id = {} from the dB\n'.format(song_id))

    # get_item(...)
    # get the item from the table.
    response = table.get_item(
        Key={
            'song_id': song_id
        }
    )

    if 'Item' in response:
        # update_item(...)
        # update an item from the table based on the key.
        response = table.update_item(
            Key={
                'song_id': song_id
            },
            UpdateExpression="set artist = :g",
            ExpressionAttributeValues={
                ':g': "Butterfly"
            }
        )

        if response['ResponseMetadata']['HTTPStatusCode'] == 200:
            print('Item updated with status code = {} OK'.format(response['ResponseMetadata']['HTTPStatusCode']))
        else:
            print('Some error occurred while updating the item from the dB')
    else:
        print('Item id = {} not found in the dB'.format(song_id))

update_item()


# import time, This file/module read the user file

import datetime  # Import all?
filename = 'DefaultUser.txt'

def create_attention_lists(userphoneandmail):
    users = []  # List [
    phones = []  # List of alarms
    status_phones = []   #  List of Status :
    to_mail_list = []   #  List of mail
    status_mail = []   #  Mail status
    user_log = [] # Build list of string to report, Each warning and error should be a line.
      # Or use a file reference and add new string? One log for each start session.
      # Possible to copy a file with open session with contents included?
      # HeaderOnTable= "User" "/t" "Acesslevel" "/t" "Celluar phones" "/t" "Voice phone" "/t" "Mail adress" "/t"
      # "Created" "/t" "Valid until" "/t" "User password" Vände jag på / \?
    logstring = ""
    start = "StartOfTable"
      # EndOfF *undantag*
    try:
        user_file = open(userphoneandmail,'r') # The reference to file? Not the  name!?
        row = 0
        for line in user_file:
            row = row+1
            if line.strip() == (start): # Sort out where the table starts
                found_table_start = True
                break # Jump to read line. Header infromation is not used from text file
            else:
                found_table_start=False # Use false to create an error log if wrong file o
                #  user_log.append("Didn't find file ", userphoneandmail)
                # logstring = logstring +"Didn't find file ", userphoneandmail)
        for line in user_file:
            users.append(line)  #Skip this line?
            row = row+1
            line = line.strip()  #tar bort radslut?
            try:
                acess_level, user_phone,e_mail,valid_until = line.split (',') # The pattern must match. replace with try?
                # Should be  possible to ignore if more fields are added? Check how CSV modules work
                #What happens if blankrow are added?
                try :
                    Year,Month,Day =valid_until.split ('-') # If format doesn't match on the string it assume there should be no limit
                    Year= int(Year) # Convert to integer to use in date function
                    Month= int(Month)
                    Day= int(Day)
                    AcessUntil = datetime.datetime (Year,Month,Day)
                    CurrentTime =datetime.datetime.now ()
                    if AcessUntil > CurrentTime: # Don't add guest user which date have passed to  the list
                        use_line =True
                    else:
                        use_line =False # The user that have pass date should be removed from list
                except ValueError:
                    use_line = True
                if use_line : # Create list of phone and mail to inform with alarm as bugler or  fire
                    phone_check = list(user_phone)
                    phone_number_length = len (user_phone)
                    pc2 = phone_check[:1]  # 0 didn't work contain 0 or + , (Capital letter? ignored for the  moment)
                    # print (pc2)
                    pc1 = ''.join(phone_check[1:])
                    # print (pc1) Skippa felsökning lägg det på format vid inmatning stora bokstäver. #*- finns också
                    phones.append (user_phone) # phone number with capital letter exist in US and UK.
                    # No check for insane  number yet
                    use_mail = e_mail.find ('@') > 0  # Do a simple check that @ is included.
                                                    # Use variabel since bad mail can be added in both mail list
                    if use_mail:
                        to_mail_list.append(e_mail) # No sanity check on mail yet. Wiki have a defintion of unvalid e-mail adress
                    else:
                        mailwithnosnabel = 'Time: {:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now())+'Bad mail in line'+str(row)+" "+str(line)+'in file '+str(userphoneandmail)
                        user_log.append(mailwithnosnabel) #Varför ger inte denna rad fel?
                    if acess_level== '3': # Create  list of  phone  for  status  or  just larm (Enum with string?)
                        status_phones.append (user_phone) # Some phone numbee will be in two  list
                        if use_mail:
                            status_mail.append (e_mail)  # Status mail adress is also larm no need to add twice
            except ValueError:
                # user_log.append("Row ",row," ",line,'in file ',userphoneandmail," bad format")
                add_this_string = 'Time: {:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now())+"row "+str(row)+str(line)+" in file "+str(userphoneandmail)+" bad format(empty value error?)"
                user_log.append(add_this_string)
                # 'in file ', user_file, " bad format")
                # print ("Row ",row," ",line,'in file ',user_file," bad format")
            except TypeError:
                badline = 'Time: {:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now())+"row "+str(row)+": "+str(line)+" in file "+str(userphoneandmail)
                #  print ('Timestamp: {:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now()))
                user_log.append (badline)
        user_file.close ()
        if found_table_start :
            phones = set (phones) # Delete  phone used twice. Set changes the order but is not important
            to_mail_list =set (to_mail_list)
            status_mail = set (status_mail)
            status_phones = set (status_phones)
        else:
            missingstartrow = 'Time: {:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now())+" Didn't found "+str(start)+' in file '+str(userphoneandmail)
            user_log.append (missingstartrow)#Hur hittar jag path?
            # Och hur ser den ut i byggd miljö?
    except FileNotFoundError:
        user_log.append ("Didn't find file ",userphoneandmail)

    # print (user_log)
    return phones, to_mail_list,status_phones, status_mail, user_log

AlarmPhones,AlarmMail,StatusP,StatusM,Log = create_attention_lists(filename) # Order from defs, Create new list drop error/warninng

print (Log)
LarmMessages = (AlarmMail, AlarmPhones) #create new tupples of phone an mail to use depending on use case to different user
StatusMessages = (StatusM, StatusP)
print (LarmMessages),
print (StatusMessages)
# print (create_attention_lists(filename))


""" Counter를 매 루프마다 생성하는 것은 매우 비효율적이다.
편의성을 위해 Counter(a) - Counter(b)와 같은 형태로 연산을 수행하려면
각각의 객체를 생성해야하는데 시간초과를 할 가능성이 높다.

"""
from collections import Counter

def solution(gems):
    kinds = len(set(gems))
    n = len(gems)
    left = right = 0
    answer = [-1, 1_000_000]
    cache = Counter([gems[left]])
    while left <= right and right < n:
        if len(cache) < kinds:
            right += 1
            if right == n:
                break
            cache[gems[right]] += 1

        elif len(cache) == kinds:
            if answer[1] - answer[0] > right - left:
                answer = [left + 1, right + 1]
            cache[gems[left]] -= 1
            if cache[gems[left]] <= 0:
                del cache[gems[left]]
            left += 1
    return answer

print(solution(["DIA", "RUBY", "RUBY", "DIA", "DIA", "EMERALD", "SAPPHIRE", "DIA"]))


from apibase import AbstractTxnHost, MakeArgs
import asyncio
import logging
import zmq

logger = logging.getLogger('apipeer.hardhash')

#----------------------------------------------------------------#
# ServiceA
#----------------------------------------------------------------#
class ServiceA(AbstractTxnHost):
  def __init__(self, connector, brokerId, *args, **kwargs):
    super().__init__(connector, brokerId)
    self.__dict__['NOTIFY'] = self._NOTIFY
    self.__dict__['TESTX'] = self._TESTX

  @classmethod
  def make(cls, context, actorId, packet):
    logger.info(f'{cls.__name__}, creating hardhash service, packet : {str(packet)}')
    connector = context.get(packet.taskId)
    if not connector:
      makeArgs = MakeArgs(
          sockType=zmq.DEALER,
          sockKw={zmq.IDENTITY:packet.taskId},
          conn=[context.hhDb])
      connector = context.addConn(packet.taskId, makeArgs)
      logger.info(f'!!! ServiceA, {packet.taskId}, added connector {connector.cid}')
    return cls(connector, context.hhId, actorId)

  def __getitem__(self, key):
    if key in self.__dict__:
      return self.__dict__[key]
    return getattr(self, key)

  # -------------------------------------------------------------- #
  # __call__
  # __call__ returns coroutine serve, which is intended to be final
  # This enables a descendent class to override __call__ with special
  # options
  # ---------------------------------------------------------------#
  async def __call__(self):
    logger.info(f'### {self.hostname} is starting ...')
    self.active.set()
    await self.serve()

  #----------------------------------------------------------------#
  # perform
  #----------------------------------------------------------------#
  async def perform(self, request, *args):
    logger.info(f'{self.hostname}, got request : {request}')
    response = await self[request](*args)
    if response:
      await self.send(response,self.name)

  #----------------------------------------------------------------#
  # _TESTX - end of transmission
  #----------------------------------------------------------------#
  async def _TESTX(self, packet):
    logger.info(f'{self.hostname}, TESTX called : {str(packet)} ...')
    await asyncio.sleep(0.1)
    return [201,{'message':'TESTX is successful'}]

  #----------------------------------------------------------------#
  # _NOTIFY - end of transmission
  #----------------------------------------------------------------#
  async def _NOTIFY(self, taskId):
    logger.info(f'{self.hostname}, notified ...')
    await asyncio.sleep(0.1)
    self.active.clear()