'''

Program 49 | Group Anagrams
https://leetcode.com/problems/group-anagrams/

'''

class Solution:
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        ans = collections.defaultdict(list)
        for s in strs:
            key = [0] * 26
            for c in s:
                key[ord(c) - ord('a')] += 1
            ans[tuple(key)].append(s)

        return ans.values()


import random
from math import sqrt
from scipy.interpolate import lagrange

from main_folder.smpc_addition.network_nodes.RandPoly import RandPoly

class SmpcAdditionNode:
    def __init__(self) -> None:
        pass

    def generate_functions(self, record):
        all_functions = []
        for feature in record:
            func = RandPoly(
                n=2,
                R=[
                    (i, x)
                    for i, x in enumerate(
                        list(
                            [
                                feature,
                                random.randint(2, 250),
                                random.randint(2, 250),
                            ]
                        )
                    )
                ],
            ).poly
            all_functions.append(func)
        return all_functions

    def generate_shares(self, func_array, x_points):
        shares = []
        for f in func_array:
            x_point_shares = []
            for x in x_points:
                x_point_shares.append(f(x))
            shares.append(x_point_shares)
        return shares

    def get_random_points(self, num_points, rand_seed, max_x):
        points = random.Random(rand_seed).sample(range(1, max_x), num_points)
        return points

    def calc_share_sums_one_record(self, f_shares, g_shares, h_shares):
        s_x_points = []
        for x_point in range(len(f_shares)):
            s_x = []
            for i, j, k in zip(f_shares[x_point], g_shares[x_point], h_shares[x_point]):
                sum = i+j+k
                s_x.append(sum)
            s_x_points.append(s_x)
        return s_x_points

    def get_set_of_lagrange_values_one_record(self, s_shares_client, s_shares_server):
        lagrange_set_one_record = []
        for feature in range(len(s_shares_client[0])):
            s_x_feature = [s_shares_client[0][feature]]
            for i in range(len(s_shares_server[0])):
                s_x_feature.append(s_shares_server[feature][i])
            lagrange_set_one_record.append(s_x_feature)
        return lagrange_set_one_record

    def reconstruct(self, shares, x_points):
        f = lagrange(x_points, shares)
        return f

    def distance_to_one_point(self, lagrange_set_one_record, x_points):
        # client interpolation
        s_n_functions = [self.reconstruct(shares, x_points) for shares in lagrange_set_one_record]
        all_s0_vals = [f(0) for f in s_n_functions]

        # calc distance
        distance = 0
        for i in all_s0_vals:
            distance += i**2
        distance = sqrt(distance)

        return distance


# -*- coding: utf-8 -*-
"""Model Examples."""

import numpy as np
import sympy
from sympy import symbols

from causing.model import Model
from causing.simulate import SimulationParams, simulate

data_path = __file__.split("causing")[0]

def example():
    """model example"""

    X1, X2, Y1, Y2, Y3 = symbols(["X1", "X2", "Y1", "Y2", "Y3"])
    equations = (  # equations in topological order (Y1, Y2, ...)
        X1,
        X2 + 2 * Y1 ** 2,
        Y1 + Y2,
    )
    m = Model(
        xvars=[X1, X2],  # exogenous variables in desired order
        yvars=[Y1, Y2, Y3],  # endogenous variables in topological order
        equations=equations,
        final_var=Y3,  # final variable of interest, for mediation analysis
    )

    ymvars = [Y3]  # manifest endogenous variables
    xdat, ymdat = simulate(
        m,
        SimulationParams(
            ymvars=ymvars,
            xmean_true=[3, 2],  # mean of exogeneous data
            sigx_theo=1,  # true scalar error variance of xvars
            sigym_theo=1,  # true scalar error variance of ymvars
            rho=0.2,  # true correlation within y and within x vars
            tau=200,  # nr. of simulated observations
        ),
    )

    estimate_input = dict(
        ymvars=ymvars,
        ymdat=ymdat,
        alpha=None,  # regularization parameter, is estimated if None
        dof=None,  # effective degrees of freedom, corresponding to alpha
    )

    return m, xdat, ymdat, estimate_input

def example2():
    """model example 2, no regularization required, no latent variables"""

    X1, Y1 = symbols(["X1", "Y1"])
    equations = (X1,)
    ymvars = [Y1]
    m = Model(
        equations=equations,
        xvars=[X1],
        yvars=[Y1],
        final_var=Y1,
    )

    xdat, ymdat = simulate(
        m,
        SimulationParams(
            ymvars=ymvars,
            xmean_true=[3],
            sigx_theo=1,
            sigym_theo=1,
            rho=0.2,
            tau=200,
        ),
    )

    estimate_input = dict(
        ymvars=ymvars,
        ymdat=ymdat,
        alpha=None,
        dof=None,
    )

    return m, xdat, ymdat, estimate_input

def example3():
    """model example 3

    difficult to estimate:
    if just Y3 is manifest, huge regularization is required and direct effects are strongly biased,
    (if all yvars are manifest, just slight regularization is required and some standard errors are huge)
    """

    X1, Y1, Y2, Y3 = symbols(["X1", "Y1", "Y2", "Y3"])
    equations = (
        2 * X1,
        -X1,
        Y1 + Y2,
    )
    ymvars = [Y3]
    m = Model(
        equations=equations,
        xvars=[X1],
        yvars=[Y1, Y2, Y3],
        final_var=Y3,
    )

    xdat, ymdat = simulate(
        m,
        SimulationParams(
            ymvars=ymvars,
            xmean_true=[3],
            sigx_theo=1,
            sigym_theo=1,
            rho=0.2,
            tau=200,
        ),
    )

    estimate_input = dict(
        ymvars=ymvars,
        ymdat=ymdat,
        alpha=None,
        dof=None,
    )

    return m, xdat, ymdat, estimate_input

def education():
    """Education

    The dataset contains following variables in this order, the variables 0.
    to 4. being time varying and variables 5. to 9. being time invariant:

    0. PERSONID = Person id (ranging from 1 to 2,178) # not used by us
    1. EDUC     = Education (years of schooling)
    2. LOGWAGE  = Log of hourly wage, at most recent job, in real 1993 dollars # we use wage instead of log wage
    3. POTEXPER = Potential experience (= AGE - EDUC - 5)
    4. TIMETRND = Time trend (starting at 1 in 1979 and incrementing by year) # not used by us
    5. ABILITY  = Ability (cognitive ability measured by test score)
    6. MOTHERED = Mother's education (highest grade completed, in years)
    7. FATHERED = Father's education (highest grade completed, in years)
    8. BRKNHOME = Dummy variable for residence in a broken home at age 14
    9. SIBLINGS = Number of siblings

    Model identified without regularization if wage instead of logwage and all observations. # yyyy

    ToDo: Automatic Hessian gives wrong results for this example: # yyyy
    Algebraic and numeric   Hessian allclose: True.
    Automatic and numeric   Hessian allclose: False.
    Automatic and algebraic Hessian allclose: False.
    No problem if ABILITY has zero effect
    """

    (
        FATHERED,
        MOTHERED,
        SIBLINGS,
        BRKNHOME,
        ABILITY,
        AGE,
        EDUC,
        POTEXPER,
        WAGE,
    ) = symbols(
        [
            "FATHERED",
            "MOTHERED",
            "SIBLINGS",
            "BRKNHOME",
            "ABILITY",
            "AGE",
            "EDUC",
            "POTEXPER",
            "WAGE",
        ]
    )

    equations = (
        # EDUC
        13
        + 0.1 * (FATHERED - 12)
        + 0.1 * (MOTHERED - 12)
        - 0.1 * SIBLINGS
        - 0.5 * BRKNHOME,
        # POTEXPER
        sympy.Max(AGE - EDUC - 5, 0),
        # WAGE
        7 + 1 * (EDUC - 12) + 0.5 * POTEXPER + 1 * ABILITY,
    )
    m = Model(
        equations=equations,
        xvars=[FATHERED, MOTHERED, SIBLINGS, BRKNHOME, ABILITY, AGE],
        yvars=[EDUC, POTEXPER, WAGE],
        final_var=WAGE,
    )

    # load and transform data
    from numpy import array, concatenate, exp, loadtxt

    xymdat = loadtxt("{}/data/education.csv".format(data_path), delimiter=",").reshape(
        -1, 10
    )
    xymdat = xymdat.T  # observations in columns
    # xymdat = xymdat[:, 0:200]      # just some of the 17,919 observations
    xdat = xymdat[[7, 6, 9, 8, 5]]  # without PERSONID, TIMETRND
    age = array(xymdat[3, :] + xymdat[1, :] + 5).reshape(
        1, -1
    )  # age = POTEXPER + EDUC + 5
    ymdat = xymdat[[1, 3, 2]]
    ymdat[2, :] = exp(ymdat[2, :])  # wage instead of log wage
    xdat = concatenate((xdat, age))

    estimate_input = dict(
        ymvars=[EDUC, POTEXPER, WAGE],
        ymdat=ymdat,
        alpha=2.637086,
        dof=0.068187,
    )

    return m, xdat, ymdat, estimate_input

def heaviside():
    """Minimal example exercise correct Heaviside(0) handling"""

    X1, Y1 = symbols(["X1", "Y1"])
    m = Model(
        xvars=[X1],
        yvars=[Y1],
        equations=(sympy.Max(X1, 0),),
        final_var=Y1,
    )

    xdat = np.array([[-1, -2, 3, 4, 5, 6]])
    ymdat = np.array([[-1.1, -2.1, 2.9, 4, 5.1, 5.9]])
    estimate_input = dict(
        ymvars=[Y1],
        ymdat=ymdat,
        alpha=None,
        dof=None,
    )
    return m, xdat, ymdat, estimate_input


class Process:
    currentPID = 1

    def __init__(self, codefile, dispatcher, processor):

        self.id = self.currentPID
        self.dispatcher = dispatcher
        self.processor = processor
        Process.currentPID += 1

        self.currentLine = 0
        self.code = self.fetch_program_code(codefile)
        self.registers = [0] * 8

    def fetch_program_code(self, codefile):
        with open(codefile, "r") as f:
            content = f.read()

        content = content.strip()
        if "====\n" in content:
            content = content.split("====\n")[1]

        commands = []

        for line in content.split("\n"):

            currentLine = line.split(" | ")[1]
            currentLine = currentLine.strip()
            operation = currentLine.split(" ")[0]
            values = currentLine.split(" ")[1].split(",")

            commands.append([operation, values])

        return commands

    def toBlockedQueue(self):
        self.registers = self.processor.exportRegisters()

    def toReadyQueue(self):
        self.registers = self.processor.exportRegisters()

    def setupProcessor(self):
        self.processor.importRegisters(self.registers)

    def setLine(self, lineNB):
        self.currentLine = lineNB

    def nextLine(self):
        self.currentLine += 1

    def hasNextOP(self):
        return self.currentLine < len(self.code)

    def runNextOP(self):
        currentOPs = self.code[self.currentLine]

        if currentOPs[0] == "ADD":
            self.processor.add(currentOPs[1][0], currentOPs[1][1], self)
            self.currentLine += 1
        elif currentOPs[0] == "MINUS":
            self.processor.minus(currentOPs[1][0], currentOPs[1][1], self)
            self.currentLine += 1
        elif currentOPs[0] == "MULTIPLY":
            self.processor.multiply(currentOPs[1][0], currentOPs[1][1], self)
            self.currentLine += 1
        elif currentOPs[0] == "JUMP":
            self.processor.jump(currentOPs[1][0], self)
        elif currentOPs[0] == "JUMPN":
            self.processor.jumpn(currentOPs[1][0], self)
        elif currentOPs[0] == "JUMPZ":
            self.processor.jumpz(currentOPs[1][0], self)
        elif currentOPs[0] == "LOAD":
            self.processor.load(currentOPs[1][0], currentOPs[1][1], self)
            self.currentLine += 1
        elif currentOPs[0] == "STORE":
            self.processor.store(currentOPs[1][0], currentOPs[1][1], self)
            self.currentLine += 1
        elif currentOPs[0] == "READ":
            self.processor.read(currentOPs[1][0], currentOPs[1][1], self)
            self.currentLine += 1
        elif currentOPs[0] == "WRITE":
            self.processor.write(currentOPs[1][0], currentOPs[1][1], self)
            self.currentLine += 1
        elif currentOPs[0] == "INIT":
            self.processor.init(currentOPs[1][0], currentOPs[1][1], self)
            self.currentLine += 1
        elif currentOPs[0] == "SEMWAIT":
            self.processor.semwait(currentOPs[1][0], self)
            self.currentLine += 1
        elif currentOPs[0] == "SEMPOST":
            self.processor.sempost(currentOPs[1][0], self)
            self.currentLine += 1


import typing as t

"""
Tags: Adjacency matrix

The algorithm finds all shortest path pairs. The graph needs to be represented
as an adjacency matrix.

Example graph definition:

    A   B   C   D

A   0   8  INF  1

B  INF  0   1  INF

C   4  INF  0  INF

D  INF  2   9   0

The diagonal ^ is 0s because the node's distance to itself if 0.

INF - means from this vertex you cannot directly reach the other one

Complexities:
T: O(V ^ 3)
S: O(V ^ 2)
"""

Graph = list[list[t.Any]]
INF = float("inf")

def print_adjacent_matrix(nb_vertices: int, graph: Graph) -> None:
    for i in range(nb_vertices):
        print()
        for j in range(nb_vertices):
            if graph[i][j] == INF:
                print("INF", end=" ")
            else:
                print(graph[i][j], end=" ")

def perform_floyd_warshall(nb_vertices: int, graph: Graph) -> Graph:
    distances = graph
    # Take all vertices one by one as a source V. Iterating over rows, each
    # row represents connections from the current vertex
    for i in range(nb_vertices):
        # Iterate over all cells in the matrix
        for row in range(nb_vertices):
            for col in range(nb_vertices):
                # If direct distance is greater than through another node,
                # pick the one going through another node
                # distances[row][col] = min(
                #     distances[row][col], distances[row][i] + distances[i][col]
                # )

                # OR
                curr_dist = distances[row][col]
                new_dist = distances[row][i] + distances[i][col]
                if new_dist < curr_dist:
                    distances[row][col] = new_dist

    return distances

def main():
    graph = [
        [0, 8, INF, 1],
        [INF, 0, 1, INF],
        [4, INF, 0, INF],
        [INF, 2, 9, 0]
    ]
    nb_vertices = 4
    distances = perform_floyd_warshall(nb_vertices, graph)
    print_adjacent_matrix(nb_vertices, distances)

if __name__ == '__main__':
    main()


from selenium import webdriver
from selenium.webdriver.common.alert import Alert
from random import choice, randint
import win32com.client as comclt
import win32gui
import win32con
import time

def handle_upload_file_dialog(file_path):
    sleep = 1
    windowsShell = comclt.Dispatch("WScript.Shell")
    time.sleep(sleep)
    windowsShell.SendKeys(file_path)
    time.sleep(sleep)
    windowsShell.SendKeys("{TAB}{TAB}")
    time.sleep(sleep)
    windowsShell.SendKeys("{ENTER}{ENTER}")

def login():
    driver.find_element_by_xpath('//div[text()="Login"]').click()
    time.sleep(1)
    driver.find_element_by_xpath("//input[@type='email']").send_keys("cheekit.chong98@gmail.com")
    time.sleep(1)
    driver.find_element_by_xpath("//input[@type='password']").send_keys("bts")
    time.sleep(1)
    driver.find_element_by_xpath('//div[text()="Login as Tenant"]').click()
    time.sleep(1)
    links = driver.find_elements_by_xpath('//div[text()="LOGIN"]')
    links[-1].click()
    time.sleep(5)

if __name__ == "__main__":
    driver = webdriver.Chrome()
    driver.get('https://esc-group-10.netlify.app/')
    time.sleep(5)
    login()
    driver.get('https://esc-group-10.netlify.app/staff/manage-tenants/create')
    time.sleep(3)
    links = driver.find_elements_by_xpath("//input[@type='text']")
    links[-1].send_keys("TEST")
    links[-2].send_keys("TEST")
    driver.find_element_by_xpath("//input[@type='email']").send_keys("Test@test.com")
    driver.find_element_by_xpath("//input[@type='password']").send_keys("testtest")
    driver.find_element_by_xpath('//div[text()="CREATE ACCOUNT"]').click()
    time.sleep(2)
    driver.get('https://esc-group-10.netlify.app/staff/manage-tenants/delete')
    time.sleep(2)
    driver.find_element_by_xpath('//div[text()="Sengkang General Hospital"]').click()
    time.sleep(1)
    driver.find_element_by_xpath('//div[text()="TEST"]').click()
    time.sleep(1)
    driver.find_element_by_xpath('//div[text()="DELETE TENANT"]').click()
    time.sleep(1)
    Alert(driver).accept()
    time.sleep(3)
    driver.close()


import sys
sys.path.insert(0, './src')
# import os
# os.getcwd()
# os.chdir('../')
from importlib import reload
import numpy as np
np.set_printoptions(suppress=True)
import pickle
from envs import merge
reload(merge)
from envs.merge import EnvMerge
import os
import time
import json
import matplotlib.pyplot as plt

with open('./src/envs/config.json', 'rb') as handle:
    config = json.load(handle)

env = EnvMerge(config)

def pickle_this(item, data_files_dir, item_name):
    data_files_dir += '/'+item_name+'.pickle'
    if not os.path.exists(data_files_dir):
        with open(data_files_dir, 'wb') as handle:
            pickle.dump(item, handle)
    else:
        print('This data id exists')

def prep_data(training_data):
    all_epis = np.unique(training_data[0][:, 0, 0])
    np.random.seed(2021)
    np.random.shuffle(all_epis)

    train_epis = all_epis[:int(len(all_epis)*0.7)]
    val_epis = np.setdiff1d(all_epis, train_epis)
    train_samples = np.where(training_data[0][:, 0:1, 0] == train_epis)[0]
    val_samples = np.where(training_data[0][:, 0:1, 0] == val_epis)[0]

    _, history_sca, future_sca, future_idm_s,\
                future_m_veh_c, future_e_veh_a = training_data
    train_input = [history_sca[train_samples, :, 2:],
                future_sca[train_samples, :, 2:],
                future_idm_s[train_samples, :, 2:],
                future_m_veh_c[train_samples, :, 2:],
                future_e_veh_a[train_samples, :, 2:]]

    test_input = [history_sca[val_samples, :, 2:],
                future_sca[val_samples, :, 2:],
                future_idm_s[val_samples, :, 2:],
                future_m_veh_c[val_samples, :, 2:],
                future_e_veh_a[val_samples, :, 2:]]

    return train_input, test_input
# %%
"""
Generate datan
"""
from data import merge_data_gen
reload(merge_data_gen)
from data.merge_data_gen import DataGenMerge
data_gen = DataGenMerge(env=env, episodes_n=500)
sim_data = data_gen.prep_data()
sim_data.shape

# %%
"""
Pickle generated data.
"""
data_id = '049'
dataset_name = 'sim_data_'+data_id
data_files_dir = './src/datasets/'+dataset_name
if not os.path.exists(data_files_dir):
    os.makedirs(data_files_dir)

if not os.path.exists(data_files_dir+'/sim_data.pickle'):
    with open(data_files_dir+'/sim_data.pickle', 'wb') as handle:
        pickle.dump(sim_data, handle)
else:
    print('This data id exists')

# %%
"""
Load generated data.
"""
data_id = '049'
dataset_name = 'sim_data_'+data_id
data_files_dir = './src/datasets/'+dataset_name
with open(data_files_dir+'/sim_data.pickle', 'rb') as handle:
    sim_data = pickle.load(handle)
sim_data.shape
sim_data[20, 1]
sim_data[:, 2]
sim_data[:, 2]
# %%
"""
count cars
"""
count = 0
np.unique(sim_data[sim_data[:, 0] == 1][:, 2]).shape[0]
for i in range(500):
    count += np.unique(sim_data[sim_data[:, 0] == i][:, 2]).shape[0]-2 #
count
2000 * 200 * 0.1/60**2
# %%

lens = []
for i in range(100):
    lens.append(np.unique(sim_data[sim_data[:, 0] == i][:, 1]).shape[0])
lens
plt.hist(lens, bins=50)
# %%
"""
Prepare data
"""
history_len = 30 # steps
rollout_len = 50
from data import data_prep
reload(data_prep)
from data.data_prep import DataPrep
data_prep = DataPrep()
sim_data, dummy_value_set = data_prep.fill_missing_values(sim_data)
sim_data_scaled, env_scaler, m_scaler = data_prep.scale_data(sim_data)
history_future_seqs = data_prep.sequence(sim_data, history_len, rollout_len)
history_future_seqs_scaled = data_prep.sequence(sim_data_scaled, history_len, rollout_len)
data_arrays = data_prep.split_data(history_future_seqs, history_future_seqs_scaled)

history_future_usc, history_sca, future_sca, future_idm_s, \
                future_m_veh_c, future_e_veh_a = data_arrays

history_future_usc.shape
history_future_usc[:, 2]
# %%
"""
count cars
"""
count = 0
np.unique(sim_data[sim_data[:, 0] == 1][:, 2]).shape[0]
history_future_usc = history_future_usc[:, 0, 0:3]
for i in range(500):
    count += np.unique(history_future_usc[history_future_usc[:, 0] == i][:, 2]).shape[0]
count
2000 * 50 * 0.1/(60**2)
np.unique(history_future_usc[history_future_usc[:, 0] == 9][:, 2]).shape[0]
# %%

# %%
train_input, test_input = prep_data(data_arrays)
train_input[-1].shape
# %%

"""
Make displacement a target
"""
def get_target_vals(arr):
    dxs = np.zeros([arr.shape[0], rollout_len+1, 1])

    for step in range(1, rollout_len+1):
        dxs[:, step, :] = dxs[:, step-1, :] + arr[:, step-1, 1:]*0.1 \
                                                    + 0.5*arr[:, step-1, 0:1]*0.1**2
    return dxs[:, 1:, :]
dxs = get_target_vals(train_input[-1])
train_input[-1] = np.append(train_input[-1], dxs, axis=-1)

dxs = get_target_vals(test_input[-1])
test_input[-1] = np.append(test_input[-1], dxs, axis=-1)

plt.plot(train_input[-1][0, :, -1])
plt.plot(train_input[-1][1000, :, -1])
# %%
# """
# BALANCE DATA
# """
# hf_usc_indexs = {}
# col_names = [
#          'episode_id', 'time_step',
#          'e_veh_id', 'f_veh_id', 'm_veh_id',
#          'm_veh_exists', 'e_veh_att',
#          'e_veh_speed', 'f_veh_speed', 'm_veh_speed',
#          'e_veh_action', 'f_veh_action', 'm_veh_action',
#          'aggressiveness',
#          'desired_v','desired_tgap', 'min_jamx', 'max_act', 'min_act',
#          'el_delta_v', 'el_delta_x', 'em_delta_v', 'em_delta_x',
#          'em_delta_y', 'delta_x_to_merge']
#
# for i, item_name in enumerate(col_names):
#     hf_usc_indexs[item_name] = i
# # %%
# history_future_usc, history_sca, future_sca, future_idm_s, future_m_veh_c, future_e_veh_a = data_arrays
# balance_value = np.count_nonzero((\
#                         history_future_usc[:, :, hf_usc_indexs['e_veh_att']] == 1).any(axis=1))/\
#                         history_future_usc.shape[0]
# print(balance_value)
# cond = (history_future_usc[:, :, hf_usc_indexs['e_veh_att']] == 1).any(axis=1)
# data_arrays = [np.append(sim_dataay, sim_dataay[cond], axis=0) for sim_dataay in data_arrays]
# %%
"""
Anywhere an array is fed to a model, the data is first scaled.
Scalers are pickled here.
"""
item_name = 'env_scaler'
pickle_this(env_scaler, data_files_dir, item_name)

item_name = 'm_scaler'
pickle_this(m_scaler, data_files_dir, item_name)

item_name = 'dummy_value_set'
pickle_this(dummy_value_set, data_files_dir, item_name)

item_name = 'train_input{history_len}_f{rollout_len}'.format(\
                                history_len=history_len, rollout_len=rollout_len)

pickle_this(train_input, data_files_dir, item_name)

item_name = 'test_input{history_len}_f{rollout_len}'.format(\
                                history_len=history_len, rollout_len=rollout_len)

pickle_this(test_input, data_files_dir, item_name)

item_name = 'data_arrays_h{history_len}_f{rollout_len}'.format(\
                                history_len=history_len, rollout_len=rollout_len)

pickle_this(data_arrays, data_files_dir, item_name)


# -*- coding: utf-8 -*-
# © 2015 Eficent - Jordi Ballester Alomar
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from openerp.osv import fields, orm
from openerp.tools.translate import _

class LocationAnalyticCreate(orm.TransientModel):
    _name = 'location.analytic.create'
    _description = 'Create an analytic Location'

    def _prepare_location(self, cr, uid, wizard, context=None):
        if context is None:
            context = {}
        res = {
            'name': wizard.name,
            'location_id': wizard.location_id.id,
            'type': 'internal' if wizard.type == 'internal' else 'customer',
            'analytic_account_id': context['default_analytic_account_id'],
        }
        if wizard.type == 'external':
            res.update(company_id=False)
        return  res

    def create_location(self, cr, uid, ids, context=None):
        if context is None:
            context = {}
        res = []
        wizard = self.browse(cr, uid, ids[0], context=context)
        loc_obj = self.pool.get('stock.location')
        loc_data = self._prepare_location(
            cr, uid, wizard, context=context)

        new_loc = loc_obj.create(
            cr, uid, loc_data, context=context)

        res.append(new_loc)

        return {
            'domain': "[('id','in', ["+','.join(map(str, res))+"])]",
            'name': _('Locations for projects'),
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'stock.location',
            'view_id': False,
            'context': False,
            'type': 'ir.actions.act_window'
        }

    def _get_analytic_locations(self, cr, uid, ids, context=None):
        if context is None:
            return
        if 'default_analytic_account_id' not in context:
            return
        res = {}
        analytic_id = context['default_analytic_account_id']
        location_ids = self.pool.get('stock.location').search(
            cr, uid, ['analytic_account_id', '=', analytic_id])
        ch_location_ids = self.pool.get('stock.location')._get_sublocations(
            cr, uid, location_ids)
        for wiz_id in self.browse(cr, uid, ids, context=context):
            res[wiz_id] = []
            for loc in ch_location_ids:
                res[wiz_id].appenf(loc.id)
        return res

    _columns = {
        'name': fields.char('Description', size=256, required=True),
        'location_id': fields.many2one('stock.location', 'Parent location',
                                       required=False,
                                       domain="[('usage', '=', type),"
                                              "('analytic_account_id', '=', context['default_analytic_account_id'])]"),
        'type': fields.selection([('internal', 'Internal'),
                                  ('customer', 'External')],
                                 'Type', required=True),
    }

class AnalyticocationManager(orm.TransientModel):
    _name = 'analytic.location.manager'
    _description = 'Manage analytic Locations'

    _columns = {
        'recursive': fields.boolean("Include Children"),
    }
    def open_location_manager(self, cr, uid, ids, context=None):
        if context is None:
            context = {}
        return {'type': 'ir.actions.act_window',
                'name': 'Create Location For Project',
                'res_model': 'location.analytic.create',
                'view_type': 'form',
                'view_mode': 'form',
                'target': 'new',
                'context': context,
                }

    def show_analytic_locations(self, cr, uid, ids, context=None):
        if context is None:
            return
        if 'default_analytic_account_id' not in context:
            return
        analytic_ids = [context['default_analytic_account_id']]
        for wiz_id in self.browse(cr, uid, ids, context=context):
            if wiz_id.recursive:
                account = self.pool.get('account.analytic.account').browse(
                    cr, uid, analytic_ids, context)
                child_ids = [child.id for child in account[0].child_ids]
                analytic_ids.extend(child_ids)
            location_ids = self.pool.get('stock.location').search(
                cr, uid, [('analytic_account_id', 'in', analytic_ids)])
            ch_location_ids = self.pool.get(
                'stock.location')._get_sublocations(cr, uid, location_ids)
            location_ids.extend(ch_location_ids)
            res = list(set(location_ids))

        return {'type': 'ir.actions.act_window',
                'name': _('Locations for project'),
                'res_model': 'stock.location',
                'view_type': 'form',
                'view_mode': 'tree, form',
                'target': 'current',
                'domain': [('id', 'in', res)],
                'nodestroy': True,
                }


import cv2 as cv
import sys

#loads the using weights and correspding configuration rule
def load_model(model_weights="",model_config=""):

	if model_weights == "" and model_config == "":
		print("Model config and weights not found!");
		sys.exit(0);

	net = cv.dnn.readNet(model_weights,model_config);
	return net;

def get_output_layers(net):
    layer_names = net.getLayerNames();
    output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()];
    return output_layers;


from __future__ import absolute_import
from pymongo import MongoClient
from pymongo.database import Database
from pymongo.collection import Collection
import six

class_to_class_name = {
    str:     'unicode',
    six.text_type: 'unicode',
    bool:    'bool',
    list:    'list',
    tuple:   'list',
    int:     'int',
    float:   'float',
}

class FedjiMongo(MongoClient):

    def __getattr__(self, db):
        return FedjiMongoDB(self, db)

class FedjiMongoDB(Database):
    # def __init__(self, fedji_client, db):
        # self.db = getattr(fedji_client.client, db)

    def __getattr__(self, collection):
        return FedjiMongoCollection(self, collection)

class FedjiMongoCollection(Collection):

    def __init__(self, fedji_db, collection):
        Collection.__init__(self, fedji_db, collection)
        attributes_collection = Database.__getattr__(
            self.database, '_attributes')
        fields = attributes_collection.find_one({})
        if fields is None:
            self.fields_id = attributes_collection.save({}, manipluate=True)
            self._fields = {}
        else:
            self.fields_id = fields.pop('_id')
            self._fields = fields

    @property
    def fields(self):
        return self._fields

    def new_field(self, field, cls):
        if field not in self.fields:
            atype = class_to_class_name[cls]
            self._fields[field] = atype
            doc = self.fields.copy()
            doc['_id'] = self.fields_id
            attributes_collection = Database.__getattr__(
                self.database, '_attributes')
            import pprint
            pprint.pprint(doc)
            attributes_collection.save(doc)

    def insert(self, doc_or_docs, **kwargs):
        if isinstance(doc_or_docs, dict):
            doc_or_docs = [doc_or_docs]
        for document in doc_or_docs:
            for k, v in six.iteritems(document):
                self.new_field(k, v.__class__)
        Collection.insert(self, doc_or_docs, **kwargs)

    # def __getattr__(self, attribute):
        # return getattr(self.collection, attribute)


from bundlewrap.exceptions import BundleError

munin_config = node.metadata.get('munin', {})

symlinks = {}
actions = {}
files = {}
pkg_apt = {}
svc_systemd = {}

trigger_reload = []
if munin_config.get('type', 'c') == 'c':
    node_type = 'munin-node-c'

    pkg_apt['munin-node-c'] = {
        'installed': True,
    }
    pkg_apt['munin-node'] = {
        'installed': False,
    }

    # if we do not have xinetd, we will fail here
    if not node.has_bundle('xinetd'):
        raise BundleError('you need to have xinetd enabled for this node')

    files['/etc/xinetd.d/munin'] = {
        'content_type': 'jinja2',
        'owner': 'root',
        'group': 'root',
        'mode': '0644',
        'context': {
            'port': munin_config.get('port', 4949),
            'ips': ' '.join(sorted(munin_config.get('server_ips', []))),
        },
        'needs': [
            'pkg_apt:xinetd',
            'pkg_apt:munin-node-c',
        ],
        'triggers': [
            'svc_systemd:xinetd.service:restart',
        ]
    }

    files['/etc/munin/munin-node.conf'] = {
        'delete': True,
    }

elif munin_config.get('type', 'c') == 'perl':
    node_type = 'munin-node'

    pkg_apt['munin-node'] = {
        'installed': True,
    }
    pkg_apt['munin-node-c'] = {
        'installed': False,
    }

    files['/etc/xinetd.d/munin'] = {
        'delete': True,
    }

    svc_systemd['munin-node'] = {
        'needs': ['pkg_apt:munin-node'],
    }

    files['/etc/munin/munin-node.conf'] = {
        'content_type': 'jinja2',
        'owner': 'root',
        'group': 'root',
        'mode': '0644',
        'context': {
            'port': munin_config.get('port', 4949),
            'allow': '\n'.join(sorted(map(
                lambda x: "allow ^{}$".format(x.replace('.', '\\.')),
                munin_config.get('server_ips', [])
            ))),
            'hostname': munin_config.get('hostname', node.hostname),
        },
        'needs': [
            'pkg_apt:munin-node',
        ],
        'triggers': [
            'svc_systemd:munin-node:restart',
        ]
    }

    trigger_reload += ['svc_systemd:munin-node:restart']

needed_apt_pkg = set()

for plugin, plugin_config in munin_config.get('plugins', {}).items():
    executable = plugin_config.get('executable', '/usr/share/munin/plugins/{}'.format(plugin))

    if 'apt' in plugin_config:
        needed_apt_pkg.add(plugin_config['apt'])

    if executable == 'munin-plugins-c':
        # we know, which package this is in so add it automaticaly
        needed_apt_pkg.add('munin-plugins-c')
        target = '/usr/lib/munin-c/plugins/munin-plugins-c'

    elif "/" not in executable:
        target = "/usr/share/munin/plugins/{}".format(executable)
    else:
        target = executable

    symlinks['/etc/munin/plugins/{}'.format(plugin)] = {
        'target': target,
        'owner': 'root',
        'group': 'root',
        'needs': [
            'pkg_apt:xinetd',
            'pkg_apt:{}'.format(node_type),
        ],
        'triggers': trigger_reload,
    }

    if len(plugin_config.get('config', {})) > 0:
        config_content = [
            '# Written by bundlewrap, do not change',
            '',
        ]
        for name, config in sorted(plugin_config['config'].items(), key=lambda x: x[0]):
            config_content += ['[{}]'.format(name), ] + config + ['', ]

        files['/etc/munin/plugin-conf.d/{}'.format(plugin)] = {
            'content': '\n'.join(config_content) + '\n',
            'owner': 'root',
            'group': 'root',
            'needs': [
                'pkg_apt:{}'.format(node_type),
            ],
            'triggers': trigger_reload,
        }
    else:
        files['/etc/munin/plugin-conf.d/{}'.format(plugin)] = {
            'delete': True,
        }

for pkg in list(needed_apt_pkg):
    pkg_apt[pkg] = {
        'installed': True,
        'needs': [
            'pkg_apt:{}'.format(node_type),
        ],
    }


import numpy as np

from tensorflow.keras.layers import Input, Flatten, Dense, Reshape, Dropout, Concatenate, Lambda, ReLU, Activation
from tensorflow.keras.layers import BatchNormalization
from tensorflow.keras.layers import LeakyReLU
from tensorflow.keras.models import Model
from tensorflow.keras import backend as K
import tensorflow as tf
_EPSILON = K.epsilon()

import matplotlib as mpl
mpl.use('TkAgg')
mpl.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm

from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import roc_auc_score
import scipy

import math
import glob
import time
import shutil
import os

from pickle import load
from sklearn.preprocessing import QuantileTransformer
from sklearn.preprocessing import PowerTransformer

colours_raw_root = [[250,242,108],
					[249,225,104],
					[247,206,99],
					[239,194,94],
					[222,188,95],
					[206,183,103],
					[181,184,111],
					[157,185,120],
					[131,184,132],
					[108,181,146],
					[105,179,163],
					[97,173,176],
					[90,166,191],
					[81,158,200],
					[69,146,202],
					[56,133,207],
					[40,121,209],
					[27,110,212],
					[25,94,197],
					[34,73,162]]

colours_raw_root = np.flip(np.divide(colours_raw_root,256.),axis=0)
cmp_root = mpl.colors.ListedColormap(colours_raw_root)

def sampling(args):
	z_mean, z_log_var = args
	epsilon = K.random_normal(shape=K.shape(z_mean), mean=0, stddev=1)
	return z_mean + K.exp(z_log_var / 2) * epsilon

def reco_loss(x, x_decoded_mean):
	# print(x)
	# print(x_decoded_mean)
	# xent_loss = tf.keras.losses.mean_absolute_error(x, x_decoded_mean)
	xent_loss = tf.keras.losses.binary_crossentropy(x, x_decoded_mean)
	# print(xent_loss)
	# quit(0)
	return xent_loss

def reco_loss_boost_pz(x, x_decoded_mean):
	xent_loss_A = tf.keras.losses.mean_squared_error(x[:,0], x_decoded_mean[:,0])
	xent_loss_B = tf.keras.losses.mean_squared_error(x[:,1], x_decoded_mean[:,1])
	xent_loss_C = tf.keras.losses.mean_squared_error(x[:,2], x_decoded_mean[:,2])
	xent_loss_D = tf.keras.losses.mean_squared_error(x[:,3], x_decoded_mean[:,3])
	xent_loss_E = tf.keras.losses.mean_squared_error(x[:,4], x_decoded_mean[:,4])
	xent_loss_F = tf.keras.losses.mean_squared_error(x[:,5], x_decoded_mean[:,5])
	xent_loss = xent_loss_A + xent_loss_B + xent_loss_C*z_boost_factor + xent_loss_D*pt_boost_factor + xent_loss_E + xent_loss_F*pz_boost_factor
	return xent_loss

def kl_loss(z_mean, z_log_var):
	kl_loss = - 0.5 * K.sum(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1)
	return kl_loss

def split_tensor(index, x):
	return Lambda(lambda x : x[:,index])(x)

print(tf.__version__)

# working_directory = '/Users/am13743/Aux_GAN_thesis/THESIS_ITERATION/TRAINING/'
# training_directory = '/Users/am13743/Aux_GAN_thesis/THESIS_ITERATION/DATA/'
# transformer_directory = '/Users/am13743/Aux_GAN_thesis/THESIS_ITERATION/TRANSFORMERS/'
# training_name = 'relu*.npy'
# testing_name = 'test_relu*.npy'
# saving_directory = 'VAE'
# save_interval = 1000

# working_directory = '/mnt/storage/scratch/am13743/AUX_GAN_THESIS/THESIS_ITERATION/TRAINING/'
# training_directory = '/mnt/storage/scratch/am13743/AUX_GAN_THESIS/THESIS_ITERATION/DATA/'
# transformer_directory = '/mnt/storage/scratch/am13743/AUX_GAN_THESIS/THESIS_ITERATION/TRANSFORMERS/'
# training_name = 'relu*.npy'
# testing_name = 'test_relu*.npy'
# saving_directory = 'VAE'
# save_interval = 25000

working_directory = 'TRAINING/'
training_directory = '/hdfs/user/am13743/THESIS/DATA/'
transformer_directory = '/mnt/storage/scratch/am13743/AUX_GAN_THESIS/THESIS_ITERATION/TRANSFORMERS/'
pre_trained_directory = '/hdfs/user/am13743/THESIS/PRE_TRAIN/'
training_name = 'relu*.npy'
testing_name = 'test_relu*.npy'
saving_directory = 'VAE'
save_interval = 25000

calculate_ROC = True

sample_boosting = False
loss_boosting = False
if loss_boosting == True and sample_boosting == True:
	print('You cant have everything...')
	quit()
boost_pz_reco_loss = False

pz_boost_factor = 2.
pt_boost_factor = 2.
z_boost_factor = 2.

latent_dim = 3
original_dim = 4
kl_factor = 1E-4
reco_factor = 1

batch_size = 50
# E_architecture = [128,128,128]
# D_architecture = [128,128,128]

E_architecture = [250,500,250]
D_architecture = [250,500,250]

def split_tensor(index, x):
	return Lambda(lambda x : x[:,index])(x)

list_of_training_files = glob.glob('%s%s'%(training_directory,training_name))
list_of_testing_files = glob.glob('%s%s'%(training_directory,testing_name))
X_test = np.load(list_of_testing_files[0])
pdg_info_test, X_test, aux_values_test, aux_values_4D_test = np.split(X_test, [1,-5,-1], axis=1)
list_for_np_choice_test = np.arange(np.shape(X_test)[0])

# try:
# 	files_to_remove = glob.glob('%s%s/CORRELATIONS/Correlations_*.png'%(working_directory,saving_directory))
# 	for file_i in files_to_remove:
# 		os.remove(file_i)
# except:
# 	print('/CORRELATIONS/ already clean')
# try:
# 	files_to_remove = glob.glob('%s%s/*.png'%(working_directory,saving_directory))
# 	for file_i in files_to_remove:
# 		os.remove(file_i)
# 	files_to_remove = glob.glob('%s%s/*.h5'%(working_directory,saving_directory))
# 	for file_i in files_to_remove:
# 		os.remove(file_i)
# 	files_to_remove = glob.glob('%s%s/*.npy'%(working_directory,saving_directory))
# 	for file_i in files_to_remove:
# 		os.remove(file_i)
# except:
# 	print('Output directory already clean')

print(' ')
print('Initializing networks...')
print(' ')

##############################################################################################################
# Build encoder model ...
input_sample = Input(shape=(original_dim,))
H_theta = Input(shape=(1,))
H_pt_theta = Input(shape=(1,))

input_sample_in = Concatenate(axis=-1)([input_sample,H_theta,H_pt_theta])

H = Dense(int(E_architecture[0]))(input_sample_in)
H = BatchNormalization(momentum=0.8)(H)
H = LeakyReLU(alpha=0.2)(H)
H = Dropout(0.2)(H)

for layer in E_architecture[1:]:
	H = Dense(int(layer))(H)
	H = BatchNormalization(momentum=0.8)(H)
	H = LeakyReLU(alpha=0.2)(H)
	H = Dropout(0.2)(H)

z_mean = Dense(latent_dim)(H)
z_log_var = Dense(latent_dim)(H)

z = Lambda(sampling, output_shape=(latent_dim,))([z_mean, z_log_var])

encoder = Model(inputs=[input_sample, H_theta, H_pt_theta], outputs=[z, z_mean, z_log_var, H_theta, H_pt_theta])
##############################################################################################################

##############################################################################################################
# Build decoder model ...
input_latent = Input(shape=(latent_dim))
H_theta = Input(shape=(1,))
H_pt_theta = Input(shape=(1,))

input_latent_in = Concatenate()([input_latent,H_theta,H_pt_theta])

H = Dense(int(D_architecture[0]))(input_latent_in)
H = BatchNormalization(momentum=0.8)(H)
H = LeakyReLU(alpha=0.2)(H)
H = Dropout(0.2)(H)

for layer in D_architecture[1:]:
	H = Dense(int(layer))(H)
	H = BatchNormalization(momentum=0.8)(H)
	H = LeakyReLU(alpha=0.2)(H)
	H = Dropout(0.2)(H)

decoded_mean = Dense(original_dim)(H)

H_r = split_tensor(0, H)
H_r = Activation('sigmoid')(H_r)
H_r = Reshape((1,))(H_r)

# H_theta = split_tensor(1, H)
# H_theta = ReLU(max_value=1)(H_theta)
# H_theta = Reshape((1,1))(H_theta)

H_z = split_tensor(2, H)
H_z = Activation('tanh')(H_z)
H_z = ReLU()(H_z)
H_z = Reshape((1,))(H_z)

H_pt = split_tensor(3, H)
H_pt = Activation('tanh')(H_pt)
H_pt = ReLU()(H_pt)
H_pt = Reshape((1,))(H_pt)

# H_pt_theta = split_tensor(4, H)
# H_pt_theta = ReLU(max_value=1)(H_pt_theta)
# H_pt_theta = Reshape((1,1))(H_pt_theta)

H_pz = split_tensor(5, H)
H_pz = Activation('tanh')(H_pz)
H_pz = ReLU()(H_pz)
H_pz = Reshape((1,))(H_pz)

decoded_mean = Concatenate(axis=-1)([H_r, H_theta, H_z, H_pt, H_pt_theta, H_pz])

decoder = Model(inputs=[input_latent, H_theta, H_pt_theta], outputs=[decoded_mean])
##############################################################################################################

input_sample = Input(shape=(original_dim,))
H_theta = Input(shape=(1,))
H_pt_theta = Input(shape=(1,))
z, z_mean, z_log_var, H_theta_d, H_pt_theta_d = encoder([input_sample,H_theta,H_pt_theta])
decoded_mean = decoder([z, H_theta_d, H_pt_theta_d])
vae = Model(inputs=[input_sample, H_theta, H_pt_theta], outputs=[decoded_mean, z_mean, z_log_var])

optimizer = tf.keras.optimizers.Adam(lr=0.0004, beta_1=0.5, decay=0, amsgrad=True)

@tf.function
def train_step(images):

	pdg, images, aux_values_BIN = images[:,:,0], images[:,0,1:7], images[:,:,7:]

	images_r = tf.expand_dims(images[:,0],1)
	images_z = tf.expand_dims(images[:,2],1)
	images_pt = tf.expand_dims(images[:,3],1)
	images_pz = tf.expand_dims(images[:,5],1)

	images = tf.concat([images_r,images_z,images_pt,images_pz],-1)

	theta_gan = tf.random.uniform([batch_size, 1])*0.97+0.015
	theta_pt_gan = tf.random.uniform([batch_size, 1])*0.97+0.015

	images_full = tf.concat([images_r,theta_gan,images_z,images_pt,theta_pt_gan,images_pz],-1)

	with tf.GradientTape() as tape:

		vae_out, vae_z_mean, vae_z_log_var = vae([images,theta_gan,theta_pt_gan])

		vae_reco_loss = reco_loss(images_full, vae_out)
		vae_reco_loss = tf.math.reduce_mean(vae_reco_loss)
		vae_kl_loss = kl_loss(vae_z_mean, vae_z_log_var)
		vae_kl_loss = tf.math.reduce_mean(vae_kl_loss)

		vae_loss = vae_kl_loss*kl_factor + vae_reco_loss*reco_factor

	grad_vae = tape.gradient(vae_loss, vae.trainable_variables)

	optimizer.apply_gradients(zip(grad_vae, vae.trainable_variables))

	return vae_kl_loss, vae_reco_loss

start = time.time()

iteration = -1

loss_list = np.empty((0,3))

axis_titles_post = ['StartX', 'StartY', 'StartZ', 'Px', 'Py', 'Pz']
axis_titles_train = ['r', 'theta', 'z', 'pt', 'pt_theta', 'pz']
axis_titles_boxcox = ['r - BOXCOX', 'theta - QT', 'z - BOXCOX', 'pt - BOXCOX', 'pt_theta - QT', 'pz - BOXCOX']

ROC_AUC_SCORE_list = np.empty((0,3))
ROC_AUC_SCORE_list = np.append(ROC_AUC_SCORE_list, [[0, 1, 0]], axis=0)
best_ROC_AUC = 1

training_time = 0

t0 = time.time()

for epoch in range(int(1E30)):

	for file in list_of_training_files:

		print('Loading initial training file:',file,'...')

		X_train = np.load(file)

		X_train = np.take(X_train,np.random.permutation(X_train.shape[0]),axis=0,out=X_train)

		if iteration == -1:
			plt.figure(figsize=(5*4, 3*4))
			subplot=0
			for i in range(0, 6):
				for j in range(i+1, 6):
					subplot += 1
					plt.subplot(3,5,subplot)
					if subplot == 3: plt.title(iteration)
					plt.hist2d(X_train[:,i+1], X_train[:,j+1], bins=50,range=[[0,1],[0,1]], norm=LogNorm(), cmap=cmp_root)
					plt.xlabel(axis_titles_boxcox[i])
					plt.ylabel(axis_titles_boxcox[j])
			plt.subplots_adjust(wspace=0.3, hspace=0.3)
			plt.savefig('%s%s/TRAIN.png'%(working_directory,saving_directory),bbox_inches='tight')
			plt.close('all')

		print('Train images shape -',np.shape(X_train))

		list_for_np_choice = np.arange(np.shape(X_train)[0])

		X_train = np.expand_dims(X_train,1).astype("float32")

		train_dataset = (
			tf.data.Dataset.from_tensor_slices(X_train).batch(batch_size,drop_remainder=True).repeat(1)
		)

		for images_for_batch in train_dataset:

			if iteration % 250 == 0: print('Iteration:',iteration)

			iteration += 1

			kl_loss_np, reco_loss_np = train_step(images_for_batch)

			loss_list = np.append(loss_list, [[iteration, kl_loss_np, reco_loss_np]], axis=0)

			if iteration % save_interval == 0:

				t1 = time.time()

				total = t1-t0

				training_time += total

				print('Saving at iteration %d...'%iteration)

				decoder.save('%s%s/decoder.h5'%(working_directory,saving_directory))
				encoder.save('%s%s/encoder.h5'%(working_directory,saving_directory))

				# if iteration < 25000:
				plt.figure(figsize=(12, 8))
				plt.subplot(2,3,1)
				plt.plot(loss_list[:,0], loss_list[:,1])
				plt.ylabel('kl Loss')
				plt.subplot(2,3,2)
				plt.plot(loss_list[:,0], loss_list[:,2])
				plt.ylabel('reco Loss')
				plt.subplot(2,3,3)
				plt.plot(loss_list[:,0], loss_list[:,1])
				plt.ylabel('kl Loss')
				plt.yscale('log')
				plt.subplot(2,3,4)
				plt.plot(loss_list[:,0], loss_list[:,2])
				plt.ylabel('reco Loss')
				plt.yscale('log')
				plt.subplot(2,3,5)
				plt.plot(loss_list[:,0], kl_factor*loss_list[:,1]+reco_factor*loss_list[:,2])
				plt.ylabel('TOTAL Loss')
				plt.yscale('log')
				plt.subplots_adjust(wspace=0.3, hspace=0.3)
				plt.savefig('%s%s/LOSSES.png'%(working_directory,saving_directory),bbox_inches='tight')
				plt.close('all')

				# try:
				noise_size = 100000

				if iteration == 0: noise_size = 10

				gen_noise = np.random.normal(0, 1, (int(noise_size), latent_dim))
				theta_gan = np.random.uniform(low=0., high=1., size=(int(noise_size), 1))*0.97+0.015
				theta_pt_gan = np.random.uniform(low=0., high=1., size=(int(noise_size), 1))*0.97+0.015
				images = np.squeeze(decoder.predict([gen_noise,theta_gan,theta_pt_gan]))

				random_indicies = np.random.choice(list_for_np_choice_test, size=(1,int(noise_size)), replace=False)
				sample = X_test[random_indicies[0]]

				images_r = np.expand_dims(sample[:,0],1)
				images_theta = np.expand_dims(sample[:,1],1)
				images_z = np.expand_dims(sample[:,2],1)
				images_pt = np.expand_dims(sample[:,3],1)
				images_theta_pt = np.expand_dims(sample[:,4],1)
				images_pz = np.expand_dims(sample[:,5],1)

				sample_in = np.concatenate((images_r,images_z,images_pt,images_pz),axis=-1)

				latent, z_mean_gen, z_log_var_gen, theta_enc, theta_pt_enc = encoder.predict([sample_in,images_theta,images_theta_pt])

				plt.figure(figsize=(2*4, 3*4))
				subplot=0
				for i in range(0, latent_dim):
					for j in range(i+1, latent_dim):
						subplot += 1
						plt.subplot(3,2,subplot)
						plt.title(iteration)
						plt.hist2d(latent[:noise_size,i], latent[:noise_size,j], bins=50,range=[[-5,5],[-5,5]], norm=LogNorm(), cmap=cmp_root)
				plt.subplots_adjust(wspace=0.3, hspace=0.3)
				plt.savefig('%s%s/LATENT_SPACE.png'%(working_directory,saving_directory),bbox_inches='tight')
				plt.close('all')

				reco = decoder.predict([latent, theta_enc, theta_pt_enc])

				plt.figure(figsize=(2*4, 3*4))
				subplot=0
				for i in range(0, 6):
					subplot += 1
					ax = plt.subplot(3,2,subplot)
					plt.title('%.4f'%scipy.stats.pearsonr(sample[:noise_size,i],reco[:noise_size,i])[0])
					plt.hist2d(sample[:noise_size,i], reco[:noise_size,i], bins=50, norm=LogNorm(), cmap=cmp_root)
					lims = [
						np.min([ax.get_xlim(), ax.get_ylim()]),  # min of both axes
						np.max([ax.get_xlim(), ax.get_ylim()]),  # max of both axes
					]
					plt.plot(lims, lims, 'k-')
				plt.subplots_adjust(wspace=0.3, hspace=0.3)
				plt.savefig('%s%s/RECONSTRUCTION.png'%(working_directory,saving_directory),bbox_inches='tight')
				plt.close('all')

				########

				plt.figure(figsize=(3*4, 2*4))
				subplot=0
				for i in range(0, 6):
					subplot += 1
					plt.subplot(2,3,subplot)
					if subplot == 2: plt.title(iteration)
					plt.hist([sample[:noise_size,i], images[:noise_size,i]], bins=50,range=[0,1], label=['Train','GEN'],histtype='step')
					plt.yscale('log')
					plt.title(iteration)
					plt.xlabel(axis_titles_train[i])
					plt.legend()
				plt.subplots_adjust(wspace=0.3, hspace=0.3)
				plt.savefig('%s%s/VALUES.png'%(working_directory,saving_directory),bbox_inches='tight')
				plt.close('all')

				plt.figure(figsize=(5*4, 3*4))
				subplot=0
				for i in range(0, 6):
					for j in range(i+1, 6):
						subplot += 1
						plt.subplot(3,5,subplot)
						if subplot == 3: plt.title(iteration)
						plt.hist2d(images[:noise_size,i], images[:noise_size,j], bins=50,range=[[0,1],[0,1]], norm=LogNorm(), cmap=cmp_root)
						plt.xlabel(axis_titles_train[i])
						plt.ylabel(axis_titles_train[j])
				plt.subplots_adjust(wspace=0.3, hspace=0.3)
				plt.savefig('%s%s/CORRELATIONS.png'%(working_directory,saving_directory),bbox_inches='tight')
				# plt.savefig('%s%s/CORRELATIONS/Correlations_%d.png'%(working_directory,saving_directory,iteration),bbox_inches='tight')
				plt.close('all')

				if iteration > 0 and calculate_ROC == True:
					try:
						clf = GradientBoostingClassifier(n_estimators=100, learning_rate=0.1, max_depth=4)

						bdt_train_size = int(np.shape(sample)[0]/2)

						real_training_data = sample[:bdt_train_size]

						real_test_data = sample[bdt_train_size:]

						fake_training_data = np.squeeze(images[:bdt_train_size])

						fake_test_data = np.squeeze(images[bdt_train_size:])

						real_training_labels = np.ones(bdt_train_size)

						fake_training_labels = np.zeros(bdt_train_size)

						total_training_data = np.concatenate((real_training_data, fake_training_data))

						total_training_labels = np.concatenate((real_training_labels, fake_training_labels))

						clf.fit(total_training_data, total_training_labels)

						out_real = clf.predict_proba(real_test_data)

						out_fake = clf.predict_proba(fake_test_data)

						plt.hist([out_real[:,1],out_fake[:,1]], bins = 100,label=['real','gen'], histtype='step')
						plt.xlabel('Output of BDT')
						plt.title(iteration)
						plt.legend(loc='upper right')
						plt.savefig('%s%s/BDT_out.png'%(working_directory,saving_directory), bbox_inches='tight')
						plt.close('all')

						ROC_AUC_SCORE_curr = roc_auc_score(np.append(np.ones(np.shape(out_real[:,1])),np.zeros(np.shape(out_fake[:,1]))),np.append(out_real[:,1],out_fake[:,1]))

						ROC_AUC_SCORE_list = np.append(ROC_AUC_SCORE_list, [[iteration, ROC_AUC_SCORE_curr, training_time]], axis=0)

						if ROC_AUC_SCORE_list[-1][1] < best_ROC_AUC:
							print('Saving best ROC_AUC.')
							decoder.save('%s%s/Decoder_best_ROC_AUC.h5'%(working_directory,saving_directory))
							encoder.save('%s%s/Encoder_best_ROC_AUC.h5'%(working_directory,saving_directory))
							best_ROC_AUC = ROC_AUC_SCORE_list[-1][1]
							shutil.copy('%s%s/CORRELATIONS.png'%(working_directory,saving_directory), '%s%s/BEST_ROC_AUC_Correlations.png'%(working_directory,saving_directory))

						plt.figure(figsize=(8,4))
						plt.title('ROC_AUC_SCORE_list best: %.4f at %d'%(best_ROC_AUC,ROC_AUC_SCORE_list[np.where(ROC_AUC_SCORE_list==best_ROC_AUC)[0][0]][0]))
						plt.plot(ROC_AUC_SCORE_list[:,0],ROC_AUC_SCORE_list[:,1])
						plt.axhline(y=best_ROC_AUC,c='k',linestyle='--')
						plt.axvline(x=ROC_AUC_SCORE_list[np.where(ROC_AUC_SCORE_list==best_ROC_AUC)[0][0]][0],c='k',linestyle='--')
						plt.savefig('%s%s/ROC_progress.png'%(working_directory,saving_directory))
						plt.close('all')
					except:
						print('Roc failed')

				print('Saving complete.')
				# except:
				# 	print('Saving failed at some point and for some unknown reason.')


import PySimpleGUI as sg
'''
sg.theme('DarkAmber')   # Add a touch of color
# All the stuff inside your window.
layout = [  [sg.Text('Some text on Row 1')],
            [sg.Text('Enter something on Row 2'), sg.InputText()],
            [sg.Button('Ok'), sg.Button('Cancel')] ]

# Create the Window
window = sg.Window('Window Title', layout)
# Event Loop to process "events" and get the "values" of the inputs
while True:
    event, values = window.read()
    if event == sg.WIN_CLOSED or event == 'Cancel': # if user closes window or clicks cancel
        break
    print('You entered ', values[0])

window.close()
'''

print('gui test')

'''
#给gui按行布局
layout = [[sg.Text('Enter a Number')],
          [sg.Input()],
          [sg.OK()] ]

#生成gui
event, (number,) = sg.Window('Enter a number example').Layout(layout).Read()

#弹出框
sg.Popup(event, number)
'''

'''

sg.theme('Dark Grey 13')

layout = [[sg.Text('Filename')],
          [sg.Input(), sg.FileBrowse()],
          [sg.OK(), sg.Cancel()]]

window = sg.Window('Get filename example', layout)

event, values = window.read()
print(values)
window.close()

def ChatBot():
    layout = [[(sg.Text('This is where standard out is being routed', size=[40, 1]))],
              [sg.Output(size=(80, 20))],
              [sg.Multiline(size=(70, 5), enter_submits=True),
               sg.Button('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0])),
               sg.Button('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))]]

    window = sg.Window('Chat Window', layout, default_element_size=(30, 2))

    # ---===--- Loop taking in user input and using it to query HowDoI web oracle --- #
    while True:
        event, value = window.read()
        if event == 'SEND':
            print(value)
        else:
            break
    window.close()
ChatBot()

layout = [[sg.Text('Your typed chars appear here:'), sg.Text(size=(15,1), key='-OUTPUT-')],
          [sg.Input(key='-IN-')],
          [sg.Button('Show'), sg.Button('Exit')]]

window = sg.Window('Pattern 2B', layout)

while True:  # Event Loop
    event, values = window.read()
    print(event, values)
    if event in  (None, 'Exit'):
        break
    if event == 'Show':
        # Update the "output" text element to be the value of "input" element
        window['-OUTPUT-'].update(values['-IN-'])

window.close()

layout = [[sg.Text('A custom progress meter')],
          [sg.ProgressBar(1000, orientation='h', size=(20, 20), key='progressbar')],
          [sg.Cancel()]]

window = sg.Window('Custom Progress Meter', layout)
progress_bar = window['progressbar']
# loop that would normally do something useful
for i in range(1000):
    # check to see if the cancel button was clicked and exit loop if clicked
    event, values = window.read(timeout=10)
    if event == 'Cancel'  or event is None:
        break
  # update bar with loop value +1 so that bar eventually reaches the maximum
    progress_bar.UpdateBar(i + 1)
# done with loop... need to destroy the window as it's still open
window.close()
'''

from hashlib import sha1
import os,shutil

def gui():
    layout = [
            [sg.Text('你选择的文件夹是:',font=("宋体", 10)),sg.Text('',key='text1',size=(50,1),font=("宋体", 10))],
            [sg.Text('程序运行记录',justification='center')],
            [sg.Output(size=(70, 20),font=("宋体", 10))],
            [sg.FolderBrowse('打开文件夹',key='folder',target='text1'),sg.Button('重命名'),sg.Button('关闭程序')]
            ]

    window = sg.Window('雁陎的工具箱', layout,font=("宋体", 15),default_element_size=(50,1))

    while True:
        event, values = window.read()
        if event in (None, '关闭'):   # 如果用户关闭窗口或点击`关闭`
            break
        if event == '重命名':
            if values['folder']:
                print('{0}正在重命名原文件为hash值{0}'.format('*'*10))
                mult_rename(values['folder'])
                print('{0}重命名完毕{0}'.format('*'*10))
            else:
                print('请先选择文件夹')

    window.close()

def calchash(file_path):  # 计算图片hash值
    with open(file_path,'rb') as f:
        sha1obj = sha1()
        sha1obj.update(f.read())
        hash = sha1obj.hexdigest()
        return hash

def mult_rename(dir_path): # 批量重命名
    for file in os.listdir(dir_path):
        file_path = os.path.join(dir_path,file)
        if not os.path.isdir(file_path): # 判断是否为文件夹
            pic_hash = calchash(file_path)      # 计算hash值
            last = file[file.rindex(r'.'):]  # 后缀
            new_name = pic_hash+last
            if file == new_name:
                print(file,'无需修改')
            else:
                try:
                    new_path = os.path.join(dir_path,new_name)
                    os.rename(file_path,new_path)
                    print('{0}已重命名为{1}'.format(file,new_name))
                except FileExistsError:
                    repeat_path = dir_path+r'\重复文件夹'
                    if os.path.exists(repeat_path) == False:
                        os.makedirs(repeat_path)
                    new_path = os.path.join(repeat_path,new_name)
                    shutil.move(file_path,new_path)
                    print(r'{0}文件重复，已移至重复文件夹下'.format(file))

def main():
    gui()

if __name__ == '__main__':
    main()


import json
import re
from collections import Counter, defaultdict
from pathlib import Path
from typing import Union

import arabic_reshaper
import demoji
import seaborn as sns
from hazm import Normalizer, sent_tokenize, word_tokenize
from loguru import logger
from src.data import DATA_DIR
from wordcloud import WordCloud

class Chat_Statistics:
    """Generates chat statistics from a telegram chat json file
    """
    def __init__(self, chat_json: Union[str, Path]):
        """
        :param chat_json (Union[str, Path]): path to telegram export json file
        """

        # load chat data
        logger.info(f" loading chat data from {chat_json} ")
        with open(chat_json) as f:
            self.chat_data = json.load(f)

        self.normalizer=Normalizer()

        # load stop words
        logger.info(f" loading stop words from {DATA_DIR / 'stopwords.txt'} ")
        stop_words = open(DATA_DIR / 'stopwords.txt').readlines()
        stop_words = map(str.strip,stop_words)
        self.stop_words=set(map(self.normalizer.normalize,stop_words))

    # delete emoji
    def de_emojify(self, text):
        """Removes emojis and some special characters from the text.

        :param text: Text that contains emoji
        """
        regrex_pattern = re.compile(pattern = "[\u2069\u2066]+", flags = re.UNICODE)
        text = regrex_pattern.sub(r'', text)
        return demoji.replace(text, " ")

    @staticmethod
    def rebuild_msg(sub_messages):
        msg_text = ''
        for sub_msg in sub_messages:
            if isinstance(sub_msg,str):
                msg_text += sub_msg
        return msg_text

    def get_top_users(self,top_n: int = 10):
        """Generating top users from telegram chat
        """

        is_question = defaultdict(bool)
        for msg in self.chat_data['messages']:
            if not isinstance(msg['text'], str):
                msg['text'] = self.rebuild_msg(msg['text'])

            sentences = sent_tokenize(msg['text'])
            for sentence in sentences:
                if ('?' not in sentence) and ('؟' not in sentence):
                    continue

                is_question[msg['id']] = True
                break

        logger.info(" Genetaing top users...")

        users=[]
        for msg in self.chat_data['messages']:
            if not msg.get('reply_to_message_id'):
                continue

            if is_question[msg['reply_to_message_id']] is False:
                continue

            users.append(msg['from'])

        return dict(Counter(users).most_common(top_n))

    def generate_word_cloud(self, output_dir:Union[str, Path]):
        """ generates a word cloud from the chat data

        Args:
            output_dir (Union[str, Path]): path to output directory for word cloud image
        """
        logger.info(" loading text content... ")
        text_content=''

        for msg in self.chat_data['messages']:
            if type(msg['text']) is str:
                tokens = word_tokenize(msg['text'])
                tokens = list(filter(lambda item:item not in self.stop_words,tokens))
                text_content += f" {' '.join(tokens)}"

        #normalize, reshape for final word cloud

        text_content = arabic_reshaper.reshape(self.de_emojify(text_content))
        text_content=self.normalizer.normalize(text_content)

        #generate word cloud
        logger.info(" generating word cloud... ")
        wordcloud = WordCloud(
            width=1200, height=1200,
            font_path=str(DATA_DIR /'Vazirmatn-Light.ttf'),
            background_color='white',
            max_font_size=150
            ).generate(text_content)

        logger.info(f" saving wordcloud to {output_dir} ")
        wordcloud.to_file(str(Path(output_dir) / "wordcloud.png"))

if __name__ == '__main__':
    chat_stats=Chat_Statistics(chat_json = DATA_DIR / 'chat.json')
    chat_stats.generate_word_cloud(output_dir= DATA_DIR)
    top_users = chat_stats.get_top_users(top_n=10)

    print(top_users)
    print('Done !')


class Graph:
	def __init__(self, vertices):
		super(Graph, self).__init__()
		self.V = vertices
		self.graph = [[0 for _ in range(vertices)] for _ in range(vertices)]
	def min_dist(self,dist,sptSet):
		mn = float('inf')
		mi = -1
		for v in range(self.V):
			if dist[v]<mn and sptSet[v]==False:
				mn = dist[v]
				mi = v
		return mi

	def dijkstra(self,src,dest,depend):
		dist = [float('inf')]*self.V
		dist[src] = 0
		sptSet = [False]*self.V
		for i in range(self.V):
			u = self.min_dist(dist,sptSet)
			if u==-1:
				return -1
			if depend.get(u,-1)!=-1 and sptSet[depend[u]]==False:
				dist[u] = float('inf')
				continue
			sptSet[u] = True
			if sptSet[dest]:
				return dist[dest]
			for v in range(self.V):
				if self.graph[u][v]>0 and sptSet[v]==False and dist[v]>dist[u]+self.graph[u][v]:
					dist[v] = dist[u]+self.graph[u][v]
		return -1

def main():
	N,E,K = map(int,input().split())
	adj_mat = [[0 for _ in range(N)] for _ in range(N)]
	for _ in range(E):
		r,c,w = map(int,input().split())
		adj_mat[r-1][c-1] = w
		adj_mat[c-1][r-1] = w
	depend = dict()
	for _ in range(K):
		L,U = map(int,input().split())
		depend[U-1] = L-1
	g = Graph(N)
	g.graph = adj_mat
	print(g.dijkstra(0,N-1,depend))

if __name__ == '__main__':
	main()


""" Utilities module.
"""

import datetime as dt

import pkg_resources

import barbante

def local_import(name):
    """ Returns the module *name*.

        Attributes:
            name - the name of the module to be imported.

        Exception:
            TypeError - if *name* is not a string.
            ImportError - if there is no module *name* in your namespace.
    """
    if type(name) is not str:
        raise TypeError("barbante.api.recommend: name must be a string.")
    try:
        mod = __import__(name)
    except ImportError:
        raise ImportError(
            "barbante.api.recommend: there is no module name {0}".format(name))
    components = name.split('.')
    for comp in components[1:]:
        mod = getattr(mod, comp)
    return mod

def resource_stream(resource_path, package=barbante.__name__):
    """ Encapsulates pkg_resources.resource_stream.
    """
    return pkg_resources.resource_stream(package, resource_path)

def resource_filename(resource_path, package=barbante.__name__):
    """ Encapsulates pkg_resources.resource_filename.
    """
    return pkg_resources.resource_filename(package, resource_path)

def parse_date_series(series, date_format, queue=None):
    """ Implements pandas' apply function.

        **Parameters**
            date - date string in some format, e.g.: 31/12/2014.

            date_format - string format for *date*, e.g.: %d/%m/%Y %H:%M:%S.

            queue - multiprocessing.Queue for returning results.
    """
    new_series = series.apply(string_to_date, args=[date_format])
    if queue is not None:
        queue.put(new_series)

def parse_date_list(*args):
    """ Replaces pandas' *apply* function.

        :param args: (date_list,
                      start_index,
                      end_index,
                      date string in some format, e.g.: 31/12/2014,
                      string format for *date*, e.g.: %d/%m/%Y %H:%M:%S,
                      multiprocessing.Queue for returning results)
    """
    date_list = args[0]
    queue = args[1]
    date_format = args[2]
    new_series = []
    for date in date_list:
        new_series.append(string_to_date(date, date_format))

    queue.put(new_series)

def string_to_date(date, date_format):
    """ Returns the Unix date format from pandas.datetime.

        **Parameters**
        date - date string in some format, e.g.: 31/12/2014.

        date_format - string format for *date*, e.g.: %d/%m/%Y %H:%M:%S.
    """
    try:
        # return int(time.mktime(dt.datetime.strptime(date,
        # date_format).timetuple()))
        return dt.datetime.strptime(date, date_format)
    except TypeError:
        return

def flatten_dict(product_model_dict):
    """ Converts a dict with nested attributes into a flattened dict,
        where the path to each attribute in the original dict maps to
        a key in the new dict.

            > d = {'a': 1, 'b': {'c': 2, 'd': {'e': 3, 'f': 4}}}
            > ProductModel._flatten_dict(d)
            {'a': 1, 'b.c': 2, 'b.d.e': 3, 'b.d.f': 4}

        :param product_model_dict: the original dict.
        :returns: a flattened dict.
    """
    result = {}
    for key, value in product_model_dict.items():
        if isinstance(value, dict):
            subdict = flatten_dict(value)
            for sk, sv in subdict.items():
                result[key + '.' + sk] = sv
        else:
            result[key] = value
    return result


import requests
from twilio.rest import Client
from decouple import config

STOCK_NAME = "TSLA"
COMPANY_NAME = "Tesla Inc"
FUNCTION = "TIME_SERIES_DAILY"

MY_API = config("MY_API", default="")
NEW_API = config("NEW_API", default="")
TWILIO_SID = config("TWILIO_SID", default="")
TWILIO_TOKEN = config("TWILIO_TOKEN", default="")

STOCK_ENDPOINT = "https://www.alphavantage.co/query"
NEWS_ENDPOINT = "https://newsapi.org/v2/everything"

parameters = {
    "function": FUNCTION,
    "symbol": STOCK_NAME,
    "apikey": MY_API
}

response = requests.get(url=STOCK_ENDPOINT, params=parameters)
response.raise_for_status()

data = response.json()["Time Series (Daily)"]
data_list = [value for (key, value) in data.items()]
yesterday_data = data_list[0]
yesterday_closing_data = yesterday_data["4. close"]
print(yesterday_closing_data)

day_before_yesterday_data = data_list[1]
day_before_yesterday_closing_price = day_before_yesterday_data["4. close"]
print(day_before_yesterday_closing_price)

difference = float(yesterday_closing_data) - float(day_before_yesterday_closing_price)
up_down = None
if difference > 0:
    up_down = "up"
else:
    up_down = "down"

diff_percent = (difference / float(yesterday_closing_data)) * 100
print(diff_percent)

if abs(diff_percent) > .1:
    news_params = {
        "apiKey": NEW_API,
        "qInTitle": COMPANY_NAME
    }

    news_response = requests.get(url=NEWS_ENDPOINT, params=news_params)
    articles = news_response.json()["articles"]
    print(articles)

    three_articles = articles[:3]
    print(three_articles)

    formatted_articles = [f"{STOCK_NAME}: {up_down}{diff_percent}%\nHeadline: {article['title']}. "
                          f"\nBrief {article['description']}" for article in three_articles]

    client = Client(TWILIO_SID, TWILIO_TOKEN)

    for article in formatted_articles:
        message = client.messages.create(
            body=article,
            from_="TWILIO PHONE NUMBER",
            to="RECEPIENT PHONE NUMBER",
        )


import os
import random

import torch
import torchvision.transforms as T
from PIL import Image
from torch.utils import data

def rreplace(s, old, new, occurrence):
    li = s.rsplit(old, occurrence)
    return new.join(li)

class ImageAttr(data.Dataset):
    """Dataset class for the ImageAttr dataset."""
    def __init__(self, image_dir, attr_path, transform, mode,
                 binary=False, n_style=4,
                 char_num=52, unsuper_num=968, train_num=120, val_num=28):
        """Initialize and preprocess the ImageAttr dataset."""
        self.image_dir = image_dir
        self.attr_path = attr_path
        self.n_style = n_style

        self.transform = transform
        self.mode = mode
        self.binary = binary

        self.super_train_dataset = []
        self.super_test_dataset = []
        self.unsuper_train_dataset = []

        self.attr2idx = {}
        self.idx2attr = {}

        self.char_num = char_num
        self.unsupervised_font_num = unsuper_num
        self.train_font_num = train_num
        self.val_font_num = val_num

        self.test_super_unsuper = {}
        for super_font in range(self.train_font_num+self.val_font_num):
            self.test_super_unsuper[super_font] = random.randint(0, self.unsupervised_font_num - 1)

        self.char_idx_offset = 10

        self.chars = [c for c in range(self.char_idx_offset, self.char_idx_offset+self.char_num)]

        self.preprocess()

        if mode == 'train':
            self.num_images = len(self.super_train_dataset) + len(self.unsuper_train_dataset)
        else:
            self.num_images = len(self.super_test_dataset)

    def preprocess(self):
        """Preprocess the font attribute file."""
        lines = [line.rstrip() for line in open(self.attr_path, 'r')]
        all_attr_names = lines[0].split()
        for i, attr_name in enumerate(all_attr_names):
            self.attr2idx[attr_name] = i
            self.idx2attr[i] = attr_name

        lines = lines[1:]

        train_size = self.char_num * self.train_font_num
        val_size = self.char_num * self.val_font_num

        for i, line in enumerate(lines):
            split = line.split()
            filename = split[0]
            values = split[1:]
            target_char = filename.split('/')[1].split('.')[0]
            char_class = int(target_char) - self.char_idx_offset
            font_class = int(i / self.char_num)

            attr_value = []
            for val in values:
                if self.binary:
                    attr_value.append(val == '1')
                else:
                    attr_value.append(eval(val) / 100.0)

            # print(filename, char_class, font_class, attr_value)

            if i < train_size:
                self.super_train_dataset.append([filename, char_class, font_class, attr_value])
            elif i < train_size + val_size:
                self.super_test_dataset.append([filename, char_class, font_class, attr_value])
            else:
                self.unsuper_train_dataset.append([filename, char_class, font_class, attr_value])

        print('Finished preprocessing the Image Attribute (Explo) dataset...')

    def __getitem__(self, index):
        """Return one image and its corresponding attribute label."""
        # dataset = self.super_train_dataset if self.mode == 'train' else self.super_test_dataset

        if self.mode == 'train':
            if index < len(self.super_train_dataset):
                filename_A, charclass_A, fontclass_A, attr_A = self.super_train_dataset[index]
                label_A = 1.0
                font_embed_A = self.unsupervised_font_num  # dummy id 968
                # B is supervised or unsupervised
                sample_p = random.random()
                if sample_p < 0.5:
                    # Unsupervise
                    index_B = index % self.char_num + self.char_num * random.randint(0, self.unsupervised_font_num - 1)
                    filename_B, charclass_B, fontclass_B, attr_B = self.unsuper_train_dataset[index_B]
                    label_B = 0.0
                    font_embed_B = fontclass_B - self.train_font_num - self.val_font_num  # convert to [0, 967]
                else:
                    # Supervise
                    # get B from supervise train !!
                    index_B = index % self.char_num + self.char_num * random.randint(0, self.train_font_num - 1)
                    filename_B, charclass_B, fontclass_B, attr_B = self.super_train_dataset[index_B]
                    label_B = 1.0
                    font_embed_B = self.unsupervised_font_num  # dummy id 968

            else:
                # get A from unsupervise train !!
                index = index - len(self.super_train_dataset)
                filename_A, charclass_A, fontclass_A, attr_A = self.unsuper_train_dataset[index]
                label_A = 0.0
                font_embed_A = fontclass_A - self.train_font_num - self.val_font_num
                # B is supervised or unsupervised
                sample_p = random.random()
                if sample_p < 0.5:
                    # Unsupervise
                    index_B = index % self.char_num + self.char_num * random.randint(0, self.unsupervised_font_num - 1)  # noqa
                    filename_B, charclass_B, fontclass_B, attr_B = self.unsuper_train_dataset[index_B]
                    label_B = 0.0
                    font_embed_B = fontclass_B - self.train_font_num - self.val_font_num  # convert to [0, 967]
                else:
                    # Supervise
                    # get B from supervise train !!
                    index_B = index % self.char_num + self.char_num * random.randint(0, self.train_font_num - 1)
                    filename_B, charclass_B, fontclass_B, attr_B = self.super_train_dataset[index_B]
                    label_B = 1.0
                    font_embed_B = self.unsupervised_font_num  # dummy id 968

        else:
            # load the random one from unsupervise data as the reference aka A
            # unsuper to super
            font_index_super = index // self.char_num + self.train_font_num
            font_index_unsuper = self.test_super_unsuper[font_index_super]
            char_index_unsuper = index % self.char_num + self.char_num * font_index_unsuper
            filename_A, charclass_A, fontclass_A, attr_A = self.unsuper_train_dataset[char_index_unsuper]
            label_A = 0.0
            font_embed_A = fontclass_A - self.train_font_num - self.val_font_num  # convert to [0, 967]

            filename_B, charclass_B, fontclass_B, attr_B = self.super_test_dataset[index]
            label_B = 1.0
            font_embed_B = self.unsupervised_font_num  # dummy id 968

        # Get style samples
        random.shuffle(self.chars)
        style_chars = self.chars[:self.n_style]
        styles_A = []
        if self.n_style == 1:
            styles_A.append(filename_A)
        else:
            for char in style_chars:
                styles_A.append(rreplace(filename_A, str(charclass_A+10), str(char), 1))

        random.shuffle(self.chars)
        style_chars = self.chars[:self.n_style]
        styles_B = []
        if self.n_style == 1:
            styles_B.append(filename_B)
        else:
            for char in style_chars:
                styles_B.append(rreplace(filename_B, str(charclass_B+10), str(char), 1))

        image_A = Image.open(os.path.join(self.image_dir, filename_A)).convert('RGB')
        image_B = Image.open(os.path.join(self.image_dir, filename_B)).convert('RGB')
        # Open and transform style images
        style_imgs_A = []
        for style_A in styles_A:
            style_imgs_A.append(self.transform(Image.open(os.path.join(self.image_dir, style_A)).convert('RGB')))
        style_imgs_A = torch.cat(style_imgs_A)
        style_imgs_B = []
        for style_B in styles_B:
            style_imgs_B.append(self.transform(Image.open(os.path.join(self.image_dir, style_B)).convert('RGB')))
        style_imgs_B = torch.cat(style_imgs_B)

        return {"img_A": self.transform(image_A), "charclass_A": torch.LongTensor([charclass_A]),
                "fontclass_A": torch.LongTensor([fontclass_A]), "attr_A": torch.FloatTensor(attr_A),
                "styles_A": style_imgs_A,
                "fontembed_A": torch.LongTensor([font_embed_A]),
                "label_A": torch.FloatTensor([label_A]),
                "img_B": self.transform(image_B), "charclass_B": torch.LongTensor([charclass_B]),
                "fontclass_B": torch.LongTensor([fontclass_B]), "attr_B": torch.FloatTensor(attr_B),
                "styles_B": style_imgs_B,
                "fontembed_B": torch.LongTensor([font_embed_B]),
                "label_B": torch.FloatTensor([label_B])}

    def __len__(self):
        """Return the number of images."""
        return self.num_images

def get_loader(image_dir, attr_path, image_size=256,
               batch_size=16, dataset_name='explor_all', mode='train', num_workers=8,
               binary=False, n_style=4,
               char_num=52, unsuper_num=968, train_num=120, val_num=28):
    """Build and return a data loader."""
    transform = []
    transform.append(T.Resize(image_size))
    transform.append(T.ToTensor())
    transform.append(T.Normalize(mean=(0.5, 0.5, 0.5), std=(0.5, 0.5, 0.5)))
    transform = T.Compose(transform)

    if dataset_name == 'explor_all':
        dataset = ImageAttr(image_dir, attr_path, transform,
                            mode, binary, n_style,
                            char_num=52, unsuper_num=968,
                            train_num=120, val_num=28)
    data_loader = data.DataLoader(dataset=dataset,
                                  drop_last=True,
                                  batch_size=batch_size,
                                  shuffle=(mode == 'train'),
                                  num_workers=num_workers)

    return data_loader


# importing other files
import color
import TestTubeGame

# This is the test tube class for the minigame.
# Things it should be capable of:
# - Drawing itself (It needs to know what colours it has)
class TestTube:

    # This function initializes the variables of the test tube
    def __init__(self, stack):
        self.volume = TestTubeGame.VOLUME
        self.stack = stack

    # This function is intended to count the amount of volume in the test tube
    def checkvolume(self):

        #sum will be equal to the actial volume in the stack
        sum = len(self.stack)

        # making sure that the correct volume is in the test tube
        if sum > self.volume:
            raise Exception("The volume counted is greater than the max volume.")
        elif sum < 0:
            raise Exception("The volume counted is smaller than zero.")
        return sum

    #This method checks if the most recent color is equal to the parameter
    def iscoloursame(self, rgb):

        if not bool(self.stack):
            return True
        elif self.stack[-1].colour == rgb.colour:
            return True
        else:
            return False

    # This function is meant to add a colour to the test tube
    def addcolor(self, rgb):
        self.checkvolume()
        if self.iscoloursame(rgb):
            self.stack.append(rgb)
            self.checkvolume()
            return True
        else:
            return False

    # This function is meant to remove the top colour from the test tube
    def removecolor(self, rgb):
        self.checkvolume()
        if self.iscoloursame(rgb):
                    self.stack.pop()
                    self.checkvolume()
                    return True
        else:
            print("Those colours are not the same.")
            return False

    def forceaddcolor(self, rgb):
            self.stack.append(rgb)

    # This function is meant to remove the top colour from the test tube
    def forceremovecolor(self, rgb):
            self.stack.pop()

    # This function returns the colour at the top of the stack
    def topcolour(self):
        if not bool(self.stack):
            return color.Colour(TestTubeGame.WHITE)
        else:
            return self.stack[-1]

    # This function returns whether or not the stack is complete
    def iscomplete(self):

        # making a for loop to check if a test tube is full of one colour or empty
        recentcolour = self.topcolour()
        if self.isempty():
            return True
        if len(self.stack) == TestTubeGame.VOLUME:
            for x in range(0,len(self.stack)):
                if self.stack[x].colour == recentcolour.colour:
                    pass
                else:
                    return False
            return True
        else:
            return False

    # This fuction checks specifically if a tube is empty
    def isempty(self):
        if bool(self.stack):
            return False
        else:
            return True

    #This method will empty a testube
    def empty(self):
        for x in self.stack:
            self.stack.pop()


"""
For example, two is written as II in Roman numeral, just two one's added together. Twelve is written as, XII, which is simply X + II. The number twenty seven is written as XXVII, which is XX + V + II.

Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:

I can be placed before V (5) and X (10) to make 4 and 9.
X can be placed before L (50) and C (100) to make 40 and 90.
C can be placed before D (500) and M (1000) to make 400 and 900.
Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999.

"""

class Solution:
    def __init__(self):
        self.ref = [
            (1000, "M"),
            (900, "CM"),
            (500, "D"),
            (400, "CD"),
            (100, "C"),
            (90, "XC"),
            (50, "L"),
            (40, "XL"),
            (10, "X"),
            (9, "IX"),
            (5, "V"),
            (4, "IV"),
            (3, "III"),
            (2, "II"),
            (1, "I")
        ]

        self.map = {
            "M": 1000,
            "D": 500,
            "C": 100,
            "L": 50,
            "X": 10,
            "V": 5,
            "III": 3,
            "II": 2,
            "I": 1
        }

    def toRoman(self, x):
        roman = ""

        while x > 0:
            for i, r in self.ref:
                #print(i, r)
                while x >= i:
                    #print("check {}, {}".format(i,r))
                    roman += r
                    x -= i

        return roman

    def getValue(self, x):
        try:
            return self.map[x]
        except KeyError as k:
            print("Invalid key: ", k)
            exit

    def toInt(self, s):
        num = 0
        i = 0
        while i < len(s):
            current = self.getValue(s[i])

            if (i+1) < len(s):
                next = self.getValue(s[i+1])

                if current >= next:
                    num = num + current
                    i = i+1
                else:
                    num = num + next - current
                    i = i + 2

            else:
                num = num + current
                i = i + 1

        return num

if __name__ == "__main__":
    s = Solution()
    #print(s.toRoman(12))

    print(s.toInt("MCDIVIT"))


from pykeyboard import PyKeyboard
import paho.mqtt.client as mqtt
import re

host = 'www.bananalife.top'
port = 1883
'''
ctrl+alt+p   play/suspend
ctrl+alt+H   left
ctrl+alt+L   right
ctrl+alt+J   down
ctrl+alt+K   up
'''
k = PyKeyboard()
netcase = {
    'play': [k.control_key, k.alt_key, 'p'],
    'left': [k.control_key, k.alt_key, 'h'],
    'right': [k.control_key, k.alt_key, 'l'],
    'down': [k.control_key, k.alt_key, 'j'],
    'up': [k.control_key, k.alt_key, 'k'],
}

#

def on_connect(client, userdata, flags, rc):
    print("Connected with result code " + str(rc))

    # Subscribing in on_connect() means that if we lose the connection and
    # reconnect then subscriptions will be renewed.
    # client.subscribe("$SYS/#")
    client.subscribe('console')

# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    data = str(msg.payload)
    print(msg.topic + " " + data)
    for i in netcase:
        find = re.findall(i, data)
        if find:
            k.press_keys(netcase[i])
            return

client = mqtt.Client(client_id='zengfupc', clean_session=True);
client.on_connect = on_connect
client.on_message = on_message

client.connect(host, port)

client.loop_forever()


from bokeh.plotting import figure
from bokeh.io import curdoc
from bokeh.models import GeoJSONDataSource, ColorBar
from bokeh.models import DatetimeTickFormatter, PrintfTickFormatter, NumeralTickFormatter, NumeralTickFormatter
from bokeh.models import HoverTool, WheelZoomTool
from bokeh.models import LogColorMapper, LinearColorMapper
from bokeh.models import BasicTicker
from bokeh.models import Label
from app import config as cfg
from app import constants as cts
from app import data

def plot_map(ds, palette=cts.MAP_PALLETE, breeze=cfg.MAP_BREEZE):
    """Plot cases map."""

    # Calculating map bounds
    minx, miny, maxx, maxy = ds.total_bounds
    x_range = maxx - minx
    y_range = maxy - miny
    ar = (maxx - minx) / (maxy - miny)
    x_range = (minx - breeze * x_range, maxx + breeze * x_range)
    y_range = (miny - breeze * y_range, maxy + breeze * y_range)

    # Preparing data
    ds = GeoJSONDataSource(geojson=ds.to_json())
    tools = "pan,reset,save"
    color_mapper = LogColorMapper(palette=tuple(reversed(palette)))

    color_bar = ColorBar(color_mapper=color_mapper, major_label_text_font_size="7px",
                     ticker=BasicTicker(desired_num_ticks=len(tuple(reversed(palette)))),
                     label_standoff=6, border_line_color=None, location=(0, 0))

    p = figure(tools=tools, x_range=x_range, y_range=y_range, aspect_ratio=ar,
               x_axis_location=None, y_axis_location=None, match_aspect=True)

    p.grid.grid_line_color = None
    p.toolbar.logo = None
    p.add_layout(color_bar, 'right')

    p.patches('xs', 'ys', fill_alpha=0.7,
              fill_color={'field': 'total_color', 'transform': color_mapper},
              line_color='gray', line_width=0.25, source=ds)

    p.add_tools(HoverTool(tooltips=cts.MAP_TOOLTIP,
                          point_policy="follow_mouse",
                          toggleable=False))
    # Adding zoom tool
    wheel_zoom = WheelZoomTool(zoom_on_axis=False)
    p.add_tools(wheel_zoom)
    p.toolbar.active_scroll = wheel_zoom

    # Applying theme
    doc = curdoc()
    doc.theme = cfg.THEME
    return p


from Queue import Queue
class Binary_Search_Tree:
    def __init__(self, data):
        self.data = data
        self.left_child = None
        self.right_child = None

def insert(root_node, value):
    if root_node.data is None:
        root_node.data = value
    else:
        if value <= root_node.data:
            if root_node.left_child is None:
                root_node.left_child = Binary_Search_Tree(value)
            else:
                insert(root_node.left_child, value)
        else:
            if root_node.right_child is None:
                root_node.right_child = Binary_Search_Tree(value)
            else:
                insert(root_node.right_child, value)
    return "value successfully inserted"

def preOrder_traversal(root_node):
    if not root_node:
        return
    else:
        print(root_node.data)
        preOrder_traversal(root_node.left_child)
        preOrder_traversal(root_node.right_child)

def inOrder_traversal(root_node):
    if not root_node:
        return
    else:
        inOrder_traversal(root_node.left_child)
        print(root_node.data)
        inOrder_traversal(root_node.right_child)

def postOrder_traversal(root_node):
    if not root_node:
        return
    else:
        postOrder_traversal(root_node.left_child)
        postOrder_traversal(root_node.right_child)
        print(root_node.data)

def levelOrder_traversal(root_node):
    if not root_node:
        return
    else:
        queue = Queue()
        queue.enqueue(root_node)
        while not queue.is_empty():
            root = queue.dequeue()
            print(root.data)
            if root.left_child:
                queue.enqueue(root.left_child)
            if root.right_child:
                queue.enqueue((root.right_child))

def searching(root_node, value):
    if root_node is None:
        print("value does not exist")
    elif root_node.data == value:
        print("Found")
    elif value < root_node.data:
        if root_node.left_child == value:
            print("Found")
        else:
            searching(root_node.left_child, value)
    else:
        if root_node.right_child == value:
            print("Found")
        else:
            searching(root_node.right_child, value)

def minimum_value(root_node):
    if root_node is None:
        return
    else:
        current = root_node
        while not current.left_child:
            current = current.left_child
        return current

def delete_node(root_node, value):
    if root_node is None:
        return root_node
    if value < root_node.data:
        root_node.left_child = delete_node(root_node.left_child, value)
    elif value > root_node.data:
        root_node.right_child = delete_node(root_node.right_child, value)
    else:
        if root_node.left_child is None:
            return root_node.right_chid
        else:
            if root_node.right_child is None:
                return root_node.left_child
        temp = minimum_value(root_node.right_child)
        root_node.data = temp.data
        root_node.right_child = delete_node(root_node.right_child, temp.data)
    return root_node

def delete_entire_binary_search_tree(binary_search_tree):
    binary_search_tree.data = None
    binary_search_tree.left_child = None
    binary_search_tree.right_child = None

binary_search_tree = Binary_Search_Tree(None)

if __name__ == "__main__":
    insert(binary_search_tree, 50)
    insert(binary_search_tree, 60)
    insert(binary_search_tree, 40)
    insert(binary_search_tree, 30)
    insert(binary_search_tree, 80)
    levelOrder_traversal(binary_search_tree)
    delete_node(binary_search_tree, 40)
    levelOrder_traversal(binary_search_tree)
    # delete_entire_binary_search_tree(binary_search_tree)
    # levelOrder_traversal(binary_search_tree)

19 - Binary Search Tree/Binary Search Tree Practice/05 Deletion in a Binary Search Tree.py