# Version 1.0.1

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
from sklearn import linear_model

#--------------------------------------------------------------------------------------------------
class EBM(object):

    def __init__(self, F=7.65, lbda=1.25, c=9.844, c_0=133.325, gam=0.70, epsi=1.0, xCO2=4):
        self.F = F
        self.lbda = lbda
        self.c = c
        self.c_0 = c_0
        self.gam = gam
        self.epsi = epsi
        self.xCO2 = xCO2

    def __str__(self):
        param = self.parameters()
        xstr = 'F = %5.2f W/m2; lbda = %5.2f W/m2/K : ECS = %5.2f K'%(self.F, self.lbda, self.F/self.lbda)
        # xstr += '\n'
        # xstr += 'c = %5.1f; c_0 = %5.1f'%(self.c, self.c_0)
        xstr += '\n'
        xstr += 'gam = %4.2f; epsi = %4.2f'%(self.gam, self.epsi)
        # xstr += '\n'
        # xstr += 'a_f = %4.2f; a_s = %4.2f'%(param['a_f'], param['a_s'])
        xstr += '\n'
        xstr += 'tau_f = %4.2f; tau_s = %4.2f; tau_e = %4.2f'%(param['tau_f'], param['tau_s'], param['tau_e'])
        return xstr

    def parameters(self):
        #
        gammprim = self.epsi * self.gam
        c0prim   = self.epsi * self.c_0
        #
        b     = (self.lbda + gammprim)/self.c + gammprim/c0prim
        bstar = (self.lbda + gammprim)/self.c - gammprim/c0prim
        delta = b*b - 4*(self.lbda*gammprim)/(self.c*c0prim)
        # Constants
        phi_f = self.c/(2*gammprim)*(bstar - np.sqrt(delta))
        phi_s = self.c/(2*gammprim)*(bstar + np.sqrt(delta))
        # Relaxation times
        tau_f = (self.c*c0prim)/(2*self.lbda*gammprim)*(b - np.sqrt(delta))
        tau_s = (self.c*c0prim)/(2*self.lbda*gammprim)*(b + np.sqrt(delta))
        # ECS contributions
        a_f   =  (phi_s*tau_f*self.lbda)/(self.c*(phi_s - phi_f))
        a_s   = -(phi_f*tau_s*self.lbda)/(self.c*(phi_s - phi_f))
        # Outputs
        param = {}
        param['tau_f'] = tau_f
        param['tau_s'] = tau_s
        param['a_f']   = a_f
        param['a_s']   = a_s
        param['phi_f'] = phi_f
        param['phi_s'] = phi_s
        param['tau_e'] = a_f*tau_s + a_s*tau_f
        return param

    def plot(self, myForcing, n_years, lplotFNH = False):
        output = analytical_EBM(self, myForcing, n_years)
        x = np.arange(n_years+1)
        plt.figure()
        plt.grid(True)
        plt.plot(x, output['T'], linestyle='-', color='k')
        plt.plot(x, output['T0'], linestyle='--', color='k')
        plt.plot(x, output['termI'], linestyle='-', color='r')
        plt.plot(x, output['termF'], linestyle='-', color='g')
        plt.plot(x, output['termS'], linestyle='-', color='b')
        plt.plot(x, output['termE'], linestyle='-', color='c')
        plt.plot(x, output['term0F'], linestyle='--', color='g')
        plt.plot(x, output['term0S'], linestyle='--', color='b')
        plt.plot(x, output['term0E'], linestyle='--', color='c')
        if lplotFNH:
            plt.plot(x, output['N'], '.', color='r', alpha=0.8)
            plt.plot(x, output['F'], '.', color='g', alpha=0.8)
            plt.plot(x, output['H'], '.', color='b', alpha=0.8)

#--------------------------------------------------------------------------------------------------
class FORCING(object):
    def __init__(self, typ='abrupt', t_0=0, xCO2_0=0, tau_e=0, xCO2_infty=4, k_=1/140, t_m=0, xCO2_m=0):
        self.typ = typ
        self.t_0 = t_0
        self.xCO2_0 = xCO2_0
        self.tau_e = tau_e
        self.xCO2_infty = xCO2_infty
        self.t_m = t_m
        self.xCO2_m = xCO2_m
        self.k_ = k_

#--------------------------------------------------------------------------------------------------
def optimal_t0(tau_s, x_0, x_infty):
    return np.int(-tau_s*np.log(1.0 - np.log(x_infty)/np.log(x_0)))

def optimal_x0(tau_e, tau_s, x_infty):
    return np.exp(tau_s/tau_e*np.log(x_infty))

def analytical_EBM(myEBM, myFORCING, n_years=150, lprint=False):

    # temporal axis
    t_ = np.arange(n_years+1, dtype=np.float)

    # myEBM
    forc = myEBM.F
    lbda = myEBM.lbda
    c = myEBM.c
    c_0 = myEBM.c_0
    gam = myEBM.gam
    epsi = myEBM.epsi
    xCO2 = myEBM.xCO2

    paramEBM = myEBM.parameters()
    phi_f = paramEBM['phi_f']
    phi_s = paramEBM['phi_s']
    tau_f = paramEBM['tau_f']
    tau_s = paramEBM['tau_s']
    a_f = paramEBM['a_f']
    a_s = paramEBM['a_s']

    # myFORCING
    typforcing = myFORCING.typ
    t_0 = myFORCING.t_0
    xCO2_0 = myFORCING.xCO2_0
    tau_e = myFORCING.tau_e
    xCO2_infty = myFORCING.xCO2_infty
    t_m = myFORCING.t_m
    xCO2_m = myFORCING.xCO2_m
    k_ = myFORCING.k_

    # from xCO2 to forcing
    F_infty = forc / np.log(xCO2) * np.log(xCO2_infty)
    F_m     = forc / np.log(xCO2) * np.log(xCO2_m)
    F_0     = forc / np.log(xCO2) * np.log(xCO2_0)

    output = {}

    if typforcing == 'abrupt':
        if lprint:
            print('-----------------------------------------------')
            print('ABRUPT : F = F_infty')
            print('-----------------------------------------------')
            print('F_infty = %5.2f W/m2 (xCO2_infty = %4.1f)'%(F_infty, xCO2_infty))
            print('-----------------------------------------------')

        F = np.full_like(t_, F_infty, dtype=np.float)

        termI  = F / lbda
        termF  = - c_step(F_infty, lbda, a_f)*np.exp(-t_/tau_f)
        termS  = - c_step(F_infty, lbda, a_s)*np.exp(-t_/tau_s)
        term0F = - c_step(F_infty, lbda, phi_f*a_f)*np.exp(-t_/tau_f)
        term0S = - c_step(F_infty, lbda, phi_s*a_s)*np.exp(-t_/tau_s)
        termE  = np.zeros(n_years+1)
        term0E = np.zeros(n_years+1)

    elif typforcing == 'linear':
        if lprint:
            print('-----------------------------------------------')
            print('LINEAR : F = k_ * t_ * F_infty')
            print('-----------------------------------------------')
            print('F_infty = %5.2f W/m2 (xCO2_infty = %4.1f)'%(F_infty, xCO2_infty))
            print('k_ = %5.2f'%k_)
            print('-----------------------------------------------')

        F = k_ * t_ * F_infty

        termI  = F / lbda
        termF  = c_linear(F_infty, k_, lbda, a_f, tau_f)*(np.exp(-t_/tau_f) - 1)
        termS  = c_linear(F_infty, k_, lbda, a_s, tau_s)*(np.exp(-t_/tau_s) - 1)
        term0F = c_linear(F_infty, k_, lbda, phi_f*a_f, tau_f)*(np.exp(-t_/tau_f) - 1)
        term0S = c_linear(F_infty, k_, lbda, phi_s*a_s, tau_s)*(np.exp(-t_/tau_s) - 1)
        termE  = np.zeros(n_years+1)
        term0E = np.zeros(n_years+1)

    elif typforcing == 'double_abrupt' :
        if lprint:
            print('-----------------------------------------------')
            print('DOUBLE ABRUPT : F[:t_0]=F_0 and F[t_0:]=F_infty')
            print('-----------------------------------------------')
            print('t_0 = %i'%t_0)
            print('F_0 = %5.2f W/m2 (xCO2_0 = %4.1f)'%(F_0, xCO2_0))
            print('F_infty = %5.2f W/m2 (xCO2_infty = %4.1f)'%(F_infty, xCO2_infty))
            print('-----------------------------------------------')

        tt_1 = np.arange(0, t_0+1)
        tt_2 = np.arange(t_0+1, n_years+1)

        F = np.zeros(n_years+1)
        F[tt_1] = F_0
        F[tt_2] = F_infty

        termI  = np.zeros(n_years+1)
        termF  = np.zeros(n_years+1)
        termS  = np.zeros(n_years+1)
        term0F = np.zeros(n_years+1)
        term0S = np.zeros(n_years+1)
        termE  = np.zeros(n_years+1)
        term0E = np.zeros(n_years+1)

        # Part 1 : tt_1 = [0:t_0]
        output_ab0   = analytical_EBM(myEBM, FORCING(typ='abrupt', xCO2_infty=xCO2_0), t_0)
        termI[tt_1]  = output_ab0['termI']
        termF[tt_1]  = output_ab0['termF']
        termS[tt_1]  = output_ab0['termS']
        term0F[tt_1] = output_ab0['term0F']
        term0S[tt_1] = output_ab0['term0S']

        # Part 2 : tt_2 = [t_0+1:n_years]
        termI[tt_2]  = F_infty/lbda
        termF[tt_2]  = c_2step(F_0, F_infty, t_0, lbda, a_f, tau_f)*np.exp(-t_[tt_2]/tau_f)
        termS[tt_2]  = c_2step(F_0, F_infty, t_0, lbda, a_s, tau_s)*np.exp(-t_[tt_2]/tau_s)
        term0F[tt_2] = c_2step(F_0, F_infty, t_0, lbda, phi_f*a_f, tau_f)*np.exp(-t_[tt_2]/tau_f)
        term0S[tt_2] = c_2step(F_0, F_infty, t_0, lbda, phi_s*a_s, tau_s)*np.exp(-t_[tt_2]/tau_s)

    elif typforcing == 'triple_abrupt' :
        if lprint:
            print('-----------------------------------------------')
            print('TRIPLE ABRUPT : F[:t_0]=F_0, F[t_0:t_m]=F_m')
            print('                F[t_m:]=F_infty')
            print('-----------------------------------------------')
            print('t_0 = %i'%t_0)
            print('F_0 = %5.2f W/m2 (xCO2_0 = %4.1f)'%(F_0, xCO2_0))
            print('t_m = %i'%t_m)
            print('F_m = %5.2f W/m2 (xCO2_m = %4.1f)'%(F_m, xCO2_m))
            print('F_infty = %5.2f W/m2 (xCO2_infty = %4.1f)'%(F_infty, xCO2_infty))
            print('-----------------------------------------------')

        tt_1 = np.arange(0, t_0+1)
        tt_2 = np.arange(t_0+1, t_m+1)
        tt_3 = np.arange(t_m+1, n_years+1)

        F = np.zeros(n_years+1)
        F[tt_1] = F_0
        F[tt_2] = F_m
        F[tt_3] = F_infty

        termI  = np.zeros(n_years+1)
        termF  = np.zeros(n_years+1)
        termS  = np.zeros(n_years+1)
        term0F = np.zeros(n_years+1)
        term0S = np.zeros(n_years+1)
        termE  = np.zeros(n_years+1)
        term0E = np.zeros(n_years+1)

        # Part 1 : tt_1 = [0:t_0]
        output_ab0   = analytical_EBM(myEBM, FORCING(typ='abrupt', xCO2_infty=xCO2_0), t_0)
        termI[tt_1]  = output_ab0['termI']
        termF[tt_1]  = output_ab0['termF']
        termS[tt_1]  = output_ab0['termS']
        term0F[tt_1] = output_ab0['term0F']
        term0S[tt_1] = output_ab0['term0S']

        # Part 2 : tt_2 = [t_0+1:t_m]
        termI[tt_2]  = F_m/lbda
        termF[tt_2]  = c_2step(F_0, F_m, t_0, lbda, a_f, tau_f)*np.exp(-t_[tt_2]/tau_f)
        termS[tt_2]  = c_2step(F_0, F_m, t_0, lbda, a_s, tau_s)*np.exp(-t_[tt_2]/tau_s)
        term0F[tt_2] = c_2step(F_0, F_m, t_0, lbda, phi_f*a_f, tau_f)*np.exp(-t_[tt_2]/tau_f)
        term0S[tt_2] = c_2step(F_0, F_m, t_0, lbda, phi_s*a_s, tau_s)*np.exp(-t_[tt_2]/tau_s)

        # Part 3 : tt_3 = [t_m+1:n_years]
        termI[tt_3]  = F_infty/lbda
        termF[tt_3]  = c_3step(F_0, F_m, F_infty, t_0, t_m, lbda, a_f, tau_f)*np.exp(-t_[tt_3]/tau_f)
        termS[tt_3]  = c_3step(F_0, F_m, F_infty, t_0, t_m, lbda, a_s, tau_s)*np.exp(-t_[tt_3]/tau_s)
        term0F[tt_3] = c_3step(F_0, F_m, F_infty, t_0, t_m, lbda, phi_f*a_f, tau_f)*np.exp(-t_[tt_3]/tau_f)
        term0S[tt_3] = c_3step(F_0, F_m, F_infty, t_0, t_m, lbda, phi_s*a_s, tau_s)*np.exp(-t_[tt_3]/tau_s)

    elif typforcing == 'expo' :
        if lprint:
            print('-----------------------------------------------')
            print('EXPONENTIAL : F = F_infty+(F_0-F_infty)*exp(-t_/tau_e)')
            print('-----------------------------------------------')
            print('F_infty = %5.2f W/m2 (xCO2_infty = %4.1f)'%(F_infty, xCO2_infty))
            print('F_0 = %5.2f W/m2 (xCO2_0 = %4.1f)'%(F_0, xCO2_0))
            print('tau_e = %i'%tau_e)
            print('-----------------------------------------------')

        F = F_infty + (F_0 - F_infty)*np.exp(-t_/tau_e)

        if tau_e == tau_s or tau_e == tau_f :
            print('>> Error')
            return None

        termI  = np.full_like(t_, F_infty/lbda, dtype=np.float)
        termS  = -(c_step(F_infty, lbda, a_s) + c_expo(F_0, F_infty, tau_e, lbda, a_s, tau_s))*np.exp(-t_/tau_s)
        termF  = -(c_step(F_infty, lbda, a_f) + c_expo(F_0, F_infty, tau_e, lbda, a_f, tau_f))*np.exp(-t_/tau_f)
        termE  = (c_expo(F_0, F_infty, tau_e, lbda, a_s, tau_s) + c_expo(F_0, F_infty, tau_e, lbda, a_f, tau_f))*np.exp(-t_/tau_e)
        term0S = -(c_step(F_infty, lbda, phi_s*a_s) + c_expo(F_0, F_infty, tau_e, lbda, phi_s*a_s, tau_s))*np.exp(-t_/tau_s)
        term0F = -(c_step(F_infty, lbda, phi_f*a_f) + c_expo(F_0, F_infty, tau_e, lbda, phi_f*a_f, tau_f))*np.exp(-t_/tau_f)
        term0E = (c_expo(F_0, F_infty, tau_e, lbda, phi_s*a_s, tau_s) + c_expo(F_0, F_infty, tau_e, lbda, phi_f*a_f, tau_f))*np.exp(-t_/tau_e)

    T = termI + termS + termF + termE
    T0 = termI + term0S + term0F + term0E
    H = gam*(T - T0)
    N = F - lbda*T - (epsi-1)*H

    output['F'] = F
    output['T'] = T
    output['T0'] = T0
    output['N'] = N
    output['H'] = H

    output['termI'] = termI
    output['termS'] = termS
    output['termF'] = termF
    output['termE'] = termE
    output['term0S'] = term0S
    output['term0F'] = term0F
    output['term0E'] = term0E

    output['normalized_T'] = T / (F_infty/lbda)
    output['normalized_T0'] = T0 / (F_infty/lbda)

    return output

#--------------------------------------------------------------------------------------------------
# Auxiliary functions for analytical_EBM
def c_step(F_infty, lbda, x_n):
    return x_n * F_infty/lbda

def c_linear(F_infty, k_, lbda, x_n, tau_n):
    return k_ * F_infty/lbda * tau_n * x_n

def c_2step(F_0, F_infty, t_0, lbda, x_n, tau_n):
    return x_n/lbda*((F_0 - F_infty)*np.exp(t_0/tau_n) - F_0)

def c_3step(F_0, F_m, F_infty, t_0, t_m, lbda, x_n, tau_n):
    return x_n/lbda*((F_m - F_infty)*np.exp(t_m/tau_n) + (F_0 - F_m)*np.exp(t_0/tau_n) - F_0)

def c_expo(F_0, F_infty, tau_e, lbda, x_n, tau_n):
    pi_n = 1.0 / (1.0 - tau_n/tau_e)
    return x_n/lbda*pi_n*(F_0 - F_infty)
#--------------------------------------------------------------------------------------------------

def derive_EBM_I(T, N, xCO2, nyr_s = 30, nyr_f = 10):

    n_years = T.size

    #--------------------------------------------------------------------------------------------------
    # 1. Estimation of F and lambda from Gregory plot (linear fit of N)
    #--------------------------------------------------------------------------------------------------
    slope, intercept, r_value, p_value, std_err = stats.linregress(T, N)
    lbda = - slope
    forc = intercept
    T_eq = forc / lbda

    #--------------------------------------------------------------------------------------------------
    # 2. Estimation of a_s and tau_s from fit of log(1 - T/T_eq) : see Eq. (17)
    #--------------------------------------------------------------------------------------------------
    t_i   = nyr_s
    x_    = np.arange(t_i, n_years)
    y_    = np.log(1 - T[t_i-1:n_years-1] / T_eq)
    slope, intercept, r_value, p_value, std_err = stats.linregress(x_, y_)
    tau_s = -1.0 / slope
    a_s   = np.exp(intercept)

    #--------------------------------------------------------------------------------------------------
    # 3. Estimation of tau_f by averaging over the first 10 years : see Eq. (18)
    #--------------------------------------------------------------------------------------------------
    a_f = 1 - a_s
    t_i = nyr_f
    t_  = np.arange(1, t_i)
    tau = t_ / (np.log(a_f) - np.log(1 - T[0:t_i-1]/T_eq - a_s*np.exp(-t_/tau_s)))
    tau_f = np.mean(tau)

    #--------------------------------------------------------------------------------------------------
    # 4. Derivation of c, c0 and gamma : see Eqs (19), (20) and (21)
    #--------------------------------------------------------------------------------------------------
    c   = lbda / (a_f / tau_f + a_s / tau_s)
    c_0 = lbda*(a_f*tau_f + a_s*tau_s) - c
    gam = c_0 / (a_s*tau_f + a_f*tau_s)

    output = EBM(F=forc, lbda=lbda, c=c, c_0=c_0, gam=gam, epsi=1.0, xCO2=xCO2)

    return output

def derive_EBM_II(T, N, xCO2):

    n_years = T.size

    #--------------------------------------------------------------------------------------------------
    # 0. set param to the EBM-1 values
    #--------------------------------------------------------------------------------------------------

    EBM_0 = derive_EBM_I(T, N, xCO2)

    forcage = FORCING(typ='abrupt', xCO2_infty=xCO2)

    datas_EBM = analytical_EBM(EBM_0, forcage, n_years)
    T0_EBM = datas_EBM['T0']
    T_EBM = datas_EBM['T']
    H_EBM = datas_EBM['H']

    n_iters = 10
    for iter in range(n_iters):

        X = np.c_[T, H_EBM[1:]]
        regr = linear_model.LinearRegression()
        regr.fit(X, N)
        forc = regr.intercept_
        lbda = - regr.coef_[0]
        epsi = 1 - regr.coef_[1]

        # print('=====>')
        # print(forc)
        # print(lbda)
        # print(epsi)
        # print('=====>')

        T_eq = forc / lbda

        t_i   = 80
        x_    = np.arange(t_i, n_years)
        y_    = np.log(1 - T[t_i-1:n_years-1] / T_eq)
        slope, intercept, r_value, p_value, std_err = stats.linregress(x_, y_)
        tau_s = -1.0 / slope
        a_s   = np.exp(intercept)

        a_f = 1 - a_s
        t_i = 6
        t_  = np.arange(1, t_i)
        tau = t_ / (np.log(a_f) - np.log(1 - T[0:t_i-1]/T_eq - a_s*np.exp(-t_/tau_s)))
        tau_f = np.mean(tau)

        c   = lbda / (a_f / tau_f + a_s / tau_s)
        c_0 = lbda*(a_f*tau_f + a_s*tau_s) - c
        gam = c_0 / (a_s*tau_f + a_f*tau_s)

        # print(c)
        # print(c_0)

        c_0 = c_0 / epsi
        gam = gam / epsi

        myEBM = EBM(F=forc, lbda=lbda, c=c, c_0=c_0, gam=gam, epsi=epsi, xCO2=xCO2)

        datas_EBM = analytical_EBM(myEBM, forcage, n_years)
        T0_EBM = datas_EBM['T0']
        T_EBM = datas_EBM['T']
        H_EBM = datas_EBM['H']

    output = EBM(F=forc, lbda=lbda, c=c, c_0=c_0, gam=gam, epsi=epsi, xCO2=xCO2)

    return output

def derive_ECS_from_EBM(iEBM, myT, myN, xCO2):
    if iEBM == 1:
        ebm = derive_EBM_I(myT, myN, xCO2)
        return ebm.F / ebm.lbda
    elif iEBM == 2:
        ebm = derive_EBM_II(myT, myN, xCO2)
        return ebm.F / ebm.lbda
    else:
        print('%i is not known')%iEBM
        return None

def derive_ECS_from_stab(myT, n_years):
    return np.mean(myT[-n_years:])


import time
import chat_test_ver1_voice_function
import chat_test_ver1_cleverbot_api_function

cleverbot_feedback_state = ["",""]

def chat_map_speak_re(last_voice ,cleverbot_feedback_state ,time_sleep ,chat_map_response ):
    feedback = chat_test_ver1_cleverbot_api_function.cleverbot_api_chatting_function(last_voice ,cleverbot_feedback_state[1])
    time.sleep(1.5)
    cleverbot_feedback_state[1] = feedback[1]
    cleverbot_feedback_state[0] = feedback[0]
    print(feedback)

    if feedback[0] != "" :

        print(feedback[0])
        chat_test_ver1_voice_function.function_speak(feedback[0])
        cleverbot_feedback_state = feedback
        time.sleep(time_sleep)

    else :

        speaks_nofeedback = "我想很久說還是不懂說，不好意思您剛說的話是:『{}』齁?，抱歉聽不是很清楚或網路太爛惹可以麻煩大大再說一次ㄇ".format(str(last_voice))
        print(speaks_nofeedback)
        chat_test_ver1_voice_function.function_speak(speaks_nofeedback)
        time.sleep(time_sleep)

##############
##############
    listenfile = chat_test_ver1_voice_function.function_listen()
    speaks_new_user_sentence = "您剛剛說:『{}』嗎，讓我想一下怎麼回答".format(listenfile)
    print(speaks_new_user_sentence)
    chat_test_ver1_voice_function.function_speak(speaks_new_user_sentence)
    time.sleep(0.3)
    chat_map_response(listenfile)
    return cleverbot_feedback_state


# -*- coding: utf-8 -*-
"""
HW1 Car problem

@author: Yoshihiro Obata
"""

# %% importing packages
import numpy as np
import pandas as pd
from ID3 import decisionTree, run_ID3, applyTree, apply_ID3
from testingTrees import tester
import matplotlib.pyplot as plt
import time

# %% importing the data and splitting it up
cols = list(pd.read_csv('car/data-desc.txt', skiprows=14))
train0 = pd.read_csv('car/train.csv', names=cols)
test0 = pd.read_csv('car/test.csv', names=cols)

attrTrain0 = np.array(train0.iloc[:,:-1])
attrTest0= np.array(test0.iloc[:,:-1])
attrNames0 = cols[:-1]
labelsTrain0 = np.array(train0.iloc[:,-1])
labelsTest0 = np.array(test0.iloc[:,-1])

# %% training the ID3 algo for testing
carTreeInit = decisionTree(train0, method = 'entropy')
carTree = run_ID3(carTreeInit)

# %% applying the ID3 algo for testing
car_errinit = applyTree(carTree, test0, carTreeInit)
errs0, total_err0 = apply_ID3(car_errinit)

# %% making trees
tic = time.perf_counter()
methods = ['entropy', 'ME', 'gini']
datTrain0 = [attrTrain0, labelsTrain0, train0]
datTest0 = [attrTest0, labelsTest0, test0]
dfs = [train0, test0]
depths0 = len(attrNames0)

errinit = tester(methods, dfs, depths=depths0)
train_err_car, test_err_car = tester.test(errinit)
toc = time.perf_counter()
print('Time for car code is {:0.4f} seconds.'.format(toc-tic))

# %% plotting results and calc avgs
avg_train = np.mean(train_err_car, axis=1)
avg_test = np.mean(test_err_car, axis=1)
color = ['r', 'b', 'k']
label = ['Entropy', 'Majority Error', 'Gini index']

depth = np.linspace(1,6,6)
fig, ax = plt.subplots(figsize = (10,7))
for method in range(len(methods)):
    plt.plot(depth, train_err_car[method,:], color=color[method],
             label = label[method]+' (training)', linewidth = 3)
    plt.plot(depth, test_err_car[method,:], linestyle = '--', color=color[method],
             label = label[method]+' (testing)', linewidth = 3)
plt.legend(fontsize = 16, loc = (1.025,0.63))
plt.xlabel('Tree Depth', fontsize = 18)
plt.ylabel('Accuracy', fontsize = 18)
ax.tick_params(labelsize = 16, size = 10, width = 2)
plt.ylim([0.65,1])
plt.xlim([0.5,6])
for spine in ax.spines:
    ax.spines[spine].set_linewidth(2)
celltext = np.array([avg_train, avg_test]).T.round(3)
rows = ['Entropy','Majority\nError','Gini\nIndex']
cols = ['Avg. Training\nAccuracy', 'Avg. Test\nAccuracy']

# plt.savefig('accuracyCAR.png', dpi = 150, bbox_inches = 'tight')
print('Training errors:\nEntropy={}\nMajority Error={}\nGini Index={}'.format(
    avg_train[0].round(3), avg_train[1].round(3), avg_train[2].round(3)))
print('\nTesting errors:\nEntropy={}\nMajority Error={}\nGini Index={}'.format(
    avg_test[0].round(3), avg_test[1].round(3), avg_test[2].round(3)))


from __future__ import unicode_literals

from django import forms

from apps.employee.models import (Employee, BloodRelative, ExperienceRecord, \
                                      CriminalRecord, PoliceRecord,
                                      PsychoPhysicalRecord,
                                      TrainingRecord, Eps, JudiciaryRecord,
                                      BloodRecord, Subsidy, Stopping,
                                      Incident, IncidentEmployee, Specialty)
from apps.core.utils.utils import genera_codigo
from apps.core.constants import CORRELATIVO_INCIDENTE

class EmployeeForm(forms.ModelForm):
    class Meta:
        model = Employee
        fields = ['tipo', 'tipo_documento', 'nro_documento', 'foto',
                  'nombres', 'primer_apellido', 'segundo_apellido',
                  'codigo', 'codigo_anterior', 'fecha_registro', 'movil',
                  'correo', 'tipo_brevete', 'nro_licencia', 'ubigeo2',
                  'observaciones', 'fecha_nacimiento', 'estad_civil', 'sexo',
                  'estatura', 'peso', 'discapacitado',
                  'descripcion_discapacidad', 'tipo_via',
                  'nombre_via', 'nro_via', 'interior', 'manzana', 'tipo_zona',
                  'nombre_zona', 'ubigeo2_residencia', 'pension', 'nro_pension',
                  'salud', 'sctr', 'afiliado_seguro', 'afiliado_sindicato',
                  'banco', 'nro_cuenta', 'nro_interbancario', 'Specialty1',
                  'Specialty2']

    def save(self, operating_unit=None, code=None, *args, **kwargs):
        employee = super(EmployeeForm, self).save(*args, **kwargs)
        if operating_unit:
            employee.unidad_operativa = operating_unit
        if code:
            if not employee.codigo:
                employee.codigo = code
        employee.save()
        return employee

    def __init__(self, *args, **kwargs):
        super(EmployeeForm, self).__init__(*args, **kwargs)
        self.fields['fecha_registro'].widget.attrs.update(
            {'class': 'ico fecha supersmall'})
        self.fields['fecha_nacimiento'].widget.attrs.update(
            {'class': 'ico fecha supersmall'})
        self.fields['foto'].widget.attrs.update(
            {'class': 'small'})

class EmployeeBloodRelativeForm(forms.ModelForm):
    class Meta:
        model = BloodRelative
        fields = ['tipo_documento', 'nro_documento', 'nombres',
                  'primer_apellido',
                  'segundo_apellido', 'parentesco', 'nacimiento', 'archivo']

    def save(self, employee=None, *args, **kwargs):
        employee_relative = super(EmployeeBloodRelativeForm, self).save(*args,
                                                                        **kwargs)
        if employee:
            employee_relative.trabajador = employee
            employee_relative.save()
        return employee_relative

    def __init__(self, *args, **kwargs):
        super(EmployeeBloodRelativeForm, self).__init__(*args, **kwargs)
        self.fields['nacimiento'].widget.attrs.update(
            {'class': 'ico fecha supersmall'})
        self.fields['archivo'].widget.attrs.update(
            {'class': 'medium'})

class EmployeeEpsForm(forms.ModelForm):
    class Meta:
        model = Eps
        fields = '__all__'

    def save(self, employee=None, *args, **kwargs):
        employee_eps = super(EmployeeEpsForm, self).save(*args, **kwargs)
        if employee:
            employee_eps.trabajador = employee
            employee_eps.save()
        return employee_eps

class BloodRecordForm(forms.ModelForm):
    class Meta:
        model = BloodRecord
        fields = '__all__'

    def __init__(self, *args, **kwargs):
        super(BloodRecordForm, self).__init__(*args, **kwargs)
        self.fields['emision'].widget.attrs.update(
            {'class': 'ico fecha supersmall' })
        self.fields['trabajador'].widget.attrs.update(
            {'class': 'select2 small'})
        self.fields['tipo'].widget.attrs.update(
            {'class': 'small'})
        self.fields['resultado'].widget.attrs.update(
            {'class': ' small'})
        self.fields['archivo'].widget.attrs.update(
            {'class': ' medium'})

class EmployeeExperienceForm(forms.ModelForm):
    class Meta:
        model = ExperienceRecord
        fields = ['nombre_empresa', 'codigo_empresa', 'Specialty_cargo',
                  'incio', 'termino', 'tipo_documento', 'archivo', 'total_mes']

    def save(self, employee=None, *args, **kwargs):
        employee_experience = super(EmployeeExperienceForm, self).save(*args,
                                                                       **kwargs)
        if employee:
            employee_experience.trabajador = employee
            employee_experience.save()
        return employee_experience

    def __init__(self, *args, **kwargs):
        super(EmployeeExperienceForm, self).__init__(*args, **kwargs)
        self.fields['incio'].widget.attrs.update(
            {'class': 'fecha ico supersmall'})
        self.fields['termino'].widget.attrs.update(
            {'class': 'fecha ico supersmall'})
        self.fields['archivo'].widget.attrs.update(
            {'class': 'medium'})

class EmployeeTrainingForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(EmployeeTrainingForm, self).__init__(*args, **kwargs)
        self.fields['total_dias'].required = False
        self.fields['total_dias'].initial = 1
        self.fields['incio'].widget.attrs.update(
            {'class': 'fecha ico supersmall'})
        self.fields['termino'].widget.attrs.update(
            {'class': 'fecha ico supersmall'})
        self.fields['archivo'].widget.attrs.update(
            {'class': 'medium'})

    class Meta:
        model = TrainingRecord
        fields = ['nombre_empresa', 'codigo_empresa', 'curso', 'incio',
                  'termino', 'archivo', 'total_dias']

    def save(self, employee=None, *args, **kwargs):
        employee_training = super(EmployeeTrainingForm, self).save(*args,
                                                                   **kwargs)
        if employee:
            employee_training.trabajador = employee
            employee_training.save()
        return employee_training

class EmployeePoliceForm(forms.ModelForm):
    class Meta:
        model = PoliceRecord
        fields = '__all__'

    def save(self, employee=None, *args, **kwargs):
        employee_police = super(EmployeePoliceForm, self).save(*args,
                                                               **kwargs)
        if employee:
            employee_police.trabajador = employee
            employee_police.save()
        return employee_police

    def __init__(self, *args, **kwargs):
        super(EmployeePoliceForm, self).__init__(*args, **kwargs)
        self.fields['emision'].widget.attrs.update(
            {'class': 'fecha ico supersmall'})
        self.fields['archivo'].widget.attrs.update(
            {'class': 'medium'})

class EmployeeCriminalForm(forms.ModelForm):
    class Meta:
        model = CriminalRecord
        fields = '__all__'

    def save(self, employee=None, *args, **kwargs):
        employee_criminal = super(EmployeeCriminalForm, self).save(*args,
                                                                   **kwargs)
        if employee:
            employee_criminal.trabajador = employee
            employee_criminal.save()
        return employee_criminal

    def __init__(self, *args, **kwargs):
        super(EmployeeCriminalForm, self).__init__(*args, **kwargs)
        self.fields['emision'].widget.attrs.update(
            {'class': 'fecha ico supersmall'})
        self.fields['archivo'].widget.attrs.update(
            {'class': 'medium'})

class EmployeePsychoPhysicalForm(forms.ModelForm):
    class Meta:
        model = PsychoPhysicalRecord
        fields = '__all__'

    def save(self, employee=None, *args, **kwargs):
        employee_psycho_physical = super(
            EmployeePsychoPhysicalForm, self).save(*args, **kwargs)
        if employee:
            employee_psycho_physical.trabajador = employee
            employee_psycho_physical.save()
        return employee_psycho_physical

    def __init__(self, *args, **kwargs):
        super(EmployeePsychoPhysicalForm, self).__init__(*args, **kwargs)
        self.fields['emision'].widget.attrs.update(
            {'class': 'fecha ico supersmall'})
        self.fields['archivo'].widget.attrs.update(
            {'class': 'medium'})

class EmployeeJudiciaryForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(EmployeeJudiciaryForm, self).__init__(*args, **kwargs)
        self.fields['planilla'].required = False
        self.fields['incio'].widget.attrs.update(
            {'class': 'fecha ico supersmall'})
        self.fields['termino'].widget.attrs.update(
            {'class': 'fecha ico supersmall'})
        self.fields['planilla'].widget.attrs.update(
            {'class': 'select2'})
    class Meta:
        model = JudiciaryRecord
        fields = '__all__'

    def save(self, employee=None, *args, **kwargs):
        employee_judicial = super(
            EmployeeJudiciaryForm, self).save(*args, **kwargs)
        if employee:
            employee_judicial.trabajador = employee
            employee_judicial.save()
        return employee_judicial

class SubsidyForm(forms.ModelForm):
    class Meta:
        model = Subsidy
        fields = '__all__'

    def clean(self):
        cleaned_data = super(SubsidyForm, self).clean()
        inicio = cleaned_data.get("inicio")
        termino = cleaned_data.get("termino")
        if inicio and termino:
            if termino < inicio:
                raise forms.ValidationError(
                    "La fecha de inicio no puede ser mayor"
                    "a la fecha termino"
                )

    def __init__(self, *args, **kwargs):
        super(SubsidyForm, self).__init__(*args, **kwargs)
        self.fields['inicio'].widget.attrs.update(
            {'class': 'fecha ico supersmall'})
        self.fields['termino'].widget.attrs.update(
            {'class': 'fecha ico supersmall'})
        self.fields['trabajador'].widget.attrs.update(
            {'class': 'select2 small'})
        self.fields['incidente'].widget.attrs.update(
            {'class': 'select large'})
        self.fields['archivo'].widget.attrs.update(
            {'class': 'select2 medium'})
        self.fields['pago_semanal'].widget.attrs.update(
            {'class': 'select small'})

class StoppingForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(StoppingForm, self).__init__(*args, **kwargs)
        self.fields['trabajador'].label = "Trabajador"
        self.fields['fecha_baja'].widget.attrs.update(
            {'class': 'fecha ico supersmall'})
        self.fields['fecha_alta'].widget.attrs.update(
            {'class': 'fecha ico supersmall'})
        self.fields['trabajador'].widget.attrs.update(
            {'class': 'select2'})
        self.fields['codigo'].widget.attrs.update(
            {'class': 'select2 supersmall'})
        self.fields['tipo'].widget.attrs.update(
            {'class': 'select2 large'})
        self.fields['archivo'].widget.attrs.update(
            {'class': 'select2 medium'})

    class Meta:
        model = Stopping
        fields = '__all__'
        widgets = {
            'codigo': forms.TextInput(attrs={'disabled': "disabled"}),
            'dias': forms.TextInput(attrs={'disabled': "disabled"}),
        }

class IncidentForm(forms.ModelForm):
    class Meta:
        model = Incident
        fields = '__all__'

    def genera_correlativo(self, unidad_operativa_pk):
        codigo = genera_codigo(unidad_operativa_pk, CORRELATIVO_INCIDENTE)
        return codigo

    def __init__(self, *args, **kwargs):
        super(IncidentForm, self).__init__(*args, **kwargs)
        self.fields['fecha'].widget.attrs.update(
            {'class': 'fecha ico supersmall'})

class IncidentEmployeeForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(IncidentEmployeeForm, self).__init__(*args, **kwargs)
        self.fields['trabajador'].label = "xD"

    class Meta:
        model = IncidentEmployee
        fields = ['trabajador']

    def save(self, incident=None, *args, **kwargs):
        incident_detail = super(IncidentEmployeeForm, self).save(
            *args,
            **kwargs)
        if incident:
            incident_detail.incidente = incident
            incident_detail.save()
        return incident_detail

    def __init__(self, *args, **kwargs):
        super(IncidentEmployeeForm, self).__init__(*args, **kwargs)
        self.fields['trabajador'].widget.attrs.update(
            {'class': 'select2'})

class EmployeeQualificationForm(forms.ModelForm):
    class Meta:
        model = Employee
        fields = ['calificacion']

class SpecialtyForm(forms.ModelForm):
    class Meta:
        model = Specialty
        fields = '__all__'


from numba.pycc import CC
from numpy import zeros

cc = CC('UrbLoadRed_inner_compiled')

@cc.export('UrbLoadRed_inner',
           '(int64, int32[:,::1], float64[:,:,::1], int64, int64, int64, float64[:,::1], float64[:,:,::1], float64[:,:,::1], int64)')
def UrbLoadRed_inner(NYrs, DaysMonth, Temp, NRur, Nqual, Storm, UrbBMPRed, water, adjurbanqtotal, nlu):
    result = zeros((NYrs, 12, 31, 16, Nqual))
    for Y in range(NYrs):
        for i in range(12):
            for j in range(DaysMonth[Y][i]):
                if Temp[Y][i][j] > 0 and water[Y][i][j] > 0.01:
                    if adjurbanqtotal[Y][i][j] > 0.001:
                        for l in range(NRur, nlu):
                            for q in range(Nqual):
                                result[Y][i][j][l][q] = (water[Y][i][j] / Storm) * UrbBMPRed[l][q]
                                if water[Y][i][j] > Storm:
                                    result[Y][i][j][l][q] = UrbBMPRed[l][q]
                else:
                    pass
    return result


"""django1 URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""

from django.urls import path
from controller import studentController
from controller import testController

urlpatterns = [
    path('api/test/test1', testController.test1, name='test1'),
    path('api/student/get', studentController.get, name='get'),
    path('api/student/getall', studentController.getall, name='getall'),
    path('api/student/getallpage', studentController.getallpage, name='getallpage'),
    path('api/student/add', studentController.add, name='add'),
    path('api/student/update', studentController.update, name='update'),
    path('api/student/delete', studentController.delete, name='delete'),
]


"""
Given a collection of integers that might contain duplicates, nums, return all possible subsets (the power set).

Note: The solution set must not contain duplicate subsets.

For example,
If nums = [1,2,2], a solution is:

[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]
"""
class Solution:
    def subsetsWithDup(self, nums):
        res = []
        nums.sort()
        self.backtrack(res, [], nums, 0)
        return res

    def backtrack(self, res, temp, nums, start):
        res.append(temp[:])
        for i in range(start, len(nums)):
            if (i > start and nums[i] == nums[i - 1]):
                continue
            temp.append(nums[i])
            self.backtrack(res, temp, nums, i + 1)
            temp.pop()


#how to add things to tuples
#this is a tuple:
essentials = ('bread', 'coffee', 'wifi')
print(essentials)

#first change the tuple to a List
newList = list(essentials)
print(newList)

#append something to the list, then change the list to a tuple.
newList.append("123")
newList = tuple(newList)

#changed tuple
essentials = newList
print(essentials)


from microbit import *
import neopixel
np = neopixel.NeoPixel(pin5, 18)
np.clear()

while True:
    val1 = pin1.read_analog()
    val2 = int((val1/1023)*255)

    for pixel_id in range(0, len(np)):
        np[pixel_id] = (255 - val2, 255 - val2, 255 - val2)
        np.show()
    sleep(100)


import torch
from utils.data import plot_data, max_req, sample_states, req_to_instances
from utils.nets import Gaussian
from utils.vis import scatter, line

num_epochs = 1e4
vis_iter = 1000
batch_size = 512
lr = 3e-4

def D(s):
    return torch.FloatTensor([req_to_instances(t.item()) for t in s]).unsqueeze(-1)

π = Gaussian(lr)

# plot data at the beginning
plot_data()

# training
for epoch in range(int(num_epochs)):

    ########################################

    # sample new states and subsequent instance counts for training during this epoch
    s = sample_states(batch_size)
    y_hat = D(s)

    # expectation maximization
    objective = π.log_prob(s / max_req, y_hat).mean()                               # states are normalized to prevent NaN's during log_prob calculation
    π.maximize(objective)

    ########################################

    # occasionally plot progress and example output
    if epoch % vis_iter == vis_iter - 1:
        line(epoch, objective.item(), 'π objective')

        points = []
        with torch.no_grad():
            s = []
            for i in range(0, max_req, max_req//20):
                s.extend(10 * [i])
            s = torch.FloatTensor(s).unsqueeze(-1)
            req = s.squeeze().tolist()
            ins = π(s / max_req).squeeze().tolist()

            points = list(zip(req,ins))
        scatter(points, 'Gaussian', clear=True)


# # Polynomial Regression - pyspark, ML
# To demonstrate the differences of running models in local python and pyspark, we'll use a simple [Polynomial Regression](https://en.wikipedia.org/wiki/Polynomial_regression).
# Note that there are two classes you can run machine learning models with the spark [python API](http://spark.apache.org/docs/2.0.0/api/python/); [ML](http://spark.apache.org/docs/2.0.0/api/python/pyspark.ml.html) & [MLlib](http://spark.apache.org/docs/2.0.0/api/python/pyspark.mllib.html). This demonstration will be done using DataFrames which requires the **ML** class.

# ## Initialize a pyspark Spark Context
# Since procuring a spark context will be a pretty common task for any spark analysis, I recommend defining an initialization magic to be sourced for every python session in the project. This is accomplished by writting the initialization magic to a file, [init_pyspark.py](http://github.mtv.cloudera.com/barker/demo_poly_reg/blob/master/init/init_pyspark.py), and sourcing that file at startup using [startup_init_pyspark.py](http://github.mtv.cloudera.com/barker/demo_poly_reg/blob/master/.ipython/profile_default/startup/startup_init_pyspark.py).
# Now you can initialize your sparkylr spark ml spark context via magic:

from pyspark.sql import SparkSession

spark = SparkSession.builder \
          .appName("spark-pypspark-ml") \
          .getOrCreate()

# ---
# The initialization creates two global environment variables; `sc` & `sqlCtx`.

# ## Generate Spark DataFrame Data
# We'll generate sample data for a multivariate linear regression with known coefficients and randomly generated error. Specifically;
# $$ y = \beta_0 + \sum_i (\beta_i x_i) + \epsilon   \thinspace \thinspace \thinspace \thinspace \thinspace     \forall i \in {1..3}$$
# $$ \beta_0: 4 $$
# $$ \beta_1: 6 $$
# $$ \beta_2: 2 $$
# $$ \beta_3: -1 $$

from pyspark.mllib.random import RandomRDDs
from pyspark.ml.linalg import Vectors
import pandas as pd
import numpy as np

x1      = RandomRDDs.uniformRDD(spark, 10000).map(lambda x: 6.0*x-2)
epsilon = RandomRDDs.normalRDD(spark, 10000).map(lambda x: 4.0*x)
def gen_poly(x):
    x1 = float(x[0])
    x2 = float(np.power(x1,2))
    x3 = float(np.power(x1,3))
    X  = Vectors.dense(x1,x2,x3)
    epsilon = float(x[1])
    y  = 4.0 + 6.0*x1 + 2.0*x2 - 1*x3 + epsilon
    return(y,X)
gen_dat = x1.zip(epsilon).map(gen_poly)

# ## Prepare Data as DataFrame
# This example will use the ML class which requires our data to be structured as a spark DataFrame.
# Well define our column for labels, y, and a column for feature vectors, X.

dat = spark.createDataFrame(gen_dat,["y", "X"])

# ## Train Model and Review Model Coefficients
from pyspark.ml.regression import LinearRegression

lr = LinearRegression(featuresCol="X",labelCol="y")
lrModel = lr.fit(dat)

coef = pd.DataFrame(data=np.dstack((np.append(np.array([lrModel.intercept, ]), lrModel.coefficients), [4,6,2,-1]))[0])
coef.columns = ['ml_coef', 'true_coef']
coef


import os

import argparse
import platform

from os.path import expanduser, join, isdir, basename
from prompt_toolkit import prompt
from prompt_toolkit.contrib.completers import WordCompleter
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from yaml import load, Loader
from colorama import Fore

if platform.system() == 'Windows':
    from colorama import init
    init()

def upload(filename):
    try:
        gauth = GoogleAuth()
        gauth.settings['client_config_file'] = join(expanduser('~'), 'client_secrets.json')
        gauth.settings['save_credentials_file'] = join(expanduser('~'), 'token.json')
        gauth.settings['save_credentials'] = True
        gauth.settings['save_credentials_backend'] = 'file'

        gauth.LocalWebserverAuth()
        drive = GoogleDrive(gauth)
        if not isdir(filename):
            create_file(drive, filename)
        else:
            current_dir = os.getcwd()
            folder_id = create_folder(drive, filename)
            working_folder = join(current_dir, filename)
            for file_ in os.listdir(working_folder):
                if not os.path.isdir(join(working_folder, file_)):
                    f = create_file_in_folder(drive, join(working_folder, file_), folder_id)

    except Exception as e:
        print(Fore.RED, e)

def create_folder(drive, foldername):
    folder_metadata = {
        'title': foldername,
        'mimeType': 'application/vnd.google-apps.folder'
    }
    folder = drive.CreateFile(folder_metadata)
    folder.Upload()
    print(Fore.GREEN, 'Folder {} Created.'.format(folder['title']))
    return folder['id']

def create_file(drive, filename):
    f = drive.CreateFile()
    f.SetContentFile(filename)
    f['title'] = basename(filename)
    f.Upload()
    print(Fore.GREEN, 'File {} Uploaded'.format(f['title']))

def create_file_in_folder(drive, filename, folder_id):
    f = drive.CreateFile({'parents': [{'kind': 'drive#fileLink', 'id': folder_id}]})
    f.SetContentFile(filename)
    f['title'] = basename(filename)
    f.Upload()
    print(Fore.GREEN, 'File {} Uploaded'.format(f['title']))

def startup():
    print("""
    ____              _    _ _
    |  _ \           | |  (_) |
    | |_) | __ _  ___| | ___| |_ _   _ _ __
    |  _ < / _` |/ __| |/ / | __| | | | '_ \
    | |_) | (_| | (__|   <| | |_| |_| | |_) |
    |____/ \__,_|\___|_|\_\_|\__|\__,_| .__/
                                    | |
                                    |_|

    """)

def cli():
    startup()
    choices = WordCompleter(['YES', 'No', 'no', 'yes'])
    text = prompt(' Backup the entire directory? ', completer=choices)
    if text.lower() == 'yes':
        upload(basename(os.getcwd()))
    elif text.lower() == 'no':
        file_completers = WordCompleter(os.listdir(os.getcwd()))
        text = prompt(' File name:  ', completer=file_completers)
        upload(text)
    else:
        print(Fore.RED + 'Aborted.')

if __name__ == '__main__':
    cli()


global_awaiting_time = 0

def to_minute(sec):
    return sec / 60

def to_timestamp(min):
    return min * 60

class OrderLog:
    def __init__(self, order_id, user_id, order_date, expected_arrive, expected_trip_time):
        self.id = order_id
        self.user_id = user_id
        self.date = order_date
        self.expected_arrive = expected_arrive
        self.expected_trip_time = expected_trip_time
        self.type = 'ordered'

    def expected_trip_finished(self):
        return self.date + \
               to_timestamp(self.expected_arrive) + \
               to_timestamp(global_awaiting_time) + \
               to_timestamp(self.expected_trip_time)

class TimeLog:
    def __init__(self, type, order_id, time):
        self.id = order_id
        self.time = time
        self.type = type

class Trip:
    order_log = None
    arrived_log = None
    start_log = None
    finish_log = None

    def set_log(self, log):
        if log.type == 'ordered':
            self.order_log = log
        if log.type == 'arrived':
            self.arrived_log = log
        if log.type == 'started':
            self.start_log = log
        if log.type == 'finished':
            self.finish_log = log

    def _should_ignore(self):
        return (
                self.order_log is None
                or self.arrived_log is None
                or self.start_log is None
                or self.finish_log is None
        )

    def is_passenger_late(self):
        return to_minute(self.start_log.time - self.arrived_log.time) > global_awaiting_time

    def is_coming_to_pass_in_time(self):
        return self.order_log.date + to_timestamp(self.order_log.expected_arrive) >= self.arrived_log.time

    def compute_late_diff(self):
        if self._should_ignore():
            return -1

        if self.is_passenger_late():
            return -1

        expected_finished = self.order_log.expected_trip_finished()
        actual_finished = self.finish_log.time

        return actual_finished - expected_finished

def parse_log(log):
    arr = log.split()
    if arr[0] == 'ordered':
        return OrderLog(arr[1], arr[2], int(arr[3]), int(arr[4]), int(arr[5]))

    return TimeLog(arr[0], arr[1], int(arr[2]))

def solve(raw_logs):
    parsed_logs = map(parse_log, raw_logs)
    trip_dict = dict()

    for parsed_log in parsed_logs:
        log_id = parsed_log.id
        trip = None

        if log_id in trip_dict:
            trip = trip_dict[log_id]
        else:
            trip = Trip()
            trip_dict[log_id] = trip

        trip.set_log(parsed_log)

    user_dict = dict()
    for trip in trip_dict.values():
        diff = trip.compute_late_diff()
        if diff <= 0:
            continue
        user_id = trip.order_log.user_id
        if user_id in user_dict:
            user_dict[user_id] += diff
        else:
            user_dict[user_id] = diff

    sorted2 = sorted(user_dict.items(), key=lambda item: (-item[1], item[0]))
    return list(map(
        lambda x: x[0],
        sorted2
    ))

n = int(input())

for i in range(n):
    logs_amount, top_users, awaiting_time = input().split()
    global_awaiting_time = int(awaiting_time)
    logs = []
    for j in range(int(logs_amount)):
        logs.append(input())

    result = solve(logs)
    if len(result) == 0:
        print('-')
    else:
        print(' '.join(result))


# coding=utf-8
import sys
import re
from q27 import remove_link

def remove_media(seq):
	markup_remove_lst = ["\[(.+?)\]", "<(.+?)>", "\{\{(.+?)\}\}"]
	MARKUP = re.compile("|".join(markup_remove_lst))
	infobox = remove_link(seq)
	for k, v in infobox.iteritems():
		infobox[k] = MARKUP.sub(r"", v)
	return infobox

def main():
    for line in remove_media(sys.stdin).items():
        print ("{0[0]}\t{0[1]}".format(line))

if __name__ == '__main__':
    main()

"""
python q28.py < eng.txt
"""


"""
To Do:
-Add an optional input for the networks so they can be defined in a main run script.
-Test
-Combine Training Operation
"""
from .method import Method
from .buffer import Trajectory
from .AdvantageEstimator import MultiStepDiscountProcessing
import tensorflow as tf
import numpy as np
from utils.utils import MovingAverage
from utils.record import Record
import random

from networks.common import NetworkBuilder

class DQN_ms(Method):

    def __init__(self,sess,settings,netConfigOverride,stateShape,actionSize,nTrajs=1,**kwargs):
        """
        Initializes I/O placeholders and the training process of a Multi-step DQN.
        Main principal is that instead of one-step TD diference, the loss is evaluated on a
        temporally extended basis.
        G = R_t + γR_t+1 + ... γ^n-1 R_t+n + q(S_t+n,a*,θ-)
        loss = MSE(G,q(S_t,A_t,θ))

        """
        #Placeholders
        self.actionSize = actionSize
        self.sess=sess
        self.HPs = settings["NetworkHPs"]
        self.scope="DQN"
        self.Model = NetworkBuilder(networkConfig=settings["NetworkConfig"],netConfigOverride=netConfigOverride,actionSize=actionSize)

        self.buffer = [Trajectory(depth=5) for _ in range(nTrajs)]
        with self.sess.as_default(), self.sess.graph.as_default():
            with tf.name_scope(self.scope):
                self.states_ = tf.placeholder(shape=[None]+stateShape, dtype=tf.float32, name='states')
                self.next_states_ = tf.placeholder(shape=[None]+stateShape, dtype=tf.float32, name='next_states')
                self.actions_ = tf.placeholder(shape=[None], dtype=tf.int32, name='actions_hold')
                self.rewards_ = tf.placeholder(shape=[None], dtype=tf.float32, name='rewards_hold')
                self.done_ = tf.placeholder(shape=[None], dtype=tf.float32, name='done_hold')

                input = {"state":self.states_}
                out = self.Model(input)
                self.q = out["Q"]

                out2 = self.Model({"state":self.next_states_})
                q_next = out2["Q"]

                with tf.name_scope('current_Q'):
                    oh_action = tf.one_hot(self.actions_, actionSize, dtype=tf.float32) # [?, num_agent, action_size]
                    curr_q = tf.reduce_sum(tf.multiply(self.q, oh_action), axis=-1) # [?, num_agent]

                with tf.name_scope('target_Q'):
                    max_next_q = tf.reduce_max(q_next, axis=-1)
                    td_target = self.rewards_  + self.HPs["Gamma"] * max_next_q * (1. - self.done_)

                with tf.name_scope('td_error'):
                    loss = tf.keras.losses.MSE(td_target, curr_q)
                    softmax_q = tf.nn.softmax(curr_q)
                    self.entropy = -tf.reduce_mean(softmax_q * tf.log(softmax_q+ 1e-5))
                    self.loss=total_loss = loss + self.HPs["EntropyBeta"] * self.entropy

                optimizer = tf.keras.optimizers.Adam(self.HPs["LearningRate"])
                self.params = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, self.scope)

                self.gradients = optimizer.get_gradients(total_loss, self.params)
                self.update_op = optimizer.apply_gradients(zip(self.gradients, self.params))

                self.grads=[self.gradients]
                self.losses=[self.loss]
                self.update_ops=[self.update_op]

        self.grad_MA = [MovingAverage(400) for i in range(len(self.grads))]
        self.loss_MA = [MovingAverage(400) for i in range(len(self.losses))]
        self.labels = ["Critic"]

    def GetAction(self, state,episode,step):
        """
        Contains the code to run the network based on an input.
        """
        if len(state.shape) == 3:
            state = state[np.newaxis, :]
        if len(state.shape) == 1:
            state = state[np.newaxis, :]
        q = self.sess.run(self.q, {self.states_: state})
        if "Exploration" in self.HPs:
            if self.HPs["Exploration"]=="EGreedy":
                prob = self.HPs["ExploreSS"] + (1-self.HPs["ExploreSS"])*(np.exp(-episode/self.HPs["ExplorationDecay"]))
                if random.uniform(0, 1) < prob:
                    actions = random.randint(0,self.actionSize-1)
                else:
                    actions = np.argmax(q, axis=-1)
            else:
                actions = np.argmax(q, axis=-1)
        else:
            actions = np.argmax(q, axis=-1)
        return actions ,[]  # return a int and extra data that needs to be fed to buffer.

    def Update(self,episode=0):
        """
        The main update function for A3C. The function pushes gradients to the global AC Network.
        The second function is to Pull
        """
        #Checking that there is enough data for a batch
        samples=0
        for i in range(len(self.buffer)):
            samples +=len(self.buffer[i])
        if samples < self.HPs["BatchSize"]:
            return

        #Combining all trajs into 1:
        s_list = []
        a_list = []
        done_list = []
        g_list = []
        s_n_list = []
        for traj in range(len(self.buffer)):
            g,s_n=MultiStepDiscountProcessing(self.buffer[traj][2],self.buffer[traj][3],self.HPs["Gamma"],self.HPs["MultiStep"])
            s_list.extend(self.buffer[traj][0])
            a_list.extend(self.buffer[traj][1])
            g_list.extend(g)
            s_n_list.extend(s_n)
            done_list.extend(self.buffer[traj][4])

        #Separating into different batches
        batches = len(s_list)//self.HPs["MinibatchSize"]+1
        s = np.array_split( s_list, batches)
        a_his = np.array_split( np.asarray(a_list).reshape(-1), batches)
        r = np.array_split( np.asarray(g_list).reshape(-1), batches)
        s_next = np.array_split( s_n_list, batches)
        done = np.array_split( done_list, batches)

        #Running all batches through multiple epochs
        for epoch in range(self.HPs["Epochs"]):
            for i in range(batches):
            #Create a feedDict from the buffer
                feedDict = {
                    self.states_ : np.squeeze(np.asarray(s[i])),
                    self.next_states_ : np.squeeze(np.asarray(s_next[i])),
                    self.actions_ : np.squeeze(np.asarray(a_his[i])),
                    self.rewards_ : np.squeeze(np.asarray(r[i])),
                    self.done_ : np.squeeze(np.asarray(done[i],dtype=float))

                }
                out = self.sess.run(self.update_ops+self.losses+self.grads, feedDict)
                out = np.array_split(out,3)
                losses = out[1]
                grads = out[2]

                for i,loss in enumerate(losses):
                    self.loss_MA[i].append(loss)

                for i,grads_i in enumerate(grads):
                    total_counter = 1
                    vanish_counter = 0
                    for grad in grads_i:
                        total_counter += np.prod(grad.shape)
                        vanish_counter += (np.absolute(grad)<1e-8).sum()
                    self.grad_MA[i].append(vanish_counter/total_counter)

        self.ClearTrajectory()

    def GetStatistics(self):
        dict ={}
        for i,label in enumerate(self.labels):
            dict["Training Results/Vanishing Gradient " + label] = self.grad_MA[i]()
            dict["Training Results/Loss " + label] = self.loss_MA[i]()
        return dict

    @property
    def getVars(self):
        return self.Model.getVars(self.scope)


from pymongo import MongoClient
from bson import json_util
import json

# Making a Connection with MongoClient (using default host and port)
connection = MongoClient()

#//////////////////////////////////////
# Getting a Database                //
db = connection["city"]          # //
collection = db["inspections"]  # //
#//////////////////////////////////

# ============================================== Create Docs
def insert_document(document):
    status = True

    try:
        collection.insert_one(document)
    except Exception as e:
        print("\n\t -->", e)
        status = False

    return status

# ============================================== Read Docs
def read_document(document):
    result = ""

    try:
        result = collection.find_one(document)
    except Exception as e:
        print("\n\t -->", e)

    return result

# ============================================== Update Docs
def update_document(document, update):
    status = True

    try:
        collection.update_one(document, {"$set": update})
    except Exception as e:
        print("\n\t -->", e)
        status = False

    return status

# ============================================== Delete Docs
def delete_document(document):
    status = True

    try:
        collection.delete_one(document)

    except Exception as e:
        print("\n\t -->", e)
        status = False

    return status

# ============================================== Main
def main():

    while True:
      print("==========================================================")
      print("1 - Create")
      print("2 - Read")
      print("3 - Update")
      print("4 - Delete")
      print("5 - Exit\n")
      userInput = int(input("Enter number choice: "))

      # Create
      if userInput == 1:
        userInputDoc = input("Enter document to create (i.e. {\"_id\" : 355, \"name\" : \"test\"}): \n")
        status = insert_document(json.loads(userInputDoc))
        print("\nDocument Created:", status)

      # Read
      elif userInput == 2:
        userInputDoc = input("Enter \"_id\" of document to be read (i.e {\"_id\" : 355}): \n")
        result = read_document(json.loads(userInputDoc))
        # Prints JSON of read document.
        print("\nRead Document:\n" + json.dumps(result, indent=4))

      # Update
      elif userInput == 3:
        userInputDoc = input("Enter document \"_id\" to update (i.e {\"_id\" : 355}): \n")
        userInputDoc2 = input("Enter update (i.e. {\"name\" : \"Updated Value UPDATED\"}): \n")
        status = update_document(json.loads(
            userInputDoc), json.loads(userInputDoc2))
        print("\nDocument Updated:", status)

      # Delete
      elif userInput == 4:
        userInputDoc = input("Enter \"_id\" of document to be deleted (i.e {\"_id\" : 355}): \n")
        status = delete_document(json.loads(userInputDoc))
        print("Document Deleted:", status)

      # Exit
      elif userInput == 5:
        break

      # Default
      else:
        print("Option not valid, enter a number from 1 to 5: ")

#//////////////
main()    # //
#////////////


"""Halo bias.

"""
import cluster_toolkit
from cluster_toolkit import _ArrayWrapper
import numpy as np
# from .peak_height import *

def bias_at_M(M, k, P, Omega_m, delta=200):
    """Tinker et al. 2010 bais at mass M [Msun/h].

    Args:
        M (float or array like): Mass in Msun/h.
        k (array like): Wavenumbers of power spectrum in h/Mpc comoving.
        P (array like): Power spectrum in (Mpc/h)^3 comoving.
        Omega_m (float): Matter density fraction.
        delta (int; optional): Overdensity, default is 200.

    Returns:
        float or array like: Halo bias.

    """
    M = _ArrayWrapper(M, 'M')
    k = _ArrayWrapper(k, allow_multidim=True)
    P = _ArrayWrapper(P, allow_multidim=True)
    if k.shape != P.shape:
        raise ValueError('k and P must have the same shape')

    bias = _ArrayWrapper.zeros_like(M)
    cluster_toolkit._lib.bias_at_M_arr(M.cast(), len(M), delta,
                                       k.cast(), P.cast(), len(k),
                                       Omega_m, bias.cast())
    return bias.finish()

def bias_at_R(R, k, P, delta=200):
    """Tinker 2010 bais at mass M [Msun/h] corresponding to radius R [Mpc/h comoving].

    Args:
        R (float or array like): Lagrangian radius in Mpc/h comoving.
        k (array like): Wavenumbers of power spectrum in h/Mpc comoving.
        P (array like): Power spectrum in (Mpc/h)^3 comoving.
        delta (int; optional): Overdensity, default is 200.

    Returns:
        float or array like: Halo bias.

    """
    R = _ArrayWrapper(R, 'R')
    k = _ArrayWrapper(k)
    P = _ArrayWrapper(P)

    bias = _ArrayWrapper.zeros_like(R)
    cluster_toolkit._lib.bias_at_R_arr(R.cast(), len(R), delta,
                                       k.cast(), P.cast(), len(k),
                                       bias.cast())
    return bias.finish()

def bias_at_nu(nu, delta=200):
    """Tinker 2010 bais at peak height nu.

    Args:
        nu (float or array like): Peak height.
        delta (int; optional): Overdensity, default is 200.

    Returns:
        float or array like: Halo bias.

    """
    nu = _ArrayWrapper(nu, 'nu')

    bias = _ArrayWrapper.zeros_like(nu)
    cluster_toolkit._lib.bias_at_nu_arr(nu.cast(), len(nu), delta,
                                        bias.cast())
    return bias.finish()

def dbiasdM_at_M(M, k, P, Omega_m, delta=200):
    """d/dM of Tinker et al. 2010 bais at mass M [Msun/h].

    Args:
        M (float or array like): Mass in Msun/h.
        k (array like): Wavenumbers of power spectrum in h/Mpc comoving.
        P (array like): Power spectrum in (Mpc/h)^3 comoving.
        Omega_m (float): Matter density fraction.
        delta (int; optional): Overdensity, default is 200.

    Returns:
        float or array like: Derivative of the halo bias.

    """
    M = _ArrayWrapper(M, 'M')
    k = _ArrayWrapper(k, allow_multidim=True)
    P = _ArrayWrapper(P, allow_multidim=True)

    deriv = _ArrayWrapper.zeros_like(M)
    cluster_toolkit._lib.dbiasdM_at_M_arr(M.cast(), len(M), delta, k.cast(),
                                          P.cast(), len(k), Omega_m,
                                          deriv.cast())
    return deriv.finish()

def _bias_at_nu_FREEPARAMS(nu, A, a, B, b, C, c, delta=200):
    """A special function used only for quickly computing best fit parameters
    for the halo bias models.
    """
    nu = _ArrayWrapper(nu, allow_multidim=True)
    bias = _ArrayWrapper.zeros_like(nu)
    cluster_toolkit._lib.bias_at_nu_arr_FREEPARAMS(nu.cast(), len(nu), delta,
                                                   A, a, B, b, C, c,
                                                   bias.cast())
    return bias.finish()


from tkinter import*
import sys

class Recordhandle:

    def compare(self, distance, recname):
        self.recordername = recname
        self.distance = distance
        self.changer = []
        self.newrecord = False
        f = open("bests.txt", "r")
        lines = f.readlines()

        for i in range(len(lines)):
            self.line = lines[i].split(';')

            if int(self.line[0]) >= self.distance:
                self.changer.append(lines[i])

            else:
                if self.newrecord == False:
                    self.changer.append(str(self.distance)+"\n")
                    self.changer.append(self.recordername)
                    self.newrecord = True
                    self.changer.append(lines[i])
                else:
                    if i < len(lines)-1:
                        self.changer.append(lines[i])
        f.close()

    def best_current(self):
            self.current = []
            f = open("bests.txt", "r")
            lines = f.readlines()

            for i in range(len(lines)):
                self.line = lines[i].split(';')
                self.current.append(self.line)

            f.close()
            return self.current

    def min_to_board(self):
            self.minboard = 0
            self.line = []
            f = open("bests.txt", "r")
            lines = f.readlines()
            self.list = lines
            self.line = lines[len(lines)-1].split(";")
            self.minboard =int(self.line[0])
            f.close()
            return self.minboard

#    def write(self):
#            self.master = Tk()
#            self.text = StringVar()
#            Label(self.master, text="You achieved new record! Type your name and press <Enter>:").pack()
#            self.e1 = Entry(self.master, textvariable = self.text)
#            self.e1.pack()
#            self.e1.bind('<Return>',self.submit)
#            self.master.mainloop()

#    def submit(self, event):
#            self.recordername = self.e1.get()
#            print(self.recordername)
        #    try:
#            self.master.destroy()
        #    except:
            #    self.compare(self.distance)


from django.contrib import auth, messages
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.db.models import Q
from django.http import HttpResponseRedirect
from django.shortcuts import render, get_object_or_404, redirect
from .models import Patient
from reminder.models import Reminder
from services.models import Service
from .forms import PatientForm, DischargeForm
import datetime

def create(request):
    '''Method to create a new expectant mother, register her for reception of
	various services as provided'''
    if not request.user.is_authenticated():
        return render(request, '404.html')
    form = PatientForm(request.POST or None)
    if form.is_valid():
        instance = form.save(commit=False)
        instance.save()
        messages.success(request, 'Patient Successfully Created')
        return HttpResponseRedirect('/patients/list/')
    context = {'form': form,}
    return render(request, 'patients/create.html', context)

def update(request, id=None):
    if not request.user.is_authenticated():
        return render(request, '404.html')
    # instance_profile = get_object_or_404(Patient, id=id)
    instance_profile = Patient.objects.get(id=id)
    instance_number = instance_profile.anc_number
    form = PatientForm(request.POST or None, instance=instance_profile)
    if form.is_valid():
        contact_ = instance_profile.patient_contact
        name_ = instance_profile.patient_name
        instance_profile.save()
        return HttpResponseRedirect(instance_profile.get_absolute_url())

def delete(request, id=None):
    if not request.user.is_authenticated():
        return render(request, '404.html')
    instance_profile = get_object_or_404(Patient, id=id)
    instance_profile.delete()
    # message success
    return redirect('patients:list')

def list(request, id=None):
    if not request.user.is_authenticated():
        return render(request, '404.html')
    patient_count = Patient.objects.count()
    queryset_list = Patient.objects.all()
    queryset_order = queryset_list.order_by('patient_name').filter(discharge=False)

    query = request.GET.get('q')
    if query:
        queryset_order = queryset_order.filter(
            Q(anc_number__icontains=query) |
            Q(patient_contact__icontains=query) |
            Q(patient_name__icontains=query)
        )

    paginator = Paginator(queryset_order, 10)
    page = request.GET.get('page')
    try:
        patient_list = paginator.page(page)
    except PageNotAnInteger:
        patient_list = paginator.page(1)
    except EmptyPage:
        patient_list = paginator.page(paginator.num_pages)

    context = {
        'patient_list': patient_list,
        'patient_count': patient_count,
    }
    return render(request, 'patients/list.html', context)

def profile(request, id=None):
    if not request.user.is_authenticated():
        return render(request, '404.html')
    instance_profile = get_object_or_404(Patient, id=id)
    # instance_weight = get_object_or_404(Weight, id=instance_profile.id)
    lmd = instance_profile.last_menstrual_date
    format = '"%m/%d/%Y'
    edd = lmd + datetime.timedelta(days=280)
    today = datetime.datetime.now().date()
    # service_list = Service.objects.all()
    # service_scheduled = service_list.filter(reminder__patient=instance_profile)
    # days_to_delivery =  datetime.datetime.strftime((edd - today), format)
    reminder_list = Reminder.objects.all()
    appointment = reminder_list.filter(patient=instance_profile)
    context = {
        'instance_profile': instance_profile,
        'instance_edd': edd,
        # 'instance_delivery': days_to_delivery,
        'appointment': appointment,
        # 'service_scheduled': service_scheduled,
        # 'appointments': appointments,
    }
    return render(request, 'patients/profile.html', context)

def discharge(request):
    if not request.user.is_authenticated():
        return render(request, '404.html')
    form = DischargeForm(request.POST or None)
    if request.method == 'POST':
        if form.is_valid():
            instance = form.save(commit=False)
            instance.save()
            messages.success(request, 'Patient Successfully Discharged')
            return redirect('users:detail')


from __future__ import division
import numpy as np; import h5py
import pandas as pd; import os
import scipy.optimize as so
import shutil

## Helper Functions ##
def E_from_M(M, e):
    func = lambda E: E - e * np.sin(E) - M
    return so.brentq(func, 0, 2 * np.pi)

def intersection(lst1, lst2):
    temp = set(lst2)
    lst3 = [value for value in lst1 if value in temp]
    return np.array(lst3)

## Convert Axisymmetric Disk to an Eccentric Disk ##
# Filename is the location of a disk h5py object.
# ecc and peri are functions of r.
# length is the halflength of a side of the box
def make_disk_eccentric(filename, ecc, per, length = 110, taper = True):
    # Make New File #
    ext = filename.rfind('.')
    output = filename[:ext] + '_eccentric' + filename[ext:]
    if os.path.isfile(output):
        os.remove(output)
    shutil.copyfile(filename, output)

    # Load Data #
    root = h5py.File(output, 'r+')
    data = root[root.keys()[1]]
    keys = data.keys()

    # Find Disk Elements #
    pos_d = np.array(data[keys[0]])
    mag_p = (pos_d[:, 0] - length)**2 + (pos_d[:, 1] - length)**2
    vel_d = np.array(data[keys[4]])
    mag_v = vel_d[:, 0]**2 + vel_d[:, 1]**2

    # Cut in Velocity #
    rdx_1 = np.where(mag_v < 10**(-5))[0]
    rdx_2 = np.where(mag_p > (length / 2)**2)[0]
    #rdx_2 = np.where(mag_p > 0)[0]
    redux = intersection(rdx_1, rdx_2)

    # Shift Positions #
    center = [length, length, 0]
    x_axis = pos_d[:, 0] - center[0]
    y_axis = pos_d[:, 1] - center[0]

    # Convert to Polar Coordinates #
    phi = np.arctan2(y_axis, x_axis)
    a = np.sqrt(x_axis**2 + y_axis**2)
    E = np.zeros(a.shape)

    # Taper e-profile #
    if taper:
        out_r = np.amin(a[redux])
        out_e = ecc(out_r)
        tap_r = out_r * (1 - out_e)
        eccen = ecc
        ecc = lambda r: (1 / np.pi * np.arctan(1 * (tap_r - r)) + 0.5) * eccen(r)

    # Make peri at Disk Edge 0 #
    #per = lambda r: peri(r) - peri(np.amin(a[redux]))

    # Convert to Orbital Elements #
    M = (phi - per(a)) % (2 * np.pi)
    e = ecc(a)
    for i in range(len(E)):
        E[i] = E_from_M(M[i], e[i])
    cf = (np.cos(E) - e) / (1 - e * np.cos(E))
    sf = (np.sqrt(1 - e**2) * np.sin(E)) / (1 - e * np.cos(E))
    cw = np.cos(per(a))
    sw = np.sin(per(a))
    ct = sf * cw + cf * sw
    st = cf * cw - sf * sw
    r = a * (1 - e**2) / (1 + e * cf)
    v = np.sqrt(2/r - 1/a)

    # Computer New Coordinates - Relative to Peri #
    tmp_px = r * cf
    tmp_py = r * sf
    tmp_vx = -sf / np.sqrt(a * (1 - e**2))
    tmp_vy = +(e + cf) / np.sqrt(a * (1 - e**2))

    # Compute New Coordinates - Absolute #
    new_px = tmp_px * cw - tmp_py * sw + center[0]
    new_py = tmp_px * sw + tmp_py * cw + center[1]
    new_vx = tmp_vx * cw - tmp_vy * sw
    new_vy = tmp_vx * sw + tmp_vy * cw

    # Change Exterior Grid #
    #out_r = np.amin(a[redux])
    #out_e = ecc(out_r)
    #out_w = per(out_r)

    new_px[redux] = pos_d[redux, 0]
    new_py[redux] = pos_d[redux, 1]
    new_vx[redux] = vel_d[redux, 0]
    new_vy[redux] = vel_d[redux, 1]

    # Alter Disk #
    data[keys[0]][:, 0] = new_px
    data[keys[0]][:, 1] = new_py
    data[keys[4]][:, 0] = new_vx
    data[keys[4]][:, 1] = new_vy
    root.close()

    return output


"""Classes for web services, HTTP requests, and HTTP exchanges.
Also a testing superclass for use by all the specific service test classes.

This utility is specific to the phylotastic web API, not a
completely general tool."""

import sys, os, requests, time, unittest, json, time

# The content-type that we anticipate getting from the web services
# when the content is json.
# At one point this was text/html, but it has since been changed to
# application/json.
anticipated_content_type = 'application/json'

# Ensure unique instantiation of each service object

services_registry = {}    # url -> Service
requests_registry = {}    # label -> Request

def get_service(group, specific_path):
    """Retrieve or create a Service object for a single URL.
    'group' is actually a port number (5004 etc.).
    'specific_path' is the part of the path in the URL
    following the part that is shared by all the services, e.g.
    'fn/names_url'. """

    url = str('http://phylo.cs.nmsu.edu:%s/phylotastic_ws/%s' % (group, specific_path))
    if url in services_registry:
        return services_registry[url]
    service = Service(url)
    services_registry[url] = service
    return service

def parse_service_url(url):
    """Given a URL, extract the 'group' and 'specific_path'
    (See the get_service function.)"""

    parts = url.split('/phylotastic_ws/')
    return (parts[0].split(':')[1],
            parts[1])

def get_request(label):
    """Retrieve an existing Request object having the given label."""
    return requests_registry.get(str(label))

class Service():
    def __init__(self, url):
        self.url = url
        self.requests = {}  # maps (method, parameters) to Request

    def get_request(self, method='GET', parameters={},
                    label=None, source=None, expect_status=None):
        key = (method, json.dumps(parameters, sort_keys=True))
        r = self.requests.get(key)
        if r == None:
            r = Request(self, method, parameters, label, source=source, expect_status=expect_status)
            self.requests[key] = r
        elif label != None:
            # Add label to existing Request that has none
            r.label = label
            requests_registry[str(label)] = r
        return r

    # exchange blob
    def get_request_from_blob(self, blob):
        return self.get_request(blob[u'method'],
                                (blob[u'parameters']
                                 if u'parameters' in blob
                                 else blob[u'data']),
                                label=blob[u'label'],
                                source=blob[u'source'])

    def name(self):
        return self.url.split('phylotastic_ws/')[-1]

    def get_examples(self):
        return [r for r in self.requests.values() if r.examplep]

    def get_times():
        times = []
        for r in requests.values():
            for x in r.exchanges:
                times.append(x.time)
        return times

class Request():
    """Every Service has a set of requests that can be (or have been) made.
    It's useful to keep track of them, e.g. so that we can do timing profiles.
    Typically a Request is a test or example."""

    def __init__(self, service, method, parameters, label, source=None, expect_status=None):
        self.service = service
        self.method = method
        self.parameters = parameters
        self.label = label
        if label != None:
            requests_registry[str(label)] = self
        self.source = source
        self.expect_status = expect_status
        self.exchanges = []   # ?

    def exchange(self):
        """Perform a single exchange for this request (method, url, query)"""

        time1 = time.time()      # in seconds, floating point
        if self.method == 'GET':
            # should we set an accept: header here?
            # in theory, yes.
            # but no, because the documentation never sets one.
            resp = requests.get(self.service.url,
                                params=self.parameters,
                                headers={'Accept': 'application/json,*/*;q=0.1'})
        elif self.method == 'POST':
            resp = requests.post(self.service.url,
                                 headers={'Content-type': 'application/json',
                                          'Accept': 'application/json,*/*;q=0.1'},
                                 data=json.dumps(self.parameters))
        else:
            print >>sys.stderr, '** unrecognized method:', self.method
        time2 = time.time()
        x = Exchange(self, response=resp, time=(time2 - time1))
        self.exchanges.append(x) # for timing analysis
        return x

    def stringify(self):
        return('%s %s?%s' %
               (self.method,
                self.service.url,
                json.dumps(self.parameters)[0:60]))

    def to_dict(self):
        return {'label': self.label,
                'service': self.service.url,
                'method': self.method,
                'parameters': self.parameters,
                'source': self.source,
                'expect_status': self.expect_status}

def to_request(blob):
    if isinstance(blob, unicode):
        # blob is a label and is globally unique
        r = get_request(blob)
        if r == None:
            print >>sys.stderr, '** No such request:', label
        return r
    else:
        (group, specific_path) = parse_service_url(blob[u'service'])
        service = get_service(group, specific_path)
        return service.get_request(method=blob[u'method'],
                                   parameters=blob[u'parameters'],
                                   label=blob[u'label'],
                                   source=blob[u'source'],
                                   expect_status=blob.get(u'expect_status'))

class Exchange():
    """An Exchange is an activation of a Request yielding either an error
    or a response (in the 'requests' library sense) and taking up time."""

    def __init__(self, request, time=None, response=None,
                 content_type='application/json',     # type *requested*
                 status_code=200, text=None, json=None):
        self.request = request
        self.time = time
        self.the_json = False
        if response != None:
            self.status_code = response.status_code
            self.text = response.text
            self.the_json = None
            ct = response.headers['content-type'].split(';')[0]
            self.content_type = ct
            if ct == 'application/json':
                self.the_json = response.json()
                # I expected the status code to be 4xx.
                # Instead, there's a 200 response, with a status_code
                # key in the JSON dict whose value is 400.
                if self.status_code == 200 and u'status_code' in self.the_json:
                    self.status_code = self.the_json[u'status_code']

        else:
            self.content_type = content_type
            self.status_code = status_code
            self.text = text
            self.the_json = json

    def json(self):
        return self.the_json

    def to_dict(self):
        if False:
            return {'request': self.request.to_dict(),
                    'time': self.time,
                    'status_code': self.status_code,
                    'content_type': self.content_type,
                    'response': self.json()}
        else:
            return {'request': self.request.label,
                    'time': self.time,
                    'status_code': self.status_code,
                    'content_type': self.content_type,
                    'response': self.json()}

def to_exchange(blob):
    rd = blob.get(u'request')
    if rd == None:
        # backward compatibility.  delete this code in a bit.
        (group, specific_path) = parse_service_url(blob[u'service'])
        service = get_service(group, specific_path)
        request = service.get_request(method=blob[u'method'],
                                      parameters=blob[u'data'],
                                      source=blob.get(u'source'))
    else:
        request = to_request(rd)
        if request == None:
            return None
    return Exchange(request,
                    content_type=blob[u'content_type'],
                    status_code=blob[u'status_code'],
                    json=blob[u'response'])

class WebappTestCase(unittest.TestCase):
    """Subclass of unittest.TestCase with some additional methods that are
    useful for testing web services.

    There should be one subclass of this class for each service."""

    # These methods get overridden in the subclasses!
    @classmethod
    def http_method(cls):
        raise unittest.SkipTest("can't test superclass")
    @classmethod
    def get_service(cls):
        raise unittest.SkipTest("can't test superclass")

    # Shortcut
    def get_request(self, method, parameters):
        return this.__class__.get_service().get_request(method, parameters)

    def assert_success(self, x, message=None):
        """Ensure that the JSON has the form of a successful response.
        x is an Exchange"""

        self.assert_response_status(x, 200, message)
        j = x.json()
        self.assertTrue(u'message' in j)
        self.assertEqual(j[u'message'], u'Success')
        # These were missing when I tried tnrs/ot/resolve on 10/25
        #self.assertTrue(u'execution_time' in j)
        #self.assertTrue(u'creation_time' in j)

    # Somehow check:
    #  Informative message:
    #   when service is down --
    #   when malformed input is provided --
    #  Expected response time: 3s~10s

    def assert_response_status(self, x, code, message=None):
        if message == None:
            message = '%s %s' % (x.status_code, x.json().get(u'message'))
        if x.status_code < 300:
            self.assertEqual(x.content_type, u'application/json', message)
        self.assertEqual(x.status_code, code, message)

    def regression_test_service(self): # unused
        """General method for doing regression tests, inherited by all
        the service-specific 'Test...' classes."""

        service = self.__class__.get_service()
        #print '\n# Regression testing:', service.url
        for request in service.requests.values():
            start_request_tests(request)

    def start_request_tests(self, request):
        present = request.exchange()
        if len(request.exchanges) > 0:
            self.check_adequacy(present, request.exchanges[0])
        return present

    def check_adequacy(self, now, then):
        """Is the 'now' exchange no worse than the 'then' exchange?"""
        now_cat = now.status_code / 100
        then_cat = then.status_code / 100
        self.assertTrue(now_cat <= then_cat)
        if now_cat == then_cat:
            self.assertTrue(now.status_code <= then.status_code)
            self.check_result(now.json(), then.json())
        else:
            print >>sys.err, ('Better status code now (%s) than before (%s)' %
                              (now.status_code, then.status_code))

    def check_result(self, now, then):
        """Recursion: Is the 'now' result no worse than the 'then' result?"""
        if isinstance(then, dict):
            self.assertTrue(isinstance(now, dict))
            for key in then:
                # Do we still have everything we had before?
                self.assertTrue(key in now)
                if key == u'creation_time': continue
                if key == u'execution_time': continue
                self.check_result(now[key], then[key])
        elif isinstance(then, list):
            self.assertTrue(isinstance(now, list))
            self.assertEqual(len(now), len(then))
            for (n, t) in zip(now, then):
                self.check_result(n, t)
        else:
            self.assertFalse(isinstance(now, dict))
            self.assertFalse(isinstance(now, list))
            self.assertEqual(now, then)

    @classmethod
    def tearDownClass(cls):
        maxtime = 0
        service = cls.get_service()
        if service == None: return
        for r in service.requests.values():
            for x in r.exchanges:
                if x.status_code == 200 and x.time > maxtime:
                    maxtime = x.time
        if maxtime > 0:
            print >>sys.stderr, '\nSlowest exchange for %s: %s' % (service.url, maxtime)

    def user_credentials(self):
        expires = config('access_token_expires')
        if expires == None or time.time() < expires:
            return (config('user_id'), config('access_token'))
        else:
            raise unittest.SkipTest("access token expired")

def write_requests(requests):
    """Write list of requests (read from documentation) to a file"""

    json.dump({'requests': [r.to_dict() for r in requests]},
              sys.stdout, indent=2, sort_keys=True)

def read_requests(inpath):
    """Read list of requests back in from file"""

    with open(inpath, 'r') as infile:
        j = json.load(infile)
        answer = [to_request(blob) for blob in j[u'requests']]
        print >>sys.stderr, 'Read %s requests from %s' % (len(requests_registry), inpath)
        return answer

def run_examples(requests):
    """Having read (or parsed) some examples, execute them"""

    exchanges = []
    i = 0
    for request in requests:
        if True:    #i % 17 == 3: for debugging
            print >>sys.stderr, request.stringify()
            exchange = request.exchange()
            if request.expect_status != None:
                if exchange.status_code != request.expect_status:
                    print >>sys.stderr, ('** Status code %s not what was expected (%s)' %
                                         (exchange.status_code, request.expect_status))
                    print >>sys.stderr, '   for', request.stringify()
            exchanges.append(exchange)
            time.sleep(1)
        i += 1
    print >>sys.stderr, i
    return exchanges

def read_exchanges(inpath):
    """Load exchanges that were previously executed and dumped to a file
    N.b. creating Exchange also stashes the request,
    for regression testing or whatever"""

    exchanges = []
    if not os.path.exists(inpath):
        print >>sys.stderr, 'No exhanges file:', inpath
        return []
    with open(inpath, 'r') as infile:
        j = json.load(infile)
        for blob in j[u'exchanges']:
            x = to_exchange(blob)
            if x != None:
                exchanges.append(x)
    print >>sys.stderr, 'Read %s exchanges from %s' % (len(exchanges), inpath)
    return exchanges

def write_exchanges(exchanges, outfile):
    """Write exchanges to file (or stdout)"""

    json.dump({'exchanges': [x.to_dict() for x in exchanges]},
              outfile, indent=2, sort_keys=True)

def find_resource(path):
    """Find a resource file on sys.path"""

    for option in sys.path:
        full = os.path.join(option, path)
        if os.path.exists(full):
            return full
    print >>sys.stderr, 'No such resource:', path
    return None

the_configuration = None

def config(param):
    """Get value from configuration file"""

    global the_configuration
    if the_configuration == None:
        path = find_resource('config.json')
        if path == None: return None
        with open(find_resource('config.json')) as infile:
            the_configuration = json.load(infile)
    if not param in the_configuration:
        print >>sys.stderr, 'No such configuration parameter:', param
    return the_configuration.get(param)

def main():
    """Main function for use by test_ files"""

    read_requests('work/requests.json')
    read_exchanges('work/exchanges.json')
    unittest.main()

# Default action from command line is to generate baseline
# exchanges for later regression checks.

if __name__ == '__main__':
    inpath = sys.argv[1]  #'work/requests.json'
    outpath = sys.argv[2] #'work/exchanges.json'
    the_requests = read_requests(inpath)
    # Get a baseline for future regression tests
    the_exchanges = run_examples(the_requests)
    with open(outpath, 'w') as outfile:
        write_exchanges(the_exchanges, outfile)


#!/usr/bin/env python
import math
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter
import matplotlib.dates as mdates
from datetime import datetime

# Toggle runtime warnings
warnings_on = True

# Todays datetime
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

# Enter your coin tickers and time masks here:
tickermasks = {
    'BTC'   : ['2017-09-01 00:00:00', str(now)],
    'ETH'   : ['2017-01-01 00:00:00', str(now)],
    'BTS'   : ['2017-08-30 00:00:00', str(now)],
    'STEEM' : ['2017-08-21 00:00:00', str(now)]}

my_tickers = list(tickermasks.keys())

# Empty dict that will be filled with len(my_tickers) number of dataframes
df = {}
dfx = {}
times = {}
marketcap = {}
volume = {}
price = {}

fig, axes = plt.subplots(len(my_tickers), figsize=(8,12))
fig.subplots_adjust(hspace=0.5)

# Check out http://socket.coincap.io/BTC for more "live" data
# Create dataframes for all tickers in my_tickers
for ticker in my_tickers:

    df[ticker] = pd.DataFrame(pd.read_json("http://socket.coincap.io/history/%s" % ticker))
    times[ticker] = ((df[ticker]['market_cap'].apply(pd.Series)[0])/1000).astype('int').astype('datetime64[s]')
    marketcap[ticker] = df[ticker]['market_cap'].apply(pd.Series)[1]
    price[ticker] = df[ticker]['price'].apply(pd.Series)[1]
    volume[ticker] = df[ticker]['volume'].apply(pd.Series)[1]

    dfx[ticker] = pd.DataFrame(dict(\
        time = times[ticker],
        marketcap = marketcap[ticker],
        volume = volume[ticker],
        price = price[ticker]))

    # Re-index dfx with time column
    dfx[ticker].set_index('time', inplace=True)

    # Check if now is out of bounds wrt dataset
    if (datetime.strptime(tickermasks[ticker][0], "%Y-%m-%d %H:%M:%S")) < dfx[ticker].index.min():
        tickermasks[ticker][0] = str(dfx[ticker].index.min())
        if warnings_on:
            print("WARNING: Chosen startdate for %s ticker is outside Coincap.io dataset. Timemask has been adjusted." % ticker)
    if (datetime.strptime(tickermasks[ticker][1], "%Y-%m-%d %H:%M:%S")) > dfx[ticker].index.max():
        tickermasks[ticker][1] = str(dfx[ticker].index.max())
        if warnings_on:
            print("WARNING: Chosen stopdate for %s ticker is outside Coincap.io dataset. Timemask has been adjusted." % ticker)

    # Create time mask based on tickermask input
    tickerindex = my_tickers.index(ticker)
    starttime = tickermasks[ticker][0]
    stoptime = tickermasks[ticker][1]
    mask = (dfx[ticker].index > starttime) & (dfx[ticker].index <= stoptime)
    mask_delta = datetime.strptime(stoptime, "%Y-%m-%d %H:%M:%S")-\
        datetime.strptime(starttime, "%Y-%m-%d %H:%M:%S")

    # Adjust visible ticks according to length of dataset
    x_major_interval = int(math.ceil((mask_delta.days/30)/10))
    if mask_delta.days < 14:
        x_minor_interval = 1
    else:
        x_minor_interval = int(mask_delta.days/10)

    # Plot ticker price vs chosen time interval
    axes[tickerindex].plot(dfx[ticker].index[mask], dfx[ticker]['price'][mask], color='black', label='Price')
    axes[tickerindex].grid(True)

    # Plot ticker market cap vs chosen time interval on seperate axis
    ax_mcap = axes[tickerindex].twinx()
    ax_mcap.plot(dfx[ticker].index[mask], dfx[ticker]['marketcap'][mask], '-.', color='black', label='Market Cap')

    # Add vertical padding to bottom part of price/marketcap plots to make
    # room for barplot. Adjust pad as needed.
    pad = 0.25
    yl = axes[tickerindex].get_ylim()
    axes[tickerindex].set_ylim(yl[0]-(yl[1]-yl[0])*pad,yl[1])
    y2 = ax_mcap.get_ylim()
    ax_mcap.set_ylim(y2[0]-(y2[1]-y2[0])*pad,y2[1])

    # Dynamic adjustment of y-axis labels depending on magnitude
    def ytickfrmt(value, pos):
        if 0 < value < 0.1:
            return '$%1.0fm' % (value*1e3)
        elif 0.1 <= value < 10:
            return '$%1.2f' % (value)
        elif 10 <= value < 1e4:
            return '$%1.0f' % (value)
        elif 1e4 <= value < 1e6:
            return '$%1.0fk' % (value*1e-3)
        elif 1e6 <= value < 1e9:
            return '$%1.0fM' % (value*1e-6)
        elif 1e9 <= value < 1e12:
            return '$%1.0fB' % (value*1e-9)
        elif value < 0:
            return ''
        else:
            return '$%1.0f' % value

    yformatter = FuncFormatter(ytickfrmt)

    # Set market cap axis labels
    ax_mcap.yaxis.set_major_formatter(yformatter)
    ax_mcap.locator_params(nbins=6, axis='y')
    ax_mcap.set_ylabel('Market Cap', fontsize=14)
    ax_volume = axes[tickerindex].twinx()

    # Plot bars with last element removed to avoid overlapping bars
    ax_volume.bar(dfx[ticker].index[mask][:-1].values, \
        dfx[ticker]['volume'][mask][:-1], \
        width=1, color='black', alpha=0.1, label='Volume')

    # Turn off ticks for volume barplot. We're only looking at the
    # changes in volume here and are less interested in the absolute values.
    ax_volume.axes.yaxis.set_ticklabels([])
    ax_volume.grid(False)

    # Increase scalefactor to reduce height of bars
    scalefactor = 1.3
    ax_volume.set_ylim(0, scalefactor*dfx[ticker]['volume'][starttime:stoptime].values.max())

    # Add empty dummy plots to get labels for twin axis
    axes[tickerindex].plot(np.nan, '-.', label = 'Market cap', color='black')
    axes[tickerindex].bar(dfx[ticker].index[mask].values, dfx[ticker]['volume'][mask]/1e16, \
        width=0.5, color='black', alpha=0.1, label='Volume')

    # Dynamic adjustment of x-axis labels
    if 1 <= mask_delta.days < 60:
        axes[tickerindex].xaxis.set_major_formatter(mdates.DateFormatter("\n%b\n%Y"))
        axes[tickerindex].xaxis.set_minor_formatter(mdates.DateFormatter("%d"))
    else:
        axes[tickerindex].xaxis.set_major_formatter(mdates.DateFormatter("%b\n%Y"))

    # Title, legend, etc
    axes[tickerindex].xaxis.set_major_locator(mdates.MonthLocator(interval=x_major_interval))
    axes[tickerindex].xaxis.set_minor_locator(mdates.DayLocator(interval=x_minor_interval))
    axes[tickerindex].set_title('%s data -- Last update: %s' % (ticker, dfx[ticker].index[-1]))
    axes[tickerindex].locator_params(nbins=6, axis='y')
    axes[tickerindex].legend(bbox_to_anchor=(1.4, 1.0), fontsize=10, loc=1, borderaxespad=0.)
    axes[tickerindex].set_ylabel('Price', fontsize=14)
    axes[tickerindex].yaxis.set_major_formatter(yformatter)

plt.savefig('CoincapGrabber_%s.png' % (str(datetime.now().strftime("%Y%m%d_%H%M%S"))), bbox_inches='tight')


"""
Helpers for running bitcoin-cli subprocesses.
"""

from decimal import Decimal
import json as systemjson
import shlex
import subprocess

verbose_mode = False
cli_args = None

def _verbose(content):
    """
    Print content iff verbose_mode is enabled.
    """
    if verbose_mode:
        print(content)

def _run_subprocess(exe, *args):
    """
    Run a subprocess (bitcoind or bitcoin-cli).

    Returns => (command, return code, output)

    exe: executable file name (e.g. bitcoin-cli)
    args: arguments to exe
    """
    cmd_list = [exe] + cli_args + list(args)
    _verbose("bitcoin cli call:\n  {0}\n".format(" ".join(shlex.quote(x) for x in cmd_list)))
    with subprocess.Popen(cmd_list, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as pipe:
        output, _ = pipe.communicate()
    output = output.decode('utf-8')
    retcode = pipe.returncode
    _verbose("bitcoin cli call return code: {0}  output:\n  {1}\n".format(retcode, output))
    return (cmd_list, retcode, output)

def call(*args):
    """
    Run `bitcoin-cli`, return OS return code.
    """
    _, retcode, _ = _run_subprocess("bitcoin-cli", *args)
    return retcode

def checkoutput(*args):
    """
    Run `bitcoin-cli`, fail if OS return code nonzero, return output.
    """
    cmd_list, retcode, output = _run_subprocess("bitcoin-cli", *args)
    if retcode != 0:
        raise subprocess.CalledProcessError(retcode, cmd_list, output=output)
    return output

def json(*args):
    """
    Run `bitcoin-cli`, parse output as JSON.
    """
    return systemjson.loads(checkoutput(*args), parse_float=Decimal)

def bitcoind_call(*args):
    """
    Run `bitcoind`, return OS return code.
    """
    _, retcode, _ = _run_subprocess("bitcoind", *args)
    return retcode