# -*- coding: utf-8 -*-
"""
Created on Fri May 28 16:47:58 2021

@author: wdu
"""
import sympy as sym

from sympy import *
from sympy import  Sum, factorial, oo, IndexedBase, Function
from sympy.abc import i, k, m, n, x

import numpy as np

import matplotlib.pyplot as plt
from scipy.io import loadmat, savemat

#----------------------------------------------

'''
#Derivatives of multivariable function
p=2
t=.5
c , n = sym.symbols('c n')
f = ((c*(1-n)**t)**(1-p) - 1)/(1-p)

#Differentiating partially w.r.t x
derivative_f = f.diff(c)
print(derivative_f)

f1 = lambdify([x,y], derivative_f )

p=2
t=.5
c , n = sym.symbols('c n')
h = ((c*(1-n)**t)**(1-p) - 1)/(1-p)

#Differentiating partially w.r.t x
derivative_fh = h.diff(n)
print(derivative_fh)

#-----------------------------------------------------------
#series

w = [1,2,3]
w = IndexedBase('w')

h = Sum( w[n]**2 , (n, 1, 3)).doit()
'''

#------------------------------------------------------------------------------

CJAC=loadmat('AltCJAC')
CJAC=list(CJAC.items())
CJAC=np.array(CJAC)
CJAC = CJAC[3][1].T

CJACW=loadmat('AltCJACW')
CJACW=list(CJACW.items())
CJACW=np.array(CJACW)
CJACW = CJACW[3][1].T

CJACN=loadmat('AltCJACN')
CJACN=list(CJACN.items())
CJACN=np.array(CJACN)
CJACN = CJACN[3][1].T

AJAC=loadmat('AltAJAC')
AJAC=list(AJAC.items())
AJAC=np.array(AJAC)
AJAC = AJAC[3][1]

AJACW=loadmat('AltAJACW')
AJACW=list(AJACW.items())
AJACW=np.array(AJACW)
AJACW = AJACW[3][1]

AJACN=loadmat('AltAJACN')
AJACN=list(AJACN.items())
AJACN=np.array(AJACN)
AJACN = AJACN[3][1]

#-------------------------------------------------------------------------------

tau = 0.1656344537815126
N_ss = 1.19
w_ss = 1/1.012
Z_ss = 1
LivPrb = .99375
DiscFac = .968
v=2

rstar = 1.048**.25 -1

rho = 2
C_ss = 1

#Phillips Curves parameters
#lambda_W = .899 #probability a firm won't be able to change wage
#lambda_P = .926  #probability a firm won't be able to change wage

lambda_W = .75 #probability a firm won't be able to change wage
lambda_P = .75  #probability a firm won't be able to change wage

Lambda = (1-lambda_P)*(1-(lambda_P/(1+rstar)))/lambda_P
ParamW = ( (1-lambda_W) / lambda_W) * ( 1 - LivPrb * lambda_W )

#Policy
phi = 0
phi_y = 0

#------------------------------------------------------------------------------

# Shock Parameters
Z = .01 # Initial Productivity shock
m_e = .01 # Initial Monetary Policy Shock
p=.66 # AR1 Coefficient

ZshkList=[]
mshkList=[]

for t in range(200):

    ZshkList.append((p**t)*Z)
    mshkList.append((p**t)*m_e)

Zshks= np.array(ZshkList)
mshk = np.array(mshkList)

# Specify Shock, if Shk = 0 then productivity shock, else Shk = 1 => monetary policy Shock

Shk = 1

dZ = np.zeros((400,1))
ShkLength = 200

if Shk == 0:

    for i in range(ShkLength):
        dZ[i][0] = Zshks[i]

if Shk == 1:

    for i in range(ShkLength):
       dZ[i + 200][0]=mshk[i]

#------------------------------------------------------------------------------
# this jacobian for pi_{t+1} wrt t=>0, below is jacobian for pi_{t} wrt t=>0

J_pi_w_1 = np.zeros((200,200)) # jacobian of inflation response to change in wage. Rows represent period in which there is a wage change. Columns represent period of inflation

for j in range(200):

    for i in range(200):

        if i < j:

            J_pi_w_1[i][j] = -Lambda*(-1/w_ss) * (1/(1+rstar)**(j-i))

# this jacobian for pi_{t+1} wrt t=>0, below is jacobian for pi_{t} wrt t=>0

J_pi_Z_1 = np.zeros((200,200)) # jacobian of inflation response to change in wage. Rows represent period in which wage change occurs. Columns denotes period of inflation

for j in range(200):

    for i in range(200):

        if i < j :
            J_pi_Z_1[i][j] =  -(1/(1+rstar)**(j-i))*(Lambda/Z_ss)

# Price inflation

J_pi_w = np.zeros((200,200)) # jacobian of inflation response to change in wage. Rows represent period in which there is a wage change. Columns represent period of inflation

for j in range(200):

    for i in range(200):

        J_pi_w[i][i] = -Lambda*(-1/w_ss)

        if i < j:
            J_pi_w[i][j] = -Lambda * (-1/w_ss) * ( 1 / (1+rstar)**(j-i))

J_pi_Z = np.zeros((200,200))

for j in range(200):

    for i in range(200):

        J_pi_Z[i][i] =   -Lambda/Z_ss

        if i < j :

            J_pi_Z[i][j] =  -(1/(1+rstar)**(j-i))*(Lambda/Z_ss)

#----------------------------------------------------------------------------
# Output

J_Y_N = np.zeros((200,200)) # Jacobian of output response to change in labor supply

for i in range(200):

    J_Y_N[i][i] = Z_ss

J_Y_Z = np.zeros((200,200)) # Jacobian of output response to change in labor supply

for i in range(200):

    J_Y_Z[i][i] = N_ss

#-----------------------------------------------------------------------------
# Government Spending

J_G_w = np.zeros((200,200)) #Jacobian of G wrt wage

for i in range(200):

    J_G_w[i][i] = tau*N_ss

J_G_N = np.zeros((200,200)) # Jacobian of G wrt N

for i in range(200):

    J_G_N[i][i] = tau*w_ss

#-----------------------------------------------------------------------------
# Nominal Rate

J_i_pi = np.zeros((200,200)) # Jacobian of i wrt pi

for i in range(200):

    J_i_pi[i][i] = phi

J_i_Y = np.zeros((200,200)) # Jacobian of i wrt Y

for i in range(200):

    J_i_Y[i][i] = phi_y

J_i_v = np.zeros((200,200)) # Jacobian of i wrt v

for i in range(200):

    J_i_v[i][i] = 1

#--------------------------------------------]
#----------------------------------------------------------------------
#Wage inflation

J_piw_C = np.zeros((200,200))

for j in range(200):

    for i in range(200):

        J_piw_C[i][i] =  (-rho/C_ss)

        if i<j:
            J_piw_C[i][j] =  (-rho/C_ss)*((DiscFac*LivPrb)**(j-i))

J_piw_C = -ParamW*J_piw_C

J_piw_w = np.zeros((200,200)) # Jacobian of wage Inflation wrt wage

for j in range(200):

    for i in range(200):

        J_piw_w[i][i] =  -ParamW *(1/w_ss)

        if i<j:
            J_piw_w[i][j] = -ParamW* (1/w_ss) *((DiscFac*LivPrb)**(j-i))

J_piw_w = J_piw_w + np.dot(J_piw_C,CJACW)

J_piw_N = np.zeros((200,200)) # Jacobian of wage inflation wrt N

for j in range(200):

    for i in range(200):

        J_piw_N[i][i] =  -ParamW*(-v/N_ss )

        if i<j:
            J_piw_N[i][j] =  -ParamW*(-v/N_ss) *((DiscFac*LivPrb)**(j-i))

J_piw_N = J_piw_N  + np.dot(J_piw_C,CJACN)

#-----------------------------------------------------------------------------

# Composing HU jacobian ways through DAG

#Goods Market Clearing Target
h1 = np.zeros((200,600))
h1[:,0:200] = CJAC #Partials wrt r
h1[:,200:400] =  CJACW + J_G_w #partials wrt w
h1[:,400:600] = CJACN - J_Y_N + J_G_N #Partials wrt N

# Wage Residual Target
h2 = np.zeros((200,600))
h2[:,0:200] =    - np.dot(J_piw_C, CJAC)
h2[:,200:400] = np.identity(200)*(1/w_ss) - J_piw_w + J_pi_w

for j in range(400):
    for i in range(200):
        if 200 + i == j and j>199 and j<400 :
            h2[i,j-1] = (-1/w_ss) - (-ParamW*(-rho/C_ss)*(CJACW[i][i-1] ))

h2_wagelag = np.zeros((200,200))
for j in range(200):
    for i in range(199):
        if  i + 1 == j :
            h2_wagelag[i+1, i ] = (1/w_ss)  + (-ParamW*(-rho/C_ss)*(CJACW[i+1][i] ))

h2[:,200:400]= np.identity(200)*(1/w_ss) - h2_wagelag - J_piw_w + J_pi_w

h2[:,400:600] =   -J_piw_N  #should be a negative here but it breaks things,

h3_r = np.zeros((200,200))
for j in range(200):
    for i in range(199):
        if  i + 1 == j :
            h3_r[i-1, i ] = 1 # because r_{t} =r_{t+1}^{a}

# Fisher Residual Target
h3 = np.zeros((200,600))
h3[:, 0:200] = h3_r
h3[:, 200:400] = (1+rstar)*J_pi_w_1 - phi*J_pi_w
h3[:, 400:600] = - np.dot(J_i_Y,J_Y_N)

h1h2= np.vstack((h1,h2))

HU = np.vstack((h1h2,h3))

#-------------------------------------------------------------------------------

# Composing HZ with DAG method

h1z  = np.zeros((200,400))
h1z[:,0:200] = - J_Y_Z

h2z = np.zeros((200,400))
h2z[:,0:200] = J_pi_Z

h3z = np.zeros((200,400))
h3z[:,0:200] = (1+rstar)*J_pi_Z_1 - phi * J_pi_Z - phi_y * J_Y_Z
h3z[:,200:400] = - J_i_v

# Stack all the matrices
h1zh2z= np.vstack((h1z,h2z))
HZ = np.vstack((h1zh2z,h3z))

#----------------------------------------------------------------------------------------
# Putting it all together

invHU = np.linalg.inv(HU)
G =np.dot(-invHU,HZ)
dU = np.dot(G,dZ)

dr = dU[0:200]
dw = dU[200:400]
dN = dU[400:600]

#Real Rate and Wage, Labor/hours
plt.plot(dr, label = 'Real Interest Rate')
plt.plot(dw , label = 'Real Wage')
plt.plot(dN , label = 'Labor')
plt.legend()
plt.show()

#Consumption
dC =  np.dot(CJAC,dr) + np.dot(CJACW,dw) + np.dot(CJACN,dN)
#plt.plot(dC)
#plt.title("Consumption")
#plt.show()

#Government Spending
dG = np.dot(J_G_N,dN) + np.dot(J_G_w,dw)
#plt.plot(dG)
#plt.title("Government Spending")
#plt.show()

#output
dY = np.dot(J_Y_N, dN) + np.dot(J_Y_Z,dZ[0:200])
#plt.plot(dY)
#plt.title("Output")
#plt.show()

#price inflation
dpi = np.dot(J_pi_w,dw) + np.dot(J_pi_Z,dZ[0:200])
#plt.plot(dpi)
#plt.title("Price Inflation")
#plt.show()

#wage inflation
dpiw = np.dot(J_piw_N,dN) + np.dot(J_piw_w,dw) +  np.dot(J_piw_C,dC)
#plt.plot(dpiw)
#plt.title("Wage Inflation")
#plt.show()

#nominal Rate
di = np.dot(J_i_pi, dpi) + np.dot(J_i_Y, dY) + np.dot(J_i_v, dZ[200:400])
#plt.plot(di)
#plt.title("Nominal Rate")
#plt.show()

#Dividends
dD = dY - dw*dN
#plt.plot(dD)
#plt.title("Dividends")
#plt.show()

#Stock Price

#percentages

fig, axs = plt.subplots(2, 2)
axs[0, 0].plot(100*dr )
axs[0, 0].set_title("Real Interest Rate")
axs[1, 0].plot(100*dw/w_ss)
axs[1, 0].set_title("Real Wage")
axs[1, 0].sharex(axs[0, 0])
axs[0, 1].plot(100*dpiw)
axs[0, 1].set_title("Nominal Wage Inflation")
axs[1, 1].plot(100*dpi)
axs[1, 1].set_title("Price Inflation")
fig.tight_layout()
#plt.savefig("GIPR1.jpg", dpi=500)

fig, axs = plt.subplots(2, 2)
axs[0, 0].plot(100*dY/N_ss)
axs[0, 0].set_title("Output")
axs[1, 0].plot(100*dC/C_ss)
axs[1, 0].set_title("Consumption")
axs[1, 0].sharex(axs[0, 0])
axs[0, 1].plot(100*dG/.19)
axs[0, 1].set_title("Government Spending")
axs[1, 1].plot(100*dN/N_ss)
axs[1, 1].set_title("Labor")
fig.tight_layout()
#plt.savefig("GIPR2.jpg", dpi=500)

fig, axs = plt.subplots(2, 2)
axs[0, 0].plot(dD)
axs[0, 0].set_title("Dividends")
axs[1, 0].plot(100*di)
axs[1, 0].set_title("Nominal Rate")
axs[1, 0].sharex(axs[0, 0])
axs[0, 1].plot(dZ[0:200])
axs[0, 1].set_title("Z")
axs[1, 1].plot(dZ[200:400])
axs[1, 1].set_title("v")
fig.tight_layout()

'''

fig, axs = plt.subplots(2, 2)
axs[0, 0].plot(dr)
axs[0, 0].set_title("Real Interest Rate")
axs[1, 0].plot(dw/w_ss)
axs[1, 0].set_title("Real Wage")
axs[1, 0].sharex(axs[0, 0])
axs[0, 1].plot(dpiw)
axs[0, 1].set_title("Nominal Wage Inflation")
axs[1, 1].plot(dpi)
axs[1, 1].set_title("Price Inflation")
fig.tight_layout()
#plt.savefig("GIPR1.jpg", dpi=500)

fig, axs = plt.subplots(2, 2)
axs[0, 0].plot(dY/N_ss)
axs[0, 0].set_title("Output")
axs[1, 0].plot(dC/C_ss)
axs[1, 0].set_title("Consumption")
axs[1, 0].sharex(axs[0, 0])
axs[0, 1].plot(dG/.19)
axs[0, 1].set_title("Government Spending")
axs[1, 1].plot(dN/N_ss)
axs[1, 1].set_title("Labor")
fig.tight_layout()
#plt.savefig("GIPR2.jpg", dpi=500)

fig, axs = plt.subplots(2, 2)
axs[0, 0].plot(dD/(N_ss*(1-w_ss)))
axs[0, 0].set_title("Dividends")
axs[1, 0].plot(di)
axs[1, 0].set_title("Nominal Rate")
fig.tight_layout()

rangelen = 30

fig, axs = plt.subplots(2, 2)
axs[0, 0].plot(dr[0:rangelen])
axs[0, 0].set_title("Real Interest Rate")
axs[1, 0].plot(dw[0:rangelen])
axs[1, 0].set_title("Real Wage")
axs[1, 0].sharex(axs[0, 0])
axs[0, 1].plot(dpiw[0:rangelen])
axs[0, 1].set_title("Nominal Wage Inflation")
axs[1, 1].plot(dpi[0:rangelen])
axs[1, 1].set_title("Price Inflation")
fig.tight_layout()
#plt.savefig("GIPR1.jpg", dpi=500)

fig, axs = plt.subplots(2, 2)
axs[0, 0].plot(dY[0:rangelen])
axs[0, 0].set_title("Output")
axs[1, 0].plot(dC[0:rangelen])
axs[1, 0].set_title("Consumption")
axs[1, 0].sharex(axs[0, 0])
axs[0, 1].plot(dG[0:rangelen])
axs[0, 1].set_title("Government Spending")
axs[1, 1].plot(dN[0:rangelen])
axs[1, 1].set_title("Labor")
fig.tight_layout()
#plt.savefig("GIPR2.jpg", dpi=500)

fig, axs = plt.subplots(2, 2)
axs[0, 0].plot(dD[0:rangelen])
axs[0, 0].set_title("Dividends")
axs[1, 0].plot(di[0:rangelen])
axs[1, 0].set_title("Nominal Rate")
axs[1, 0].sharex(axs[0, 0])
axs[0, 1].plot(dZ[0:200])
axs[0, 1].set_title("Z")
axs[1, 1].plot(dZ[200:400])
axs[1, 1].set_title("v")
fig.tight_layout()

'''

'''

def PsumMrs(t,d,x):
    # t is the current period
    # d is the period in which there is a deviation in the interest rate

    result = 0

# =============================================================================
#     if x==1:
#
#         for k in range(t):
#             result +=(LivPrb**k)*((rho/C_ss)*(DiscFac**k)*CJAC[t][k])
#     else:
#
# =============================================================================

    if x == 0:
        JAC = CJAC
    elif x==1:
        JAC =CJACW
    elif x==2:
        JAC = CJACN

    for k in range(200-t):
        result +=(LivPrb**k)*((rho/C_ss)*JAC[d][t+k]) #k here is the value in period k when the change occurs in period t

    #for k in range(200-t):
        #result +=(LivPrb**k)*((rho/C_ss)*(DiscFac**k)*JAC[d][t+k])

    result = -ParamW*result

    return result

H_u = np.zeros((600,600))

H1=[] #target 1
for i in range(200):
    H1.append(3*i)

H2 =[] # target 2
for i in range(200):
    H2.append(3*i + 1)

H3 = [] # target 3
for i in range(200):
    H3.append(3*i + 2)

#------------------------------------------------------------------------------

# the following calculates H_1 partial derivatives w.r.t. r,w,N for all t = 0,1,2,...
# i/3 is the period, t, that we are in
# j is the period in which the deviation occurs

for i in H1:

    for j in range(200):
        H_u[i][j] = CJAC[j][int(i/3)]
        H_u[i][200 + j] = CJACW[j][int(i/3)]
        H_u[i][400 + j] = CJACN[j][int(i/3)]

    H_u[i][200 + int(i/3)] =  CJACW[int(i/3)][int(i/3)] - tau*N_ss
    H_u[i][400 + int(i/3)] = CJACN[int(i/3)][int(i/3)] - Z_ss - w_ss*tau

#------------------------------------------------------------------------------

for i in H2:
    for j in range(200):
                                               # (i-1)/3 is the period, t, that we are in
        H_u[i][j] = PsumMrs(int((i-1)/3) , j, 0)  # j is the period in which the deviation occurs

        if int((i-1)/3) > j:

           H_u[i][200 + j] = PsumMrs(int((i-1)/3), j, 1 ) #wage
           H_u[i][400 + j] =  PsumMrs(int((i-1)/3), j, 2 ) #labor

        elif int((i-1)/3)  ==  j + 1:

            H_u[i][200 + j] = - 1/w_ss + PsumMrs(int((i-1)/3), j, 1 )
            H_u[i][400 + j] = PsumMrs(int((i-1)/3), j, 2 )

        elif int((i-1)/3) ==  j:

            H_u[i][200 + j] = 1/w_ss - ParamW*(1/w_ss) + PsumMrs(int((i-1)/3), j, 1 )  - Lambda*(-1/w_ss)
            H_u[i][400 + j] = ParamW* (-v/N_ss) + PsumMrs(int((i-1)/3), j, 2 ) # should a discount factor be added here?

        elif int((i-1)/3) < j:
            H_u[i][200 + j] =  - ParamW*(LivPrb**j)*((1/w_ss))  +  PsumMrs(int((i-1)/3), j, 1 ) - (Lambda/(1+rstar)**(j-int((i-1)/3)))*(-1/w_ss)
            H_u[i][400 + j] = ParamW*(LivPrb**(j-int((i-1)/3)))*(-v/N_ss) + PsumMrs(int((i-1)/3), j, 2 )

    H_u[i][200] = 1/w_ss + ParamW*1/w_ss +  PsumMrs(int((i-1)/3),0, 1 )+ Lambda*(-1/w_ss)

    #--------------------------------------------------------------------------

for i in H3:

    for j in range(200):

        if int((i-2)/3) == j:
             H_u[i][j] = 1
             H_u[i][200 + j] = phi*Lambda*(1/w_ss)
             H_u[i][400 + j] = phi_y*Z_ss

        elif int((i-2)/3) < j:
            H_u[i][j] = 0
            H_u[i][200 + j] = -(Lambda/(1+rstar)**j)*(1/w_ss)*(1+rstar) + (phi*Lambda/(1+rstar)**(j-int((i-2)/3)))*(1/w_ss)
            H_u[i][400 + j] = 0

        elif int((i-2)/3) > j:
            H_u[i][j] = 0
            H_u[i][200 + j] = 0
            H_u[i][400 + j] = 0

#------------------------------------------------------------------------------

H_z = np.zeros((600,400))

for i in H1:

    for j in range(200):

        if int(i/3)== j:
             H_z[i][j] = - N_ss

#------------------------------------------------------------------------------

for i in H2:

    for j in range(200):

        if int((i-1)/3) == j:

            H_z[i][j] = - Lambda/Z_ss

        if int((i-1)/3) < j:

            H_z[i][j] = - (Lambda / (1 + rstar)**(j-int((i-1)/3)))*(1/Z_ss)

#------------------------------------------------------------------------------

for i in H3:

    for j in range(200):

        if int((i-2)/3) == j :

            H_z[i][j] =   phi*Lambda/Z_ss - phi_y*N_ss
            H_z[i][200 + j] = -1

        if int((i-2)/3) < j :

            H_z[i][j] =  -(1+rstar)*(1/(1+rstar)**(j-int((i-2)/3)))*(Lambda/Z_ss) + (1/(1+rstar)**(j-int((i-2)/3)))*phi*Lambda/Z_ss - phi_y*N_ss

#----------------------------------------------------------------------------------

Inv_H_u = np.linalg.inv(H_u)

dU = np.dot( np.dot(-Inv_H_u,H_z),dZ)

dr = dU[0:200]
dw = dU[200:400]
dN = dU[400:600]

plt.plot(dr, label = 'Interest Rate')
plt.plot(dw , label = 'Wage')
plt.plot(dN , label = 'Labor')
plt.legend()
plt.show()

#Consumption
dC =  np.dot(CJAC,dr) + np.dot(CJACW,dw) + np.dot(CJAC,dN)
plt.plot(dC)
plt.title("Consumption")
plt.show()

#Government Spending
dG = np.dot(J_G_N, dN) + np.dot(J_G_w,dw)
plt.plot(dG)
plt.title("Government Spending")
plt.show()

#output
dY = np.dot(J_Y_N, dN) + np.dot(J_Y_Z,dZ[0:200])
plt.plot(dY)
plt.title("Output")
plt.show()

#price inflation
dpi = np.dot(J_pi_w,dw) + np.dot(J_pi_Z,dZ[0:200])
plt.plot(dpi)
plt.title("Price Inflation")
plt.show()

#wage inflation
dpiw = np.dot(J_piw_C,dC) + np.dot(J_piw_N,dN) + np.dot(J_piw_w,dw)
plt.plot(dpiw)
plt.title("Wage Inflation")
plt.show()

#nominal Rate
di = np.dot(J_i_pi, dpi) + np.dot(J_i_Y, dY) + np.dot(J_i_v, dZ[200:400])
plt.plot(di)
plt.title("Nominal Rate")
plt.show()

fig, axs = plt.subplots(2, 2)
axs[0, 0].plot(dr)
axs[0, 0].set_title("Interest Rate")
axs[1, 0].plot(dw)
axs[1, 0].set_title("Wage")
axs[1, 0].sharex(axs[0, 0])
axs[0, 1].plot(dpiw)
axs[0, 1].set_title("Wage Inflation")
axs[1, 1].plot(dpi)
axs[1, 1].set_title("Inflation")
fig.tight_layout()

fig, axs = plt.subplots(2, 2)
axs[0, 0].plot(dY)
axs[0, 0].set_title("Output")
axs[1, 0].plot(dC)
axs[1, 0].set_title("Consumption")
axs[1, 0].sharex(axs[0, 0])
axs[0, 1].plot(dG)
axs[0, 1].set_title("Government")
axs[1, 1].plot(dN)
axs[1, 1].set_title("Labor")
fig.tight_layout()

'''

#-----------------


# THIS IS dashboard BLUEPRINT for dashboard page
# This is where user their dashboard for postings or messages
from flask import Blueprint, render_template, request,session

def initDashBoard(db):
    dashboard = Blueprint('dashboard', __name__)

    @dashboard.route('/dashboard')
    def dashboardPage():
        return render_template('dashboard/dashboard.html')

    @dashboard.route('/messages')
    def messages():
        msgs = db.message.getDashBoardMessage()
        print(msgs)
        numMsgs = len(msgs)
        return render_template('dashboard/message.html', msgs=msgs, numMsgs=numMsgs)

    @dashboard.route('/userPostings')
    def userPostings():
        # allPosts = db.getAllPostings()
        # posts = db.getPostingOrganizedData(allPosts)
        allPosts = db.post.getAPosting("email", session['email'])
        posts = db.post.getPostingOrganizedData(allPosts,2)
        numPosts = len(posts)
        return render_template('dashboard/postings.html', posts=posts, numPosts=numPosts)

    @dashboard.route('/dashboard/delete/<postid>', methods= ['GET' , 'POST'])
    def deletePost(postid):
        print(postid)
        db.post.deleteAPosting(postid)

        #getting all the remaining posts in current account
        allPosts = db.post.getAPosting("email", session['email'])
        posts = db.post.getPostingOrganizedData(allPosts)
        numPosts = len(posts)

        return render_template('dashboard/postings.html', posts=posts, numPosts=numPosts)

    return dashboard


import unittest

import numpy as np

from pymoo.operators.survival.rank_and_crowding import RankAndCrowdingSurvival

class NonDominatedRankTest(unittest.TestCase):
    def test_crowding_distance(self):
        F = np.array([[0.31, 6.10], [0.22, 7.09], [0.79, 3.97], [0.27, 6.93]])
        cd = RankAndCrowdingSurvival.calc_crowding_distance(F, F_min=np.array([0.1, 0]), F_max=np.array([1, 60]))
        self.assertTrue(np.all(np.round(cd, decimals=2) == np.array([0.63, np.inf, np.inf, 0.12])))

    def test_crowding_distance_degenerated(self):
        F = np.array([[0.0, 6.10], [0.0, 7.09], [0.0, 7.09]])
        cd = RankAndCrowdingSurvival.calc_crowding_distance(F)

        print(cd)

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


import argparse

import cv2
import matplotlib.pyplot as plt
from PIL import Image
from torchvision import transforms

from utils.model_utils import *

def get_attention_mask(im, x, model):
    logits, att_mat = model(x.unsqueeze(0))
    att_mat = torch.stack(att_mat).squeeze(1)

    # Average the attention weights across all heads.
    att_mat = torch.mean(att_mat, dim=1)

    # To account for residual connections, we add an identity matrix to the
    # attention matrix and re-normalize the weights.
    residual_att = torch.eye(att_mat.size(1))
    aug_att_mat = att_mat + residual_att
    aug_att_mat = aug_att_mat / aug_att_mat.sum(dim=-1).unsqueeze(-1)

    # Recursively multiply the weight matrices
    joint_attentions = torch.zeros(aug_att_mat.size())
    joint_attentions[0] = aug_att_mat[0]

    for n in range(1, aug_att_mat.size(0)):
        joint_attentions[n] = torch.matmul(aug_att_mat[n], joint_attentions[n - 1])

    # Attention from the output token to the input space.
    v = joint_attentions[-1]
    grid_size = int(np.sqrt(aug_att_mat.size(-1)))
    mask = v[0, 1:].reshape(grid_size, grid_size).detach().numpy()
    mask = cv2.resize(mask / mask.max(), im.size)[..., np.newaxis]
    # result = (mask * im).astype("uint8")

    return mask

def visualize(model_dir, img_path, plot_layerwise_attentions=False, base=False):
    config_file = os.path.join(model_dir, 'model_config.json')
    with open(config_file) as cfg:
        config = json.load(cfg)
    print('Visualizing attention for model:')
    print(config)

    if base:
        model = VisionTransformer(CONFIGS[config['model_type']], num_classes=21843, zero_head=False,
                                  img_size=config['img_size'], vis=True)
        model.load_from(np.load('checkpoints/pretrained_ckpts/ViT-B_16.npz'))
    else:
        model = VisionTransformer(CONFIGS[config['model_type']], num_classes=config['num_classes'], zero_head=False,
                                  img_size=config['img_size'], vis=True)
        checkpoint_file = os.path.join(model_dir, 'checkpoint.bin')
        model.load_state_dict(torch.load(checkpoint_file, map_location=torch.device('cpu')))
    model.eval()

    transform = transforms.Compose([
        transforms.Resize((config['img_size'], config['img_size'])),
        transforms.ToTensor(),
        transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]),
    ])
    im = Image.open(img_path)
    x = transform(im)

    mask = get_attention_mask(im, x, model)

    fig, ax1 = plt.subplots(ncols=1, figsize=(5, 5))

    ax1.set_title('Attention map')
    _ = ax1.imshow(im)
    _ = ax1.imshow(mask, cmap='jet', alpha=0.5)
    plt.show()

    return mask

def visualize_imgs(model_dir, img_dir, plot_layerwise_attentions=False, base=False):
    config_file = os.path.join(model_dir, 'model_config.json')
    with open(config_file) as cfg:
        config = json.load(cfg)
    print('Visualizing attention for model:')
    print(config)

    if base:
        model = VisionTransformer(CONFIGS[config['model_type']], num_classes=21843, zero_head=False,
                                  img_size=config['img_size'], vis=True)
        model.load_from(np.load('checkpoints/pretrained_ckpts/ViT-B_16.npz'))
    else:
        model = VisionTransformer(CONFIGS[config['model_type']], num_classes=config['num_classes'], zero_head=False,
                                  img_size=config['img_size'], vis=True)
        checkpoint_file = os.path.join(model_dir, 'checkpoint.bin')
        model.load_state_dict(torch.load(checkpoint_file, map_location=torch.device('cpu')))
    model.eval()

    transform = transforms.Compose([
        transforms.Resize((config['img_size'], config['img_size'])),
        transforms.ToTensor(),
        # transforms.Lambda(lambda x: x.repeat(3, 1, 1)),
        transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]),
    ])
    for img_path in os.listdir(img_dir):
        if 'jpg' in img_path or 'png' in img_path or 'ppm' in img_path or 'JPG' in img_path:
            im = Image.open(os.path.join(img_dir,img_path))
            x = transform(im)
            mask = get_attention_mask(im, x, model)

            fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(10, 5))
            ax1.imshow(im)
            _ = ax2.imshow(im)
            _ = ax2.imshow(mask, cmap='jet', alpha=0.5)
            plt.show()
            fig.savefig(os.path.join('data/test_imgs', 'attn_images/attn_'+img_path.split('.')[0]+'.png'), bbox_inches='tight')

    return

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--model_config", type=str, default="checkpoints/output_ckpts/cifar10_img224",
                        help="Where to search for pretrained ViT models.")
    parser.add_argument("--test_img", type=str, default="data/test_imgs/traffic_sign2.png",
                        help="Where to search for pretrained ViT models.")
    parser.add_argument("--img_dir", type=str, default="data/test_imgs",
                        help="Where to search for pretrained ViT models.")
    args = parser.parse_args()
    # visualize(args.model_config, args.test_img, plot_layerwise_attentions=False, base=True)
    visualize_imgs(args.model_config, args.img_dir, plot_layerwise_attentions=False, base=True)

    return

if __name__ == "__main__":
    main()


#code writting for executing in python 3:
#virtualenv: cleanPy3
#path: /Users/tina/.virtualenvs/cleanPy3/bin/python3.5
# env name: CleanPy
#header source saved into SQLite db: data_wrangling.db
##Replacing Headers:
from csv import DictReader
import pprint

data_file = '../data/unicef/mn.csv'
headers_file = '../data/unicef/mn_headers_updated.csv'

def getting_data(data_file, headers_file):
    '''Input: data and headers .csv files.
    Reads data in as dictionaries
    adds data row by row to lists'''
    data_rdr = DictReader(open(data_file), 'rb')
    header_rdr = DictReader(open(headers_file), 'rb')
    data_rows = [d for d in data_rdr]
    header_rows = [hd for hd in header_rdr]
    return(data_rows, header_rows)

def short_to_long(header_rows):
    '''Input: header_rows from getting_data[1]
    Maps short to long headings from header data
    Returns header dictionary
     '''
    headers = {}
    for header_dict in header_rows:
        headers[header_dict['r']] = header_dict['b']
    return headers

def expand_data_headers(data_rows, headers):
    '''Input: data_rows list from getting_data[0], headers dictionary from short_to_long(header_rows).
    Changes short headers to long headers
    Returns data with long headings'''
    new_rows = []
    for data_dict in data_rows[:1]:
        new_dict = {}
        for dkey, dval in list(data_dict.items()):
            print('dkey:', dkey)
            print('dval:', dval)
            for short_head in dval:
                print('short_head:', short_head)
                print('dval.index(short_head):', dval.index(short_head))
                # new_dict[]
            # for i in range(len(dval)):
            #     print(i)
                # if dval[i] in headers.keys():
                #     print('Match!')
                #     print('dval[i]', dval[i])
                #     print('headers[dval[i]]:', headers[dval[i]])
                #     print()
                    # item = headers[dval[i]]
                    # print(item)
                    # data_dict[dkey[i]]

header_rows = getting_data(data_file, headers_file)[1]
headers = short_to_long(header_rows)
data_rows = getting_data(data_file, headers_file)[0]
print(data_rows[:2])
data = expand_data_headers(data_rows, headers)
# pprint.pprint(headers)


import torch
import numpy as np
from torch.autograd import Variable
from data.Vocab import NMTVocab
import time
import math
import sys
import os

_FLOAT32_INF = np.float32(np.finfo('float32').max / 10)

class Beam(object):
    """
    Class for managing the internals of the beam search process.

    Takes care of beams, back pointers, and scores.

    Args:
       size (int): beam size
       pad, bos, eos (int): indices of padding, beginning, and ending.
       n_best (int): nbest size to use
       cuda (bool): use gpu
       global_scorer (:obj:`GlobalScorer`)
    """
    def __init__(self, size, pad, bos, eos,
                 n_best=1, cuda=False,
                 global_scorer=None,
                 min_length=0,
                 stepwise_penalty=False):

        self.size = size
        self.tt = torch.cuda if cuda else torch

        # The score for each translation on the beam.
        self.scores = self.tt.FloatTensor(size).zero_()
        self.all_scores = []

        # The backpointers at each time-step.
        self.prev_ks = []

        # The outputs at each time-step.
        self.next_ys = [self.tt.LongTensor(size)
                        .fill_(pad)]
        self.next_ys[0][0] = bos

        # Has EOS topped the beam yet.
        self._eos = eos
        self.eos_top = False

        # The attentions (matrix) for each time.
        self.attn = []

        # Time and k pair for finished.
        self.finished = []
        self.n_best = n_best

        # Information for global scoring.
        self.global_scorer = global_scorer
        self.global_state = {}

        # Minimum prediction length
        self.min_length = min_length

        # Apply Penalty at every step
        self.stepwise_penalty = stepwise_penalty

    def get_current_state(self):
        "Get the outputs for the current timestep."
        return self.next_ys[-1]

    def get_current_origin(self):
        "Get the backpointers for the current timestep."
        return self.prev_ks[-1]

    def advance(self, word_probs, attn_out):
        """
        Given prob over words for every last beam `wordLk` and attention
        `attn_out`: Compute and update the beam search.

        Parameters:

        * `word_probs`- probs of advancing from the last step (K x words)
        * `attn_out`- attention at the last step

        Returns: True if beam search is complete.
        """
        num_words = word_probs.size(1)
        if self.stepwise_penalty:
            self.global_scorer.update_score(self, attn_out)
        # force the output to be longer than self.min_length
        cur_len = len(self.next_ys)
        if cur_len < self.min_length:
            for k in range(len(word_probs)):
                word_probs[k][self._eos] = -1e20
        # Sum the previous scores.
        if len(self.prev_ks) > 0:
            beam_scores = word_probs + \
                self.scores.unsqueeze(1).expand_as(word_probs)
            # Don't let EOS have children.
            for i in range(self.next_ys[-1].size(0)):
                if self.next_ys[-1][i] == self._eos:
                    beam_scores[i] = -1e20
        else:
            beam_scores = word_probs[0]
        flat_beam_scores = beam_scores.view(-1)
        best_scores, best_scores_id = flat_beam_scores.topk(self.size, 0,
                                                            True, True)

        self.all_scores.append(self.scores)
        self.scores = best_scores

        # best_scores_id is flattened beam x word array, so calculate which
        # word and beam each score came from
        prev_k = best_scores_id / num_words
        self.prev_ks.append(prev_k)
        self.next_ys.append((best_scores_id - prev_k * num_words))
        self.attn.append(attn_out.index_select(0, prev_k))
        self.global_scorer.update_global_state(self)

        for i in range(self.next_ys[-1].size(0)):
            if self.next_ys[-1][i] == self._eos:
                global_scores = self.global_scorer.score(self, self.scores)
                s = global_scores[i]
                self.finished.append((s, len(self.next_ys) - 1, i))

        # End condition is when top-of-beam is EOS and no global score.
        if self.next_ys[-1][0] == self._eos:
            self.all_scores.append(self.scores)
            self.eos_top = True

    def done(self):
        return self.eos_top and len(self.finished) >= self.n_best

    def sort_finished(self, minimum=None):
        if minimum is not None:
            i = 0
            # Add from beam until we have minimum outputs.
            while len(self.finished) < minimum:
                global_scores = self.global_scorer.score(self, self.scores)
                s = global_scores[i]
                self.finished.append((s, len(self.next_ys) - 1, i))
                i += 1

        self.finished.sort(key=lambda a: -a[0])
        scores = [sc for sc, _, _ in self.finished]
        ks = [(t, k) for _, t, k in self.finished]
        return scores, ks

    def get_hyp(self, timestep, k):
        """
        Walk back to construct the full hypothesis.
        """
        hyp, attn = [], []
        for j in range(len(self.prev_ks[:timestep]) - 1, -1, -1):
            hyp.append(self.next_ys[j+1][k])
            attn.append(self.attn[j][k])
            k = self.prev_ks[j][k]
        return hyp[::-1], torch.stack(attn[::-1])

def tile_batch(x, multiplier, batch_dim=0):
    """
    :type x: Variable
    """
    x_size = x.size()
    out_size = x_size[:batch_dim] + (x_size[batch_dim] * multiplier,) + x_size[batch_dim+1:]

    x_tiled = torch.unsqueeze(x, dim=batch_dim + 1)
    x_tiled = x_tiled.repeat(*[1 if d != batch_dim + 1 else multiplier for d in range(len(x_size) + 1)])
    x_tiled = x_tiled.view(*out_size)

    return x_tiled

def mask_scores(scores, beam_mask, eos_id):
    """
    Mask scores of next step according to beam mask.
    Args:
        scores (torch.Tensor): Scores of next tokens with shape [batch_size, beam_size, vocab_size].
            Smaller should be better (usually negative log-probs).
        beam_mask (torch.Tensor): Mask of beam. 1.0 means not closed and vice verse. The shape is
            [batch_size, beam_size]

    Returns:
        Masked scores of next tokens.
    """
    vocab_size = scores.size(-1)

    finished_row = beam_mask.new(vocab_size, ).zero_() + float(_FLOAT32_INF)

    # If beam finished, only PAD could be generated afterwards.
    finished_row[eos_id] = 0.0

    scores = scores * beam_mask.unsqueeze(2) + \
             torch.matmul((1.0 - beam_mask).unsqueeze(2), finished_row.unsqueeze(0))

    return scores

def tensor_gather_helper(gather_indices,
                         gather_from,
                         batch_size,
                         beam_size,
                         gather_shape,
                         use_gpu):

    range_ = (torch.arange(0, batch_size) * beam_size).long()

    if use_gpu:
        range_ = range_.cuda()

    gather_indices_ = (gather_indices + torch.unsqueeze(range_, 1)).view(-1)

    output = torch.index_select(gather_from.view(*gather_shape), 0, gather_indices_)

    out_size = gather_from.size()[:1 + len(gather_shape)]

    return output.view(*out_size)

def reranking_beams(word_ids, scores):

    word_ids = word_ids.cpu().numpy()
    scores = scores.cpu().numpy()

    # Reranking beams
    reranked_beams = np.argsort(scores, axis=1)
    reranked_word_ids = np.ones_like(word_ids) * NMTVocab.PAD

    for b in range(scores.shape[0]):
        for ii in reranked_beams[b]:
            reranked_word_ids[b, ii] = word_ids[b, ii]

    reranked_word_ids = reranked_word_ids.tolist()

    return reranked_word_ids

def _yield_value(iterable):
    for value in iterable:
      yield value

def _yield_flat_nest(nest):
    for n in _yield_value(nest):
        if is_sequence(n):
            for ni in _yield_flat_nest(n):
                yield ni
        else:
            yield n

def is_sequence(seq):
    return isinstance(seq, list)

def flatten(nest):

    if is_sequence(nest):
        return list(_yield_flat_nest(nest))
    else:
        return [nest]

def _packed_nest_with_indices(structure, flat, index):

    packed = []
    for s in _yield_value(structure):
        if is_sequence(s):
            new_index, child = _packed_nest_with_indices(s, flat, index)
            packed.append(child)
            index = new_index
        else:
            packed.append(flat[index])
            index += 1
    return index, packed

def pack_sequence_as(structure, flat_sequence):

    if not is_sequence(flat_sequence):
        raise TypeError("flat_sequence must be a sequence")

    flat_structure = flatten(structure)

    if len(flat_structure) != len(flat_sequence):
        raise ValueError("Count not pack sequence: expected {0} but got {1}".format(len(flat_structure),
                                                                                len(flat_structure)))

    _, packed = _packed_nest_with_indices(structure, flat_sequence, 0)

    return packed

def _recursive_assert_same_structure(nest1, nest2):
    """Helper function for `assert_same_structure`."""
    is_sequence_nest1 = is_sequence(nest1)
    if is_sequence_nest1 != is_sequence(nest2):
        raise ValueError(
            "The two structures don't have the same nested structure.\n\n"
            "First structure: %s\n\nSecond structure: %s." % (nest1, nest2))

    if not is_sequence_nest1:
        return  # finished checking

    nest1_as_sequence = [n for n in _yield_value(nest1)]
    nest2_as_sequence = [n for n in _yield_value(nest2)]
    for n1, n2 in zip(nest1_as_sequence, nest2_as_sequence):
        _recursive_assert_same_structure(n1, n2)

def assert_same_structure(nest1, nest2):

    len_nest1 = len(flatten(nest1)) if is_sequence(nest1) else 1
    len_nest2 = len(flatten(nest2)) if is_sequence(nest2) else 1
    if len_nest1 != len_nest2:
        raise ValueError("The two structures don't have the same number of "
                         "elements.\n\nFirst structure (%i elements): %s\n\n"
                         "Second structure (%i elements): %s"
                         % (len_nest1, nest1, len_nest2, nest2))
    _recursive_assert_same_structure(nest1, nest2)

def map_structure(func, *structure):

    if not callable(func):
        raise TypeError("func must be callable!")

    for other in structure[1:]:
        assert_same_structure(structure[0], other)

    flat_structure = [flatten(s) for s in structure]
    entries = zip(*flat_structure)

    return pack_sequence_as(
        structure[0], [func(*x) for x in entries])

def np_pad_batch_2D(samples, pad, batch_first=True, volatile=False, cuda=True):

    batch_size = len(samples)

    sizes = [len(s) for s in samples]
    max_size = max(sizes)

    x_np = np.full((batch_size, max_size), fill_value=pad, dtype='int64')

    for ii in range(batch_size):
        x_np[ii, :sizes[ii]] = samples[ii]

    if batch_first is False:
        x_np = np.transpose(x_np, [1, 0])

    x = Variable(torch.LongTensor(x_np).contiguous(),
                 volatile=volatile)
    if cuda is True:
        x = x.cuda()

    return x

def safe_exp(value):
    """Exponentiation with catching of overflow error."""
    try:
        ans = math.exp(value)
    except OverflowError:
        ans = float("inf")
    return ans

class Statistics(object):
    """
    Train/validate loss statistics.
    """
    def __init__(self, loss=0, n_words=0, n_correct=0):
        self.loss = loss
        self.n_words = n_words
        self.n_correct = n_correct
        self.n_src_words = 0
        self.start_time = time.time()

    def update(self, stat):
        self.loss += stat.loss
        self.n_words += stat.n_words
        self.n_correct += stat.n_correct

    def ppl(self):
        return safe_exp(self.loss / self.n_words)

    def accuracy(self):
        return 100 * (self.n_correct / self.n_words)

    def elapsed_time(self):
        return time.time() - self.start_time

    def print_out(self, step, epoch, batch, n_batches, lr, batch_size, best_bleu):
        t = self.elapsed_time()

        out_info = ("Step %d, Epoch %d, %d/%d| lr: %.6f| words: %d| "
                    "acc: %.2f| ppl: %.2f| %.1f tgt tok/s| %.2f s elapsed | best bleu is: ") \
                   % (step, epoch, batch, n_batches, lr, int(batch_size), self.accuracy(), self.ppl(), \
                    self.n_words / (t + 1e-5), time.time() - self.start_time)
        # for i in range(len(best_bleu)):
        #     out_info += '%.2f, ' % best_bleu[i]
        out_info += '%.2f' % best_bleu
        print(out_info)
        sys.stdout.flush()

    def print_valid(self, step):
        t = self.elapsed_time()
        out_info = ("Valid at step %d: acc %.2f, ppl: %.2f, %.1f tgt tok/s, %.2f s elapsed") % \
              (step, self.accuracy(), self.ppl(), self.n_words / (t + 1e-5),
               time.time() - self.start_time)
        print(out_info)
        sys.stdout.flush()

class Saver(object):
    """ Saver to save and restore objects.

    Saver only accept objects which contain two method: ```state_dict``` and ```load_state_dict```
    """

    def __init__(self, save_prefix, num_max_keeping=1):

        self.save_prefix = save_prefix.rstrip(".")

        save_dir = os.path.dirname(self.save_prefix)

        if not os.path.exists(save_dir):
            os.mkdir(save_dir)

        self.save_dir = save_dir

        if os.path.exists(self.save_prefix):
            with open(self.save_prefix) as f:
                save_list = f.readlines()
            save_list = [line.strip() for line in save_list]
        else:
            save_list = []

        self.save_list = save_list
        self.num_max_keeping = num_max_keeping

    @staticmethod
    def savable(obj):

        if hasattr(obj, "state_dict") and hasattr(obj, "load_state_dict"):
            return True
        else:
            return False

    def save(self, global_step, **kwargs):

        state_dict = dict()

        for key, obj in kwargs.items():
            if self.savable(obj):
                state_dict[key] = obj.state_dict()

        saveto_path = '{0}.{1}'.format(self.save_prefix, global_step)
        torch.save(state_dict, saveto_path)

        self.save_list.append(os.path.basename(saveto_path))

        if len(self.save_list) > self.num_max_keeping:
            out_of_date_state_dict = self.save_list.pop(0)
            os.remove(os.path.join(self.save_dir, out_of_date_state_dict))

        with open(self.save_prefix, "w") as f:
            f.write("\n".join(self.save_list))

    def load_latest(self, **kwargs):

        if len(self.save_list) == 0:
            return

        latest_path = os.path.join(self.save_dir, self.save_list[-1])

        state_dict = torch.load(latest_path)

        for name, obj in kwargs.items():
            if self.savable(obj):

                if name not in state_dict:
                    print("Warning: {0} has no content saved!".format(name))
                else:
                    print("Loading {0}".format(name))
                    obj.load_state_dict(state_dict[name])


# this file is to implement a node-based Binary Search Tree with a tombstone in each node
import sys

class Node():
    def __init__(self, value, left=None, right=None):
        self._value = value
        self._left = left
        self._right = right
        self._tombstone = False

    def getValue(self):
        return self._value

    def setValue(self, data):
        self._value = data

    def getLeft(self):
        return self._left

    def setLeft(self, Node):
        self._left = Node

    def getRight(self):
        return self._right

    def setRight(self, Node):
        # return self._right
        self._right = Node

    def getTombstone(self):
        return self._tombstone

    def setTomestone(self, boo):
        self._tombstone = boo

    def __str__(self):
        #print(str(self.data)+str(self.left)+str(self.right))
        return "{0:<10}{1:<10}{2:<10}".format(
            (str(self._left.getValue()) if self._left else "None"),
            str(self._value) + ("(T)" if self._tombstone else ""),
            (str(self._right.getValue()) if self._right else "None"))

class BST():
    def __init__(self):
        self._root = None

    def isEmpty(self):
        return not self._root

    def insert(self, data):
        if not self._root:
            self._root = Node(data)
            return
        current = self._root
        while True:
            if current.getTombstone() and (
                    self.maxInSubTree(current.getLeft()) == None
                    or self.maxInSubTree(current.getLeft()) < data) and (
                        self.minInSubTree(current.getRight())
                        or self.minInSubTree(current.getRight()) >= data):
                current.setValue(data)
                # current.tombstone = False
                current.setTomestone(False)
                break
            elif data < current.getValue():
                if not current.getLeft():
                    current.setLeft(Node(data))
                    return
                else:
                    current = current.getLeft()
            else:
                if not current.getRight():
                    current.setRight(Node(data))
                    return
                else:
                    current = current.getRight()

    def findTarget(self, data):
        if not self._root:
            return None
        current = self._root
        while True:
            if data == current.getValue() and not current.getTombstone():
                # current._tombstone = True
                return current
            elif data < current.getValue():
                if not current.getLeft():
                    return None
                else:
                    current = current.getLeft()
            else:
                if not current.getRight():
                    return None
                else:
                    current = current.getRight()

    def exists(self, data):
        return self.findTarget(data) != None

    def delete(self, data):
        target = self.findTarget(data)
        if target:
            # target._tombstone = True
            target.setTomestone(True)
            return True
        return False

    def minInSubTree(self, node):
        if not node:
            return None
        if node.getTombstone():
            # res is a very large value, 2**63, idealy largest signed integer value
            # without being converted to a string
            res = sys.maxsize
        else:
            res = node.getValue()
        # this part should add in extra check for the tombstone
        leftMin = self.minInSubTree(node.getLeft())
        rightMin = self.minInSubTree(node.getRight())
        # instead of not leftMin, but simply leftMin
        if leftMin:
            res = min(res, leftMin)
        if rightMin:
            res = min(res, rightMin)
        return res

    def maxInSubTree(self, node):
        if not node:
            return None
        if node.getTombstone():
            # res is assigned the ideal smallest value
            res = -sys.maxsize-1
        else:
            res = node.getValue()
        # print(node)
        # print(res)
        # this part should add in extra check for the tombstone
        leftMax = self.maxInSubTree(node.getLeft())
        rightMax = self.maxInSubTree(node.getRight())
        # print(leftMax)
        if leftMax:
            res = max(res, leftMax)
        # print(rightMax)
        if rightMax:
            res = max(res, rightMax)
        return res

    def print(self):
        # traverse from top to its right subtree then left for every node
        if self.isEmpty():
            print("Empty")
            return
        stack = [self._root]
        print("{0:<10}{1:<10}{2:<10}".format("Node.left", "Node.data",
                                             "Node.right"))
        while len(stack) > 0:
            current = stack.pop()
            print(current)
            # print(current.getLeft())
            if current.getLeft():
                stack.append(current.getLeft())
            # print(current.getRight())
            if current.getRight():
                stack.append(current.getRight())
            # print(stack)

# a = BST()
# a.insert(5)
# a.insert(2)
# a.insert(7)
# a.print()
# a.insert(5.1)
# a.insert(8)
# if a.exists(2):
#     a.print()
#     a.delete(5)
#     a.print()
# if a.exists(10):
#     print("hey dude you got problem")
# a.insert(5.5)
# a.print()

# b = BST()
# b.insert(5)
# b.insert(2)
# b.insert(4.9)
# b.insert(7)
# if b.exists(5):
#     b.delete(5)
#     b.print()
# b.insert(4.8)
# b.print()

# c = BST()
# c.insert(1)
# c.insert(5)
# c.insert(2)
# c.insert(7)
# c.print()
# c.insert(5.1)
# c.insert(8)
# if c.exists(2):
#     c.print()
#     c.delete(5)
#     c.print()
# if c.exists(10):
#     print("hey dude you got problem")
# c.insert(5.5)
# c.print()

# d = BST()
# d.insert(1)
# d.insert(5)
# d.insert(2)
# d.insert(4.9)
# d.insert(7)
# if d.exists(5):
#     d.delete(5)
#     d.print()
# d.insert(4.8)
# d.print()

# e = BST()
# e.insert(1)
# e.insert(5)
# e.insert(2)
# e.insert(4.9)
# e.insert(7)
# if e.exists(5):
#     e.delete(5)
#     e.print()
# if e.exists(4.9):
#     e.delete(4.9)
#     e.print()
# e.insert(4.8)
# e.print()


#!/usr/bin/env python
#-*- coding: utf8 -*-
__author__ = 'mahui'
import random
import string

class CreatPaxID():
    """
    功能：生成一个身份证号
    """
    def transform_sex(self, sex):
        if sex == 'F': return random.choice(['2', '4', '6', '8', '0'])
        elif sex == 'M': return random.choice(['1', '3', '5', '7', '9'])
        else: return '5'

    def calculate_last(self, start, birthday, code, No17):
        foidlist = []
        for i in list(start): foidlist.append(string.atoi(i))
        for i in list(birthday): foidlist.append(string.atoi(i))
        for i in list(code): foidlist.append(string.atoi(i))
        foidlist.append(string.atoi(No17))
        numlist = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
        sum = 0
        for i in range(0, 17):
            sum = sum + foidlist[i] * numlist[i]
        finallist = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']
        return finallist[sum % 11]

    def create_paxs_id(self, start,birthday, sex):
        No17 = self.transform_sex(sex)
        No18 = self.calculate_last(start, birthday, '05', No17)
        foid = start + birthday + '05' + No17 + No18
        return foid

# id=CreatPaxID().create_foid("130705",'19861027','F','05')
# # print id


distance = 4
bus_speed = 25
time_at_stops = 2*10
bus_time = ((60/25)*4) + time_at_stops
print("time on bus: {}".format(round(bus_time,2)))
jogging_time = ((60/7)*2)+((60/15)*2)
print("Time to jog: {}".format(round(jogging_time,2)))
if jogging_time > bus_time:
    print("It is quicker to get the bus")
else:
    print("It is quicker to run")


# -*- coding:utf-8 -*-

from theano import tensor

import thdl.model
from thdl.model.layers import Layer

class ASLayer(Layer):
    def __init__(self, embedding_layer=None, q1_conv_layer=None, q2_conv_layer=None):
        self.embedding_layer = embedding_layer
        self.q1_dimshufle = thdl.model.layers.Dimshuffle((0, 'x', 1, 2))
        self.q2_dimshufle = thdl.model.layers.Dimshuffle((0, 'x', 1, 2))
        self.q1_conv_layer = q1_conv_layer
        self.q2_conv_layer = q2_conv_layer

    def forward(self, inputs, **kwargs):
        q1_embed = self.embedding_layer.forward(inputs[0])
        q1_embed_shuffle = self.q1_dimshufle.forward(q1_embed)
        q1_conv = self.q1_conv_layer.forward(q1_embed_shuffle)

        q2_embed = self.embedding_layer.forward(inputs[1])
        q2_embed_shuffle = self.q2_dimshufle.forward(q2_embed)
        q2_conv = self.q1_conv_layer.forward(q2_embed_shuffle)

        return tensor.concatenate([q1_conv, q2_conv], axis=1)

    def to_json(self):
        config = {
            'embedding_layer': self.embedding_layer.to_json(),
            "q1_conv_layer": self.q1_conv_layer.to_json(),
            "q2_conv_layer": self.q2_conv_layer.to_json(),
        }
        return config

    @property
    def params(self):
        return self.embedding_layer.params + self.q1_conv_layer.params + self.q2_conv_layer.params

    @property
    def regularizers(self):
        return self.embedding_layer.regularizers + self.q1_conv_layer.regularizers + self.q2_conv_layer.regularizers

    @property
    def updates(self):
        ups = super(ASLayer, self).updates
        ups.update(self.q1_conv_layer.updates)
        ups.update(self.q2_conv_layer.updates)
        return ups


from rest_framework import serializers

from .models import Invitation

class InvitationSerializer(serializers.Serializer):
    first_name = serializers.CharField(required=True)
    last_name = serializers.CharField(required=True)
    email = serializers.EmailField(required=True)
    has_accepted = serializers.BooleanField(read_only=True)

    class Meta:
        model = Invitation
        fields = ('first_name', 'last_name', 'email', 'has_accepted')

    def create(self, validated_data):
        instance = Invitation(**validated_data)
        instance.save()

        return instance


from django.template import Context, loader
from django.http import HttpResponse
from django.db import models
from modClass import tableGenerator
from django.core.context_processors import csrf
from django.shortcuts import render_to_response

import find2, settings, listDir, os, uploadFile
import probadb
def index(request):
	ht = HttpResponse()
	ht.write('Click here for app - DIR
')
	ht.write('Form
')
	ht.write('Upload files')
	return ht

def fin(request,path,fn):
	root = settings.Velly_Root
	res = find2.findReal(root+path,fn)
	ht = HttpResponse()
	for el in res:
		if el != "\n":
			ht.write(el)
		else: ht.write("
")
	ht.write("abv.bg")
	ht.flush()
	return ht

def Dir(request, path):
	root = settings.Velly_Root
	p = os.path.join(root,path)
	res = listDir.execute(p, settings.temps[0], settings.temps[1])
	c = Context({
        	'STATIC_URL': settings.STATIC_URL
    	})
	f = open(settings.TEMPLATE_DIRS+"ind.html", "w")
	f.write(res)
	f.flush()
	f.close()
	t = loader.get_template(settings.TEMPLATE_DIRS+"ind.html")
	return HttpResponse(t.render(c))
def textfiles(request, path):
	root = settings.Velly_Root
	p = root+path
	try:
		f = open(p,"r")
	except IOError:
		return HttpResponse("Access denied")
	res = '<INPUT TYPE="button" VALUE="Back" onClick="history.go(-1);">

'
	l = f.readlines()
	f.close()
	for el in l:
		el = el.replace("	", "      ")
		el = el.replace("<", "<")
		el = el.replace(">",	">")
		res += el.replace(" ", " ")+"
"
	return HttpResponse(res)

def proba(request):
	 return HttpResponse(probadb.delete())

def form(request):
	try:
	     f = open(settings.STATICFILES_DIRS[0]+'/index.html','r')
	     f1 = open(settings.temps[1],'r')
	     t = f1.read()
	     res = f.read()
	     res += '
DIR'
	     f.close()
	     f1.close()
	     return HttpResponse(res.replace("#$$$list$$$#",tableGenerator.generate('Person')))
	except IOError:
		 return HttpResponse("Form template does not exist
"+settings.STATICFILES_DIRS[0]+'/index.html')

def Error(request):
	return HttpResponse('<META HTTP-EQUIV="REFRESH" CONTENT="1;URL=/">Error 404')

def upload(request):
	try:
		res = listDir.execute(settings.UPLOAD_PATH,settings.temps[3],settings.temps[1])
		f = open(settings.TEMPLATE_DIRS+"/t.html", 'w')
		f.write(res)
		f.close()
		return render_to_response(settings.TEMPLATE_DIRS+"/t.html", Context(csrf(request)))
	except IOError:
		return "Cannot open template upload.html"


from distutils.command.install import install

from .models import *
from rest_framework import serializers

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('username', 'email', 'groups')

class GroupSerializers(serializers.ModelSerializer):
    class Meta:
        model = Group
        fields = ('name',)

class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = ('name',)

class InstrumentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Instrument
        fields = ('id', 'name', 'level', 'associated_concepts', 'difficulty', 'time', 'winner_selection',
                  'category', 'purpose_teaching', 'purpose_reinforce', 'purpose_check', 'purpose_social', 'description',
                  'groups', 'attachments', 'public', 'creation_date', 'update_date')

    def to_representation(self, instance):
        response = super().to_representation(instance)
        response['owner'] = instance.owner.get_full_name()
        response['category'] = Category.objects.get(pk=response['category']).name
        response['Objetivos'] = GoalSerializer(
            Component.objects.filter(instrument=instance, component_type='Objetivos'),
            many=True).data
        response['Reglas'] = RuleSerializer(
            Component.objects.filter(instrument=instance, component_type='Reglas'),
            many=True).data
        response['Roles'] = RoleSerializer(
            Component.objects.filter(instrument=instance, component_type='Roles'),
            many=True).data
        response['Pasos'] = StepSerializer(
            Component.objects.filter(instrument=instance, component_type='Pasos'),
            many=True).data
        response['Materiales'] = MaterialSerializer(
            Component.objects.filter(instrument=instance, component_type='Materiales'),
            many=True).data
        return response

class GoalSerializer(serializers.ModelSerializer):
    class Meta:
        model = Component
        fields = ('id',)

    def to_representation(self, instance):
        response = super().to_representation(instance)
        response['Oname'] = instance.description
        return response

class RuleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Component
        fields = ('id',)

    def to_representation(self, instance):
        response = super().to_representation(instance)
        response['Rname'] = instance.description
        return response

class RoleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Component
        fields = ('id',)

    def to_representation(self, instance):
        response = super().to_representation(instance)
        response['Roname'] = instance.description
        return response

class StepSerializer(serializers.ModelSerializer):
    class Meta:
        model = Component
        fields = ('id',)

    def to_representation(self, instance):
        response = super().to_representation(instance)
        response['Sname'] = instance.description
        return response

class MaterialSerializer(serializers.ModelSerializer):
    class Meta:
        model = Component
        fields = ('id',)

    def to_representation(self, instance):
        response = super().to_representation(instance)
        response['Maname'] = instance.description
        return response

class EvidenceSerializer(serializers.ModelSerializer):
    class Meta:
        model = Evidence
        fields = ('id', 'principle',)

    def to_representation(self, instance):
        response = super().to_representation(instance)
        principle = Principle.objects.get(pk=response['principle'])
        response['principle'] = PrincipleSerializer(principle).data
        return response

class ComponentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Component
        fields = ('description', 'component_type')

class EvidencePrincipleSerializer(serializers.ModelSerializer):
    component = ComponentSerializer()

    class Meta:
        model = Evidence
        fields = ('id', 'component')

class PrincipleSerializer(serializers.ModelSerializer):
    evidences = EvidencePrincipleSerializer(many=True)

    class Meta:
        model = Principle
        fields = ('id', 'principle', 'grade', 'weight', 'evidences')


# -*- coding: utf-8  -*-
"""Unit tests for database.py."""

import unittest

import mock

import database

class TestReData(unittest.TestCase):

    def test_reData_event_line(self):
        input_data = 'wl["monuments"][2010] = {'
        result = database.reData(input_data, 2014)
        expected = {
            u'country': None,
            u'year': '2010',
            u'end': None,
            u'event': 'monuments',
            u'start': None
        }
        self.assertEqual(result, expected)

    def test_reData_event_line_public_art(self):
        input_data = 'wl["public_art"][2012] = {'
        result = database.reData(input_data, 2014)
        expected = {
            u'country': None,
            u'year': '2012',
            u'end': None,
            u'event': 'public_art',
            u'start': None
        }
        self.assertEqual(result, expected)

    def test_reData_country_line(self):
        input_data = '''
    ["az"] = {["start"] = 20170430200000, ["end"] = 20170531195959},
    '''
        result = database.reData(input_data, 2017)
        expected = {
            u'country': 'az',
            u'year': None,
            u'end': '20170531195959',
            u'event': None,
            u'start': '20170430200000'
        }
        self.assertEqual(result, expected)

class TestRePrefix(unittest.TestCase):

    def test_re_prefix_match_ascii_line(self):
        self.assertIsNotNone(database.re_prefix(u'    ["az"] = "Azerbaijan",'))

    def test_re_prefix_match_ascii_line_with_space(self):
        self.assertIsNotNone(database.re_prefix(u'    ["gq"] = "Equatorial Guinea",'))

    def test_re_prefix_match_ascii_line_with_dash(self):
        self.assertIsNotNone(database.re_prefix(u'    ["gw"] = "Guinea-Bissau",'))

    def test_re_prefix_match_ascii_line_with_accents(self):
        self.assertIsNotNone(database.re_prefix(u'    ["re"] = "Réunion",'))

    def test_re_prefix_match_ascii_line_with_apostrophe(self):
        self.assertIsNotNone(database.re_prefix(u'    ["ci"] = "Côte d\'Ivoire",'))

class TestGetDataMixin(unittest.TestCase):

    def setUp(self):
        patcher = mock.patch('database.get_data_for_category', autospec=True)
        self.mock_get_data_for_category = patcher.start()
        self.mock_get_data_for_category.return_value = (
            (20140523121626, False, u'Bob', 20130523235032),
            (20140523121626, False, u'Alice', 20140528235032),
            (20140529121626, False, u'Alice', 20140528235032),
            (20140530121626, False, u'Alice', 20140528235032),
        )
        self.addCleanup(patcher.stop)

        self.expected_timestamp_data = {
            '20140523': {
                'images': 2,
                'joiners': 2,
                'newbie_joiners': 1
            },
            '20140529': {
                'images': 1,
                'joiners': 0,
                'newbie_joiners': 0
            },
            '20140530': {
                'images': 1,
                'joiners': 0,
                'newbie_joiners': 0
            }
        }

        self.images_count = 4
        self.usercount = 2
        self.userreg = 1
        self.usage = 0

        self.user_data = {
            u'Alice': {
                'count': 3,
                'reg': 20140528235032,
                'usage': 0
            },
            u'Bob': {
                'count': 1,
                'reg': 20130523235032,
                'usage': 0
            }
        }

class TestGetData(TestGetDataMixin):

    def test_GetData(self):
        competition_config = {
            u'Brazil': {'start': 20140501030000, 'end': 20140601025959},
        }

        result = database.getData("Dumplings2014", competition_config)

        expected = {
            u'Brazil': {
                'count': self.images_count,
                'usercount': self.usercount,
                'start': 20140501030000,
                'userreg': self.userreg,
                'data': self.expected_timestamp_data,
                'users': self.user_data,
                'usage': self.usage,
                'category': u'Images_from_Wiki_Loves_Dumplings_2014_in_Brazil',
                'end': 20140601025959
            }
        }
        self.assertEquals(result, expected)

class TestGetCountryData(TestGetDataMixin):

    def test_get_country_data(self):
        category = u'Images_from_Wiki_Loves_Dumplings_2014_in_Brazil'
        result = database.get_country_data(category, 20140501030000, 20140601025959)

        expected = {
            'count': self.images_count,
            'usercount': self.usercount,
            'start': 20140501030000,
            'userreg': self.userreg,
            'data': self.expected_timestamp_data,
            'users': self.user_data,
            'usage': self.usage,
            'category': category,
            'end': 20140601025959
        }
        self.mock_get_data_for_category.assert_called_once_with(category)
        self.assertEquals(result, expected)

class TestUpdateEventData(TestGetDataMixin):

    def setUp(self):
        super(self.__class__, self).setUp()
        patcher = mock.patch('database.write_database_as_json', autospec=True)
        self.mock_write_database_as_json = patcher.start()
        self.addCleanup(patcher.stop)

    def test_udpate_event_data(self):
        self.maxDiff = None
        event_name = u'dumplings2014'
        event_configuration = {
            u'Azerbaijan': {
                'start': 20140430200000,
                'end': 20140531195959,
            },
            u'Guinea-Bissau': {
                'start': 20140430200000,
                'end': 20140531195959,
            },
        }
        db = {}
        result = database.update_event_data(event_name, event_configuration, db)

        expected_base = {
            'count': self.images_count,
            'usercount': self.usercount,
            'start': 20140430200000,
            'userreg': self.userreg,
            'data': self.expected_timestamp_data,
            'users': self.user_data,
            'usage': self.usage,
            'end': 20140531195959
        }

        expected_az = expected_base.copy()
        expected_az.update({
            'category': u'Images_from_Wiki_Loves_Dumplings_2014_in_Azerbaijan',
        })
        expected_gb = expected_base.copy()
        expected_gb.update({
            'category': u'Images_from_Wiki_Loves_Dumplings_2014_in_Guinea-Bissau',
        })

        expected = {
            u'dumplings2014': {
                u'Azerbaijan': expected_az,
                u'Guinea-Bissau': expected_gb,
            }
        }
        self.assertEquals(result, expected)
        self.mock_write_database_as_json.assert_called_once_with(expected)

class TestParseConfig(unittest.TestCase):

    def test_parse_config_empty(self):
        config = ''
        result = database.parse_config(config)
        expected = {}
        self.assertEquals(result, expected)

    def test_parse_config(self):
        config = '''
wl["prefixes"] = {
    ["az"] = "Azerbaijan",
    ["gw"] = "Guinea-Bissau"
}

wl["monuments"][2017] = {
    ["az"] = {["start"] = 20170430200000, ["end"] = 20170531195959},
    ["gw"] = {["start"] = 20170430200000, ["end"] = 20170531195959},
}

wl["monuments"][2018] = {
    ["az"] = {["start"] = 20180430200000, ["end"] = 20180531195959},
    ["gw"] = {["start"] = 20180430200000, ["end"] = 20180531195959},
}

'''
        result = database.parse_config(config)
        expected = {
            u'monuments2017': {
                u'Azerbaijan': {
                    'start': 20170430200000,
                    'end': 20170531195959,
                },
                u'Guinea-Bissau': {
                    'start': 20170430200000,
                    'end': 20170531195959,
                },
            },
            u'monuments2018': {
                u'Azerbaijan': {
                    'start': 20180430200000,
                    'end': 20180531195959,
                },
                u'Guinea-Bissau': {
                    'start': 20180430200000,
                    'end': 20180531195959,
                },
            }
        }
        self.assertEquals(result, expected)

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


"""
@author: krissrex
"""

def caesar(instring, key=1, encrypt=True,):
  '''
  Caesar encryption.
  Arguments:
    instring  Message         (string)
    key       Alphabet offset (integer)
    encrypt
      True  -> encrypt        (boolean)
      False -> decrypt        (boolean)
  '''
  outstr = ""
  key = key if encrypt else key*-1
  for letter in instring:
    outstr += chr((((ord(letter)-32)+key)%223)+32)
  return outstr

def vigenere(instring, key, encrypt=True):
  '''
  Vigenere encryption.
  Arguments:
    instring  Message   (string)
    key       Keyword   (string)
    encrypt
      True  -> encrypt  (boolean)
      False -> decrypt  (boolean)
  '''
  keypad = ""
  outstr = ""
  codec = 1 if encrypt else -1
  for index, letter in enumerate(instring):
    keypad += key[index % len(key)]

  for index, letter in enumerate(instring):
      outstr += chr((((ord(letter)-32)+codec*(ord(keypad[index])-32))%223)+32)
  return outstr

def tabularecta():
  '''http://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher#Description'''
  tabrect = []
  for i in range(0,26):
    tabrect.append([])
    for n in range(0,26):
      tabrect[i].append(chr(((n+i)%26)+97))
  return tabrect

# TODO: Move this from shift, and rename instring to message
def xor(instring, key):
  '''
  Bitwise Exclusive OR performed on instring, with key padded with itself.
  Arguments:
    instring  Message           (string)
    key       Key to xor with   (string)
  '''
  keypad = ""
  outstr = ""
  for index, letter in enumerate(instring):
    keypad += key[index % len(key)]

  for index, letter in enumerate(instring):
    outstr += chr((((ord(letter)-32) ^ (ord(keypad[index])-32))%223)+32)
  return outstr

def alcaesar(instr, key=1, encrypt=True):
  '''
  Caesar encryption which follows the alphabet instead of the ASCII table.
  Arguments:
    instring  Message         (string)
    key       Alphabet offset (integer)
    encrypt
      True  -> encrypt        (boolean)
      False -> decrypt        (boolean)
  '''
  outstr = ""
  codec = 1 if encrypt else -1

  for letter in instr:
    temp = ord(letter)
    if letter.isalpha():
      if letter.islower():
        temp = (((temp-97)+codec*key)%26)+97
      else:
        temp = (((temp-65)+codec*key)%26)+65

    elif letter.isdigit():
      temp (((temp-48)+codec*key)%10)+48
    outstr += chr(temp)
  return outstr

def alvigenere(instring, key, encrypt=True):
  '''Vigenere encryption which follows the alphabet instead of the ASCII table.
  Arguments:
    instring  Message   (string)
    key       Keyword   (string)
    encrypt
      True  -> encrypt  (boolean)
      False -> decrypt  (boolean)
  '''
  keypad = ""
  outstr = ""
  codec = 1 if encrypt else -1
  for index, letter in enumerate(instring):
    keypad += key[index % len(key)]

  for index, letter in enumerate(instring):
    temp = ord(letter)
    if letter.isalpha():
      if letter.islower():

        temp = (((ord(letter)-97)+codec*(ord(keypad[index])-97))%26)+97
      else:
        temp = (((ord(letter)-65)+codec*(ord(keypad[index])-65))%26)+65
    elif letter.isdigit():
      temp (((ord(letter)-48)+codec*(ord(keypad[index])-48))%10)+48
    outstr += chr(temp)
  return outstr


def insert(x,ss):
    left = []
    if ss == []:
        return [x]
    else:
        while ss!=[]:
            smallest = min(ss)
            if x>smallest:
                ss.remove(smallest)
                left.append(smallest)
            else:
                left.append(x)
        return left+x

def isort0(s):
    if s != []:
        return insert(s[0],isort0(s[1:]))
    else:
        return []

print((insert(9,[6,7,8,10])))
print(isort0([10,5,6]))


import tensorflow as tf
import os
import logging
import gin

@gin.configurable
def set_devices(idx_gpu, soft_device_placement=True, num_cpu_threads=0):

    # Set jit active for XLA routines - Not functional yet
    # tf.config.optimizer.set_jit(True)

    os.unsetenv('CUDA_VISIBLE_DEVICES')  # to see the actual list, prior restrictions have to be unset
    gpus = tf.config.experimental.list_physical_devices('GPU')
    logging.info(f'Available physical devices: {gpus}.')
    if gpus:
        logging.info(f'Fetching devices: {idx_gpu}.')
        # Restrict TensorFlow to only use one specific GPU
        try:
            tf.config.experimental.set_visible_devices(gpus[int(idx_gpu)], 'GPU')
            #  set memory growth option for all GPU devices (even the ones not used). Otherwise current tf version throws a ValueError
            for idx in range(len(gpus)):
                tf.config.experimental.set_memory_growth(gpus[int(idx)], True)
        except RuntimeError as e:
            # Visible devices and memory growth must be set at program startup
            print(e)

        # set device placement
        tf.config.set_soft_device_placement(soft_device_placement)

        logging.info(f'Visible devices: {tf.config.experimental.get_visible_devices()}.')
        logging.info(f'Memory growth option: {tf.config.experimental.get_memory_growth(gpus[int(idx_gpu)])}')
        logging.info(f'Using soft device placement: {tf.config.get_soft_device_placement()}')

    # Set CPU options
    if num_cpu_threads > 0:
        tf.config.threading.set_inter_op_parallelism_threads(2)
        tf.config.threading.set_intra_op_parallelism_threads(num_cpu_threads)
    else:
        tf.config.threading.set_inter_op_parallelism_threads(2)
        tf.config.threading.set_intra_op_parallelism_threads(4)

    # set some optimizations
    tf.config.optimizer.set_experimental_options({'layout_optimizer': True,
                                                  'remapping': True,
                                                  'arithmetic_optimization': True,
                                                  'dependency_optimization': True,
                                                  'loop_optimization': True,
                                                  'function_optimization': True,
                                                  'scoped_allocator_optimization': True})
    # report CPU optimizations
    logging.info(f'Using the following optimization options: {tf.config.optimizer.get_experimental_options()}.')


'''
## License

The MIT License (MIT)

Grove Base Hat for the Raspberry Pi, used to connect grove sensors.
Copyright (C) 2020  Seeed Technology Co.,Ltd.
'''

import io
from setuptools import setup, find_packages

with open('README.md') as f:
    long_description = f.read()

requirements = ['smbus2','spidev','pyserial']

def is_pi():
    found = False
    try:
        with io.open('/proc/cpuinfo', 'r') as cpuinfo:
            for line in cpuinfo:
                if line.startswith('Hardware'):
                    _, value = line.strip().split(':', 1)
                    value = value.strip()
                    if value in ('BCM2708', 'BCM2709', 'BCM2835', 'BCM2836'):
                        found = True
    except IOError:
        pass

    return found

if is_pi():
    requirements.append('RPi.GPIO')
    requirements.append('rpi_ws281x')

setup(
    name='Seeed_grove.py',
    version='0.3',
    description='Python library for Seeedstudio Grove devices',
    long_description=long_description,
    long_description_content_type='text/markdown',
    author='JunJie Chen',
    author_email='hansen.chen@seeed.cc',
    url='https://github.com/seeed-studio/grove.py',
    packages=find_packages(include=['grove']),
    include_package_data=True,
    install_requires=requirements,
    zip_safe=False,
    license = 'MIT',
    classifiers=[
        'Development Status :: 2 - Pre-Alpha',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: MIT License',
        'Operating System :: POSIX :: Linux',
        "Programming Language :: Python :: 2",
        'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.4',
        'Programming Language :: Python :: 3.5',
    ],
    keywords=['grove','Seeed'])


import argparse
import re
import string
from datetime import datetime
import operator
import sys
import colorama
from colorama import Fore,  Back,  Style
from typing import List
from os.path import basename
import math

from computer import Computer

class ChemicalSpec:
    def __init__(self, num, name):
        self.num: int = num
        self.name: str = name

    @staticmethod
    def from_str(definition: str):
        (num_str, name) = definition.strip().split(' ')
        return ChemicalSpec(int(num_str), name)

    def __str__(self):
        return '{0} {1}'.format(self.num, self.name)

    def __repr__(self):
        return str(self)

class Reaction:
    def __init__(self, ingredients: List[ChemicalSpec], result: ChemicalSpec):
        self.ingredients = ingredients
        self.result: ChemicalSpec = result

    @staticmethod
    def from_str(definition: str):
        (ingredients, result) = definition.split(' => ')

        ingredient_list = []
        for ingredient in ingredients.split(', '):
            ingredient_list.append(ChemicalSpec.from_str(ingredient))

        return Reaction(ingredient_list, ChemicalSpec.from_str(result))

    def name(self) -> str:
        return self.result.name

    def __str__(self):
        return '{0} => {1}'.format(self.ingredients, self.result)

    def __repr__(self):
        return str(self)

class Nanofactory:
    def __init__(self, reaction_definitions: List[Reaction]):
        self.reaction_defs = {}
        self.chemical_store = {'ORE': 0}
        self.order_total = {'ORE': 0}
        for reaction in reaction_definitions:
            self.reaction_defs[reaction.name()] = reaction
            self.chemical_store[reaction.name()] = 0
            self.order_total[reaction.name()] = 0

    def consume(self, order_size: int, name: str):
        # print('consuming {0} {1}'.format(order_size, name))

        stock = self.chemical_store[name]
        if order_size <= stock:
            self.chemical_store[name] -= order_size
            return
        extra_needed = order_size - stock
        self.chemical_store[name] = 0

        if name == 'ORE':
            self.order_total[name] += extra_needed
            return

        reaction = self.reaction_defs[name]
        reaction_yield = reaction.result.num
        reactions_needed = 1
        if reaction_yield < extra_needed:
            reactions_needed = int(extra_needed / reaction_yield)
            if extra_needed % reaction_yield != 0:
                reactions_needed += 1

        # print('   {0} {1} reactions needed'.format(reactions_needed, name))
        for chem_spec in reaction.ingredients:
            self.consume(chem_spec.num * reactions_needed, chem_spec.name)
        self.chemical_store[name] += reactions_needed * reaction_yield - extra_needed

reactions = {}
multiples = {}

def main():
    colorama.init()

    inputFile = basename(__file__)[:2] + '-input.txt'
    # inputFile = basename(__file__)[:2] + '-example-1.txt'
    # inputFile = basename(__file__)[:2] + '-example-2.txt'
    # inputFile = basename(__file__)[:2] + '-example-3.txt'
    # inputFile = basename(__file__)[:2] + '-example-4.txt'
    # inputFile = basename(__file__)[:2] + '-example-5.txt'
    lines = []
    with open(inputFile,  'r') as infile:
        for line in infile:
            lines.append(line.strip())

    for line in lines:
        reaction = Reaction.from_str(line)
        print('loaded:', reaction)
        reactions[reaction.result.name] = reaction

    factory = Nanofactory(list(reactions.values()))

    print('')
    fuel_count = -1
    while factory.order_total['ORE'] < 1000000000000:
        fuel_count += 1
        if fuel_count % 1000 == 0:
            print('made {0} fuel from {1} ore'.format(
                fuel_count, format(factory.order_total['ORE'], ',d')))
        factory.consume(1, 'FUEL')
    print('')
    print('made {0} fuel from {1} ore'.format(fuel_count, factory.order_total['ORE']))

if __name__ == "__main__":
    main()


import random
from datetime import datetime, timedelta
from operator import attrgetter
from db_interface import add_room
from entities import Event, SanitizedEvent, Room, SanitizedStatus
import db_interface as db
import algorithms as algo
base = datetime(2021, 1, 10, 00, 00, 00)

room_names = ['Faner Hall', 'CS Main office', 'Linux Lab', 'Conference Room', 'Subway',
              'Grad School', 'Shryock Auditorium', 'REC center', 'Health Center', 'Campus Loop']

def gen_un(num=10):
    retVal = [70983, 67375, 38274, 15948, 39332, 46551, 89452, 65581, 91513, 56695, 93495, 14489, 33796, 22258, 35436, 28273, 15909, 49829, 91888, 41355, 12265, 25575, 13295, 94272, 75041, 79724, 94331, 49094, 97765, 76097, 27260, 79237, 56386, 41642, 76750, 19871, 80257, 18477, 84637, 46571, 44554, 84530, 48237, 71753, 77888, 33971, 60273, 54860, 29805, 20182, 50195, 69364, 69740, 66008, 36869, 90767, 76004, 17735, 70777, 92915, 87067, 63783, 49224, 86903, 81915, 56155, 35367, 50982, 90378, 96810, 49721, 29100, 34701, 53327, 35004, 51669, 85598, 38272, 80275, 59151, 50044, 27577, 69158, 33447, 63480, 44912, 57918, 46857, 77435, 76053, 15148, 16125, 54986, 31127, 38305, 65443, 29092, 75663, 98398, 48838]
    #[random.randint(10001, 99999) for i in range(num)]
    # print(retVal)
    return retVal

def gen_bmp_un(num=10):
    retVal = ['BMP32369', 'BMP85052', 'BMP26184', 'BMP95577', 'BMP75406', 'BMP50291', 'BMP87861', 'BMP16918', 'BMP72539', 'BMP80786']
    #["BMP" + str(random.randint(10001, 99999)) for i in range(num)]
    # print(retVal)
    return retVal

def gen_rid(num=10):
    retVal = ['J28929', 'P72143', 'S87978', 'L83225', 'B21970', 'S96687', 'L89485', 'D49972', 'G19247', 'S15838']
    #[chr(65 + random.randint(0, 25)) + str(random.randint(10001, 99999)) for i in range(num)]
    # print(retVal)
    return retVal

# or a function

def gen_datetime(base, max_hour_limit=10):
    # generate a datetime in format yyyy-mm-dd hh:mm:ss.000000
    base += timedelta(hours=random.randint(0, max_hour_limit),
                      minutes=random.randint(1, 30), seconds=random.randint(0, 10), microseconds=random.randint(0, 100000))
    return base

def get_entry_exit_pairs(user_id, ridList, num=100):
    events = []
    start = base
    for _ in range(num):
        room_id = ridList[random.randint(0, len(ridList)-1)]
        start = gen_datetime(start)
        if(start >= datetime.now()):
            break
        end = gen_datetime(start)
        events.append(Event(user_id, room_id, 1, start))
        events.append(Event(user_id, room_id, 0, end))
        start = end
    return events

def get_sanitized_events_for_the_day(unList, roomList, date, frequency=1):
    events = []
    random.shuffle(unList)
    random.shuffle(roomList)
    minLength = min(len(unList), len(roomList))
    for user_id, room_id in zip(unList[:minLength], roomList[:minLength]):
        baseTime = date
        for _ in range(frequency):
            start = gen_datetime(baseTime, max_hour_limit=10)
            end = gen_datetime(start, max_hour_limit=1)
            events.append(SanitizedEvent(user_id, room_id, 1, start))
            events.append(SanitizedEvent(user_id, room_id, 0, end))
            baseTime = end
    return events

def addToFile(events, fname):
    f = open("covid-contact-tracing/server/mockdata/"+fname, "w")
    for event in events:
        f.write(str(event)+"\n")

def generate_room_entries(rooms):
    rooms.sort(key=attrgetter('id'))
    addToFile(rooms, f"room-by-id.txt")
    rooms.sort(key=attrgetter('name'))
    addToFile(rooms, f"room-by-name.txt")
    rooms.sort(key=attrgetter('max_capacity'))
    addToFile(rooms, f"room-by-capacity.txt")

def generate_mock_event_files(events, title):
    events.sort(key=attrgetter('user_id'))
    addToFile(events, f"{title}-user_id.txt")
    events.sort(key=attrgetter('room_id', 'timestamp'))
    addToFile(events, f"{title}-room_id.txt")
    events.sort(key=attrgetter('timestamp'))
    addToFile(events, f"{title}-timestamp.txt")

def main():
    global base
    unList = gen_un(100)
    bmpUserList = gen_bmp_un(10)
    ridList = gen_rid(10)
    random.shuffle(room_names)
    roomList = [Room(rid, room_names[i], random.randint(2, 100))
                for i, rid in enumerate(ridList)]
    all_events, all_sanitized_events = [], []
    for un in unList:
        base = datetime(2021, 1, 10, 00, 00, 00)
        all_events += (get_entry_exit_pairs(un, ridList, 100))

    for dayCount in range((datetime.now() - base).days):
        date = datetime(2021, 1, 10, 00, 00, 00) + timedelta(days=dayCount)
        all_sanitized_events += get_sanitized_events_for_the_day(
            bmpUserList, ridList,  date, frequency=2)

    generate_room_entries(roomList)
    generate_mock_event_files(all_events, 'events')
    generate_mock_event_files(all_sanitized_events, 'sanitized-events')

    for room in roomList:
        db.add_room(room.__dict__)

    for event in sorted(all_events+all_sanitized_events, key=attrgetter('timestamp')):
        algo.add_event_algo(event)

    return all_events, all_sanitized_events

if __name__ == "__main__":
    main()


import datetime

import mock
from pytest import raises

from serde import Model, field
from serde.error import DeserializationError, SerdeError, SerializationError, ValidationError
from tests import py2_patch_str_with_basestring

class TestModel:

    def test___new__(self):
        class Example(Model):
            a = field.Int()
            b = field.Bool()

        # The field attributes should not be present on the final class.
        assert not hasattr(Example, 'a')
        assert not hasattr(Example, 'b')

        # But they should be in the _fields attribute
        assert hasattr(Example._fields, 'a')
        assert hasattr(Example._fields, 'b')

        with raises(AttributeError):
            Example._fields.c

        # When extending a model the parent field attributes should also be
        # present, but subclass fields of the same name should override them.
        class Example2(Example):
            b = field.Float()
            c = field.Float()

        assert hasattr(Example2._fields, 'a')
        assert isinstance(Example2._fields.a, field.Int)
        assert hasattr(Example2._fields, 'b')
        assert isinstance(Example2._fields.b, field.Float)
        assert hasattr(Example2._fields, 'c')
        assert isinstance(Example2._fields.c, field.Float)

        class Example3(Example2):
            pass

        assert hasattr(Example2._fields, 'a')
        assert isinstance(Example2._fields.a, field.Int)
        assert hasattr(Example2._fields, 'b')
        assert isinstance(Example2._fields.b, field.Float)
        assert hasattr(Example2._fields, 'c')
        assert isinstance(Example2._fields.c, field.Float)

        class Example4(Model):
            a = field.Int()
            b = field.Float()

            def __init__(self):
                super(Example4, self).__init__(a=5, b=50.5)

        assert hasattr(Example4._fields, 'a')
        assert isinstance(Example4._fields.a, field.Int)
        assert hasattr(Example4._fields, 'b')
        assert isinstance(Example4._fields.b, field.Float)

        example = Example4()
        assert example.a == 5
        assert example.b == 50.5

        class Example5(Example4):
            b = field.Int()
            c = field.Float()

            def __init__(self):
                super(Example4, self).__init__(a=5, b=50, c=100.5)

        assert hasattr(Example5._fields, 'a')
        assert isinstance(Example5._fields.a, field.Int)
        assert hasattr(Example5._fields, 'b')
        assert isinstance(Example5._fields.b, field.Int)
        assert hasattr(Example5._fields, 'c')
        assert isinstance(Example5._fields.c, field.Float)

        example = Example5()
        assert example.a == 5
        assert example.b == 50
        assert example.c == 100.5

    def test___init__(self):
        # A simple Model with no fields.
        class Example(Model):
            pass

        example = Example()
        assert example.__dict__ == {}

        # Instantiating this with parameters should fail.
        with raises(SerdeError):
            Example(None)

        with raises(SerdeError):
            Example(a=None)

        # A simple Model with one required field and one optional
        class Example(Model):
            a = field.Int(required=False)
            b = field.Bool()

        # Passing in the same argument twice.
        with raises(SerdeError):
            Example(5, a=6)

        # Just passing in the required
        example = Example(b=True)
        assert example.__dict__ == {'b': True, 'a': None}

        # Passing in optional as well
        example = Example(a=5, b=False)
        assert example.__dict__ == {'b': False, 'a': 5}

        # Not passing in any args should fail.
        with raises(ValidationError):
            Example()

        # Passing in arguments of the wrong type should fail validation
        with raises(ValidationError):
            Example(b='test')

        with raises(ValidationError):
            Example(b=None)

        with raises(ValidationError):
            Example(a=5.5, b=True)

        # A more complex Model
        class SubExample(Model):
            x = field.Int()

        def assert_value_between_0_and_20(value):
            assert 0 <= value < 20

        class Example(Model):
            a = field.Int(validators=[assert_value_between_0_and_20])
            b = field.Bool(required=False, default=False)
            c = field.Nested(SubExample, required=False)
            d = field.Nested(SubExample)

        # Just passing in required
        example = Example(a=5, d=SubExample(x=10))
        assert example.__dict__ == {'a': 5, 'b': False, 'c': None, 'd': SubExample(x=10)}

        # Passing in all
        example = Example(a=5, c=SubExample(x=50), b=True, d=SubExample(x=10))
        assert example.__dict__ == {'a': 5, 'b': True, 'c': SubExample(x=50), 'd': SubExample(x=10)}

        # Not passing in all the required kwargs should fail.
        with raises(ValidationError):
            Example(a=5)

        # Passing in arguments of the wrong type should fail validation
        with raises(ValidationError):
            Example(a='test', d=SubExample(x=10))

        with raises(ValidationError):
            Example(a=5, d=Example(a=5, d=SubExample(x=10)))

        with raises(ValidationError):
            Example(a=5, d=SubExample(x=10), b=5)

        with raises(ValidationError):
            Example(a=5, d=SubExample(x=10), c=Example(a=5, d=SubExample(x=10)))

        with raises(ValidationError):
            Example(a=30, d=SubExample(x=10))

    def test___eq__(self):
        class Example(Model):
            a = field.Int()
            b = field.Bool(required=False)

        assert Example(a=5) != Example(a=6)
        assert Example(a=5) != Example(a=6, b=True)
        assert Example(a=5) == Example(a=5)

    def test___hash__(self):
        # A more complex Model with a sub Model
        class SubExample(Model):
            x = field.Float()

        class Example(Model):
            a = field.List(field.Int)
            b = field.Nested(SubExample)

        assert (hash(Example(a=[5], b=SubExample(x=10.5)))
                == hash(Example(a=[5], b=SubExample(x=10.5))))
        assert (hash(Example(a=[5], b=SubExample(x=10.5)))
                != hash(Example(a=[5], b=SubExample(x=10.0))))

    def test_to_dict(self):
        class Example(Model):
            a = field.Int()
            b = field.Bool(required=False)

        example = Example(a=5)
        assert example.to_dict() == {'a': 5}

        example = Example(a=5, b=False)
        assert example.to_dict() == {'a': 5, 'b': False}

        # A more complex Model with a sub Model
        class SubExample(Model):
            x = field.Float(serializers=[lambda x: x])

        class Example(Model):
            a = field.Int(rename='d')
            b = field.Nested(SubExample)
            c = field.Bool(required=False)

        example = Example(a=5, b=SubExample(x=10.5))
        assert example.a == 5
        assert example.to_dict() == {'d': 5, 'b': {'x': 10.5}}

        example = Example(a=5, b=SubExample(x=10.5), c=True)
        assert example.to_dict() == {'d': 5, 'b': {'x': 10.5}, 'c': True}

        class Example(Model):
            a = field.List(field.Int)

        example = Example(a=[1, 2, 3, 4])

        # set a bad value
        example.a = 5

        with raises(SerializationError):
            example.to_dict()

        # Make the field always fail serialization
        def serialize(value):
            raise SerializationError('unable to serialize {}'.format(value))

        example = Example(a=[1, 2, 3, 4])
        Example._fields.a.serialize = serialize

        with raises(SerializationError):
            example.to_dict()

    def test_from_dict(self):
        # A simple Model.
        class Example(Model):
            a = field.Int()
            b = field.Bool(required=False)

        example = Example(a=5)
        assert Example.from_dict({'a': 5}) == example

        example = Example(a=5, b=False)
        assert Example.from_dict({'a': 5, 'b': False}) == example

        with raises(DeserializationError):
            Example.from_dict({'a': 5, 'b': False, 'c': 'extra'})

        with raises(DeserializationError):
            Example.from_dict({'b': False})

        # A more complex Model with a sub Model
        class SubExample(Model):
            x = field.Float(deserializers=[lambda x: x])

        class Example(Model):
            a = field.Int()
            b = field.Nested(SubExample)
            c = field.Bool(required=False)

        example = Example(a=5, b=SubExample(x=10.5))
        assert Example.from_dict({'a': 5, 'b': {'x': 10.5}}) == example

        example = Example(a=5, b=SubExample(x=10.5), c=True)
        assert Example.from_dict({'a': 5, 'b': {'x': 10.5}, 'c': True}) == example

        example = Example.from_dict({'a': 5, 'b': {'x': 10.5}})
        assert isinstance(example.b, SubExample)

        with raises(DeserializationError):
            Example.from_dict({'a': 5, 'b': {'x': 10.5}, 'z': True})

        example = Example.from_dict({'a': 5, 'b': {'x': 10.5}, 'z': True}, strict=False)
        assert not hasattr(example, 'z')

        # Make the field always fail serialization
        def deserialize(value):
            raise DeserializationError('unable to deserialize {}'.format(value))

        Example._fields.a.deserialize = deserialize

        with raises(DeserializationError):
            Example.from_dict({'a': 5, 'b': {'x': 10.5}})

        # Generic exceptions should also be mapped to a Deserialization error
        def deserialize(value):
            raise Exception('unable to deserialize {}'.format(value))

        Example._fields.a.deserialize = deserialize

        with raises(DeserializationError):
            Example.from_dict({'a': 5, 'b': {'x': 10.5}})

    @py2_patch_str_with_basestring
    def test_from_json(self):
        class Example(Model):
            a = field.Int()
            b = field.Str()

        assert Example.from_json('{"a": 50, "b": "test"}') == Example(a=50, b='test')

    def test_to_json(self):
        class Example(Model):
            a = field.Int()
            b = field.Str()

        example = Example(a=50, b='test')
        assert example.to_json(sort_keys=True) == '{"a": 50, "b": "test"}'

    @py2_patch_str_with_basestring
    def test_from_toml(self):
        class Example(Model):
            a = field.Int()
            b = field.Str()

        with mock.patch('serde.model.toml', None):
            with raises(SerdeError):
                Example.from_toml('a = 50\nb = "test"\n')

        assert Example.from_toml('a = 50\nb = "test"\n') == Example(a=50, b='test')

    def test_to_toml(self):
        class Example(Model):
            a = field.Int()
            b = field.Str()

        example = Example(a=50, b='test')
        assert example.to_toml() == 'a = 50\nb = "test"\n'

    def test_from_yaml(self):
        class Example(Model):
            a = field.Int()
            b = field.Str()

        with mock.patch('serde.model.yaml', None):
            with raises(SerdeError):
                Example.from_yaml('a: 50\nb: test\n')

        assert Example.from_yaml('a: 50\nb: test\n') == Example(a=50, b='test')

    def test_to_yaml(self):
        class Example(Model):
            a = field.Int()
            b = field.Str()

        example = Example(a=50, b='test')
        assert example.to_yaml(dict=dict, default_flow_style=False) == 'a: 50\nb: test\n'

    def test_serialization_error_context(self):
        class Example(Model):
            a = field.DateTime()

        try:
            example = Example(a=datetime.datetime.utcnow())
            example.a = 'not a datetime'

        except SerializationError as e:
            assert e.model is Example
            assert e.field is Example._fields.a
            assert e.value == 'not a datetime'

    def test_deserialization_error_context(self):
        class Example(Model):
            a = field.DateTime()

        try:
            Example.from_dict({'a': 'not a datetime'})
        except DeserializationError as e:
            assert e.model is Example
            assert e.field is Example._fields.a
            assert e.value == 'not a datetime'

    def test_validation_error_context(self):
        class Example(Model):
            a = field.Int()

        try:
            Example('not an field.Int')
        except ValidationError as e:
            assert e.model is Example
            assert e.field is Example._fields.a
            assert e.value == 'not an field.Int'