import pandas as pd
import numpy as np
import statsmodels.api as sm
import matplotlib
import matplotlib.pyplot as plt

def TAR(y, threshold, lags, save_path=None):
    """
    Objective: Using OLS, estimate a threshold autoregressive model.
    :param y: Dataframe with pandas DatetimeIndex.
    :param threshold: (float) cutoff level separating the two regimes.
    :param lags: (int) number of lags to include in AR model.
    :param save_path: (str) of location to save images or None to turn off saving.
    :return:
            -results: list object containing OLS results for the regions below and above, respectively.
            -residuals: Series object containing timeseries of residuals.
            predict: Series object containing timeseries of predicted values.
    """
    y = y.dropna()
    # X = pd.DataFrame(np.zeros((len(y), lags)))
    X = pd.DataFrame()
    # print(X)
    # print('a')
    for i in range(1, lags+1):
        lag = y.shift(i)
        # print(lag)
        # X.iloc[:, i-1] = lag
        X = pd.concat([X, lag], axis=1)
        # print(X)
    # print(X)
    X = X.dropna()
    # print(X)
    X = sm.add_constant(X)
    # print(X)

    # Regression for values below the threshold
    less = X[X.iloc[:, 1] < threshold]
    # print('b')
    out1 = sm.OLS(y.loc[less.index], less).fit()
    # print('c')
    print('Regression results for values BELOW threshold:')
    print(out1.summary())

    # Regression for values above the threshold
    greater = X[X.iloc[:, 1] >= threshold]
    out2 = sm.OLS(y.loc[greater.index], greater).fit()
    print('Regression results for values ABOVE threshold:')
    print(out2.summary())

    # Residuals
    resid1 = out1.resid
    resid2 = out2.resid
    residuals = pd.concat([resid1, resid2], axis=0)

    # Results
    results = [out1, out2]

    # ACF plot of residuals
    fig1, ax1 = plt.subplots(figsize=(36, 10))
    sm.graphics.tsa.plot_acf(residuals, ax=ax1)
    ax1.set_title('ACF of Residuals')
    ax1.set_xlabel('Lags')
    ax1.set_ylabel('Autocorrelation')
    fig1.show()

    if save_path is not None:
        fig1.savefig(save_path + 'residual_acf.png')

    # Predicted values
    predict1 = out1.predict(less)
    predict2 = out2.predict(greater)
    predict = pd.concat([predict1, predict2], axis=0).sort_index()

    # create predicted values plot
    fig2, ax2 = plt.subplots(figsize=(36, 10))
    ax2.plot(y, label='Actual', linewidth=2)
    ax2.plot(predict, label='Predicted', linestyle='--', linewidth=2)
    ax2.set_title('Actual vs Predicted Values')
    ax2.set_xlabel('Time')
    ax2.set_ylabel('Value')
    ax2.legend()
    fig2.show()

    if save_path is not None:
        fig2.savefig(save_path + 'predicted_values.png')

    return results, residuals, predict


from data import window, frameRow2, frameRow3, frameRow4

from PeriodiekSysteem import Nr, Symb, Naam, MolM, Dicht, SP, KP, zoek, frmPeriodiek
frmPeriodiek.pack(pady=10)

from MolaireMassa import frameMolM, entFormule, berekenMolM
frameMolM.grid(row=0, column=1, padx=5, sticky='n')

from MolaireMassa import frmCommas
frmCommas.grid(row=0, column=2, sticky='n',padx=5)

from WortelHerleiden import frmWortel, entGetal, entGetal2, wortel
frmWortel.grid(row=0, column=0, sticky='n', padx=5)

from ReactieVergelijking import frmReacTot, entReac, CalcReac
frmReacTot.grid(row=0, column=0, padx=5)

from TwentyFourGame import frm24Game, TwfGameEnt1, TwfGameEnt2, TwfGameEnt3, TwfGameEnt4, twfGame
frm24Game.grid(row=0, column=1, padx=5)

from GtaVoltHack import VLFrame, VLCinp1, VLCinp2, VLCinp3, VLFinp1, VLFinp2, VLFinp3, VLtargEnt, VLhack
VLFrame.grid(row=0, column=2, padx=5)

from FileDateChanger import FTFrame
FTFrame.grid(row=0, column=3, padx=5)

from nCrnPr import frmCP, entCPn, entCPr, CPber
frmCP.grid(row=0, column=0, padx=5)

def enter(key):
    if Nr.get() != '' or Symb.get() != '' or Naam.get() != '' or MolM.get() != '' or Dicht.get() != '' or SP.get() != '' or KP.get() != '':
        zoek()
    if entFormule.get() != '':
        berekenMolM(0, 0)
    if entGetal.get() != '' or entGetal2.get() != '':
        wortel()
    if entReac.get() != '':
        CalcReac(entReac.get())
    if TwfGameEnt1.get() != '' and TwfGameEnt2.get() != '' and TwfGameEnt3.get() != '' and TwfGameEnt4.get() != '':
        twfGame()
    if VLCinp1.get() != '' and VLCinp2.get() != '' and VLCinp3.get() != '' and VLFinp1.get() != '' and VLFinp2.get() != '' and VLFinp3.get() != '' and VLtargEnt.get() != '':
        VLhack()
    if entCPn.get() != '' and entCPr.get() != '':
        CPber()

frameRow2.pack(pady=5)
frameRow3.pack(pady=5)
frameRow4.pack(pady=5)

window.bind('<Return>', enter)

window.mainloop()


import sys
import numpy as np
from tqdm import tqdm

fil = sys.argv[1]
vocab_dir = sys.argv[2]

with open(vocab_dir + '/source_tokens.txt', 'r') as f:
    src_vocab_token2index = dict({x.strip('\n'): idx + 1 for idx, x in enumerate(f.readlines())})
    src_vocab_token2index['@@PADDING@@'] = 0
target_namespaces = ["answer", "program"]
dst_vocab_token2index = {}
for tn in target_namespaces:
    with open(vocab_dir + f'/{tn}.txt', 'r') as f:
        dst_vocab_token2index[tn] = dict({x.strip('\n'): idx + 1 for idx, x in enumerate(f.readlines())})
        dst_vocab_token2index[tn]['@@PADDING@@'] = 0

with open(fil, 'r') as f:
    lines = f.readlines()

QUES_MAX_LEN = 160 + 2
ANS_MAX_LEN = 30 + 3
PROG_MAX_LEN = 30 + 3
N = len(lines) // 2
Q = np.zeros((N, QUES_MAX_LEN + 1), dtype=np.ubyte)
A = np.zeros((N, ANS_MAX_LEN + 1), dtype=np.ubyte)
P = np.zeros((N, PROG_MAX_LEN + 1), dtype=np.ubyte)
get_src_idx = lambda x: src_vocab_token2index[x]
get_dst_idx = {k: dst_vocab_token2index[k].__getitem__ for k in dst_vocab_token2index}

for idx in tqdm(range(len(lines) // 2)):
    ques = lines[2 * idx].strip()
    ans, prog = lines[2 * idx + 1].strip().split('###')
    prog = prog.split()
    assert len(ques) <= QUES_MAX_LEN
    assert len(ans) <= ANS_MAX_LEN
    assert len(prog) <= PROG_MAX_LEN
    Q[idx][:len(ques)] = list(map(get_src_idx, ques))
    Q[idx][-1] = len(ques)
    A[idx][:len(ans) + 2] = [dst_vocab_token2index["answer"]["@start@"]] + list(map(get_dst_idx["answer"], ans)) + [
        dst_vocab_token2index["answer"]["@end@"]]
    A[idx][-1] = len(ans) + 2
    P[idx][:len(prog) + 2] = [dst_vocab_token2index["program"]["@start@"]] + list(map(get_dst_idx['program'], prog)) + [
        dst_vocab_token2index["program"]["@end@"]]
    P[idx][-1] = len(prog) + 2

data = {"Q": Q, "A": A, "P": P}

if Q.shape[0] > 10 ** 7:
    format = 'npz'
else:
    format = 'npy'

if fil.endswith('.txt'):
    save_path = fil[:-4] + '.' + format
else:
    save_path = f'{fil}.{format}'
if format == 'npy':
    np.save(save_path, data)
else:
    np.savez(save_path, Q=Q, A=A, P=P)


import logging
import os

from osbenchmark.builder.downloaders.builders.binary_builder import BinaryBuilder
from osbenchmark.exceptions import ExecutorError, BuildError

class SourceBinaryBuilder(BinaryBuilder):
    def __init__(self, executor, path_manager, jdk_resolver, source_directory, build_jdk_version, log_directory):
        self.logger = logging.getLogger(__name__)
        self.executor = executor
        self.path_manager = path_manager
        self.jdk_resolver = jdk_resolver

        self.source_directory = source_directory
        self.build_jdk_version = build_jdk_version
        self.log_directory = log_directory

    def build(self, host, build_commands, override_source_directory=None):
        for build_command in build_commands:
            self._run_build_command(host, build_command, override_source_directory)

    def _run_build_command(self, host, build_command, override_source_directory):
        source_directory = self.source_directory if override_source_directory is None else override_source_directory

        self.path_manager.create_path(host, self.log_directory, create_locally=False)
        log_file = os.path.join(self.log_directory, "build.log")

        _, jdk_path = self.jdk_resolver.resolve_jdk_path(host, self.build_jdk_version)
        self.executor.execute(host, f"export JAVA_HOME={jdk_path}")

        self.logger.info("Running build command [%s]", build_command)
        try:
            self.executor.execute(host, f"{source_directory}/{build_command} > {log_file} 2>&1")
        except ExecutorError:
            raise BuildError(f"Executing {build_command} failed. The build log can be found at {log_file}")


#%%
r"""
Hack into the MNIST Module
"""
import argparse
import sys

import matplotlib.pyplot as plt
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as torchF

from mnist_module import MNISTClassifier
# from npxconv import outerconv_2d
from plot_utils import savefig
from record_utils import record_append, record_dump_to_file

_arg = argparse.ArgumentParser()
_arg.add_argument("--hack_layer",
                  type=int,
                  default=3,
                  help="hack layer in [1, 2, 3, 4]")
_arg.add_argument("--train_epho",
                  type=int,
                  default=256,
                  help="train epho for hacking network")
_arg.add_argument("--eng", type=float, default=0.4, help="alpha * Ep + X")
args = _arg.parse_args()

HACK_LAYER = args.hack_layer

# read data
# shape N, 28, 28
test_img = np.load("mnist/mnist-test-image.npy")
test_img = test_img.astype(np.float32) / 255.0
assert test_img.shape[1] == 28 and test_img.shape[2] == 28

# shape 6000, int8
test_lab = np.load("mnist/mnist-test-label.npy")

torch_test_img = torch.FloatTensor(test_img.reshape(-1, 1, 28, 28))

train_img = np.load("mnist/mnist-train-image.npy")
train_img = train_img.astype(np.float32) / 255.0
assert train_img.shape[1] == 28 and train_img.shape[2] == 28

#%%

state_dict = torch.load("result/mnist-classifier.torch")
classifier = MNISTClassifier().eval()

classifier.load_state_dict(state_dict)

# accuracy

classifier_preict = classifier.forward(torch_test_img)
classifier_label = torch.argmax(classifier_preict, dim=-1)
classifier_label = classifier_label.data.cpu().numpy()

acc = np.mean(classifier_label == test_lab)

record_append("classifier", "", accuracy=acc)

# compute order one proxy kernels
# the weights
# _W1 = classifier.conv1.weight  # (5, 1, 3, 3)
# _W2 = classifier.conv2.weight  # (10, 5, 3, 3)
# _W3 = classifier.conv3.weight  # (10, 10, 3, 3)
# # compute proxy kernel layer by layer

# # (1, 5, 3, 3) * (5, 10, 3, 3) -> (1, 10, 7, 7) s=4,p=3
# _W = torch.conv_transpose2d(_W1.transpose(0, 1),
#                             _W2.transpose(0, 1),
#                             stride=2,
#                             padding=0)
# # (1, 10, 7, 7) * (10, 10, 3, 3) -> (1, 10, 15, 15) s=8, p=3
# _W = torch.conv_transpose2d(_W, _W3.transpose(0, 1), stride=2, padding=0)
# _W = _W / torch.norm(_W, dim=(2, 3), keepdim=True)
# print(_W.shape)
# exit(0)

# emulate order1
class EMUo1(nn.Module):

    def __init__(self):
        super().__init__()
        if HACK_LAYER == 1:
            self.cv1 = nn.Conv2d(1, 5, 3, 2, 1)
        elif HACK_LAYER == 2:
            self.cv1 = nn.Conv2d(1, 10, 7, 4, 3)
        elif HACK_LAYER == 3:
            self.cv1 = nn.Conv2d(1, 10, 15, 8, 3)
        elif HACK_LAYER == 4:
            self.cv1 = nn.Conv2d(1, 10, 31, 8, 3)

    def forward(self, input):
        out = self.cv1(input)
        if HACK_LAYER == 4:
            out = out.reshape(out.shape[0], out.shape[1])
        return out

#%%

emu = EMUo1()
emuopt = torch.optim.Adam(emu.parameters(), lr=1e-2)

for i in range(args.train_epho):
    np.random.shuffle(train_img)
    for _i in range(1, train_img.shape[0], 64):
        emuopt.zero_grad()
        # _x = torch.rand(64, 1, 28, 28)
        # _x = torch.randn(64, 1 * 28 * 28)
        # _x /= torch.norm(_x, dim=(-1), keepdim=True)
        # _x = _x.reshape(64, 1, 28, 28)
        _x = torch.FloatTensor(train_img[_i:_i + 64].reshape(-1, 1, 28, 28))

        target = classifier.forward(_x, k=HACK_LAYER)
        predict = emu.forward(_x)
        loss = torchF.mse_loss(predict, target)
        loss.backward()
        emuopt.step()

    print(f"\repho {i:4d}/{args.train_epho} loss {loss :.8f}", end="")

print("")

#%%

#%% compute proxy kernel epilson
def compute_ker_perturbation(ker, x, scale):
    """
    ker: shape (n, n)
    x: shape (28, 28)
    """
    f_x = np.fft.fftn(x, axes=(0, 1))
    f_W = np.fft.fftn(ker, s=x.shape, axes=(0, 1))

    Ep = np.fft.ifftn(f_W - f_x, axes=(0, 1)).real
    Ep -= np.min(Ep)
    Ep /= np.max(Ep)

    return scale * Ep + x

# l2 norm of hacker network and classifier network
classifier_pred = classifier.forward(torch_test_img, k=HACK_LAYER)
hacker_pred = emu.forward(torch_test_img)

hacker_label = classifier.forward_rest(hacker_pred, k=HACK_LAYER)

hacker_label = torch.argmax(hacker_label, dim=-1).data.cpu().numpy()

record_append(
    "classifier_hacker",
    "",
    error=torchF.mse_loss(classifier_pred, hacker_pred),
    hacker_accuracy=np.mean(test_lab == hacker_label),
)
# tick_label = [str(_d) for _d in range(10)]
# y = np.linspace(0, 9, 10)
# barhig = 0.35
# y1 = y - barhig / 2
# y2 = y + barhig / 2

predWriter = open(f"result/mnist-hack-{HACK_LAYER}-predict.csv", "w")
# predWriter = sys.stdout  #open(f"result/mnist-hack-{HACK_LAYER}-predict-temp.csv", "w")

predWriter.write("label")
for i in range(10):
    predWriter.write(",%d" % i)
predWriter.write("\n")

# wemu = emu.cv1.weight.data.cpu().numpy()
# wfin = _W.transpose(0, 1).data.cpu().numpy()

# fig, axi = plt.subplots(2, 10, sharex=False, sharey=True)
# for i in range(10):
#     axi[0, i].imshow(wemu[i, 0])
#     axi[0, i].axis("off")
#     axi[1, i].imshow(wfin[i, 0])
#     axi[1, i].axis("off")

# plt.show()

wfin = emu.cv1.weight.data.cpu().numpy()
wfinlen = wfin.shape[0]

for tag in range(wfinlen + 2):

    while True:
        picked_idx = np.random.randint(0, test_img.shape[0])
        obj_x = test_img[picked_idx]
        real_label = test_lab[picked_idx]

        t_obj_x = torch.tensor(obj_x.reshape(1, 1, 28, 28),
                               dtype=torch.float32)
        obj_pred = classifier.forward(t_obj_x)
        print("predict", torch.argmax(obj_pred), real_label)
        # skip wrong prediction
        if torch.argmax(obj_pred[0]) != real_label:
            continue
        break

    if tag < wfinlen:
        weig = wfin[tag, 0].copy()
    elif tag == wfinlen:
        weig = np.random.rand(wfin.shape[2], wfin.shape[3])
    else:
        weig = np.random.randn(wfin.shape[2], wfin.shape[3])

    fig = plt.figure(figsize=(8, 8))
    plt.imshow(obj_x) #, cmap='gray')
    plt.axis('off')
    savefig(fig, f"mnist-hack-{HACK_LAYER}-img-{tag}")
    # plt.show()
    plt.close()

    fig = plt.figure(figsize=(8, 8))
    plt.imshow(weig) #, cmap='gray')
    plt.axis('off')
    savefig(fig, f"mnist-hack-{HACK_LAYER}-patch-{tag}")
    # plt.show()
    plt.close()

    # Epx = randX.copy()
    # Epx[0:weig.shape[0],0:weig.shape[1]] = weig

    Epx = compute_ker_perturbation(weig, obj_x, args.eng)

    fig = plt.figure(figsize=(8, 8))
    plt.imshow(Epx)  #, cmap='gray')
    plt.axis('off')
    savefig(fig, f"mnist-hack-{HACK_LAYER}-img-patch-{tag}")
    # plt.show()
    plt.close()

    # prepate data
    t_Epx = torch.tensor(Epx.reshape(1, 1, 28, 28), dtype=torch.float32)

    pke_pred = classifier.forward(t_Epx)

    # print(torch.topk(pke_pred, k=3)[1])
    obj_pred = obj_pred[0].data.cpu().numpy()
    pke_pred = pke_pred[0].data.cpu().numpy()

    record_append(
        f"hack-{tag}",
        "",
        label=real_label,
        hack_label=np.argmax(pke_pred),
        object_predict=obj_pred,
        patched_predict=pke_pred,
    )

    predWriter.write("preX %d" % tag)
    for x in obj_pred:
        predWriter.write(",%.8f" % x)
    predWriter.write("\npreE %d" % tag)
    for x in pke_pred:
        predWriter.write(",%.8f" % x)
    predWriter.write("\n")

print("all done")

predWriter.close()

record_dump_to_file(f"mnist-hack-{HACK_LAYER}-predict")
# record_dump_to_file(sys.stdout)


# https://www.acmicpc.net/problem/20291

import sys
input = sys.stdin.readline
n = int(input())
extends = {}

for i in range(n) :
    name, extend = input().rstrip().split('.')
    if extend in extends :
        extends[extend] += 1
    else :
        extends[extend] = 1

extends = sorted(extends.items(), key = lambda x : x[0])

for k, v in extends :
    print(k, v)


import pandas as pd

# How to Get Column Names in Pandas DataFrame
# Method 1
data = pd.read_csv(r'D:\Filehandling\nba.csv', encoding='latin1')
for col in data.columns:
    print(col)

# Method 2 -using column attribute with dataframe object
data = pd.read_csv(r'D:\Filehandling\nba.csv', encoding='latin1')
list(data.columns)

# Method 3 -using keys function
data = pd.read_csv(r'D:\Filehandling\nba.csv', encoding='latin1')
print(data.keys())

# Method 4 - using column.values method
data = pd.read_csv(r'D:\Filehandling\nba.csv', encoding='latin1')
list(data.columns.values)

# Method 5 - Sorted() Method
data = pd.read_csv(r'D:\Filehandling\nba.csv', encoding='latin1')
df = sorted(data)
print(df)

# DROP COLUMNS in DATAFRAME
data = {
    'TATA': ['ALTROZ', 'NANO', 'NEXON', 'INDICA'],
    'TOYOTA': ['INNOVA', 'FORTUNER', 'GLANZA', 'CRYSTA'],
    'MARUTI': ['ALTO', 'WAGONR', 'BREEZA', 'BALENO'],
    'HYUNDAI': ['EON', 'VERNA', 'SANTRO', 'I20'],
    'RENAULT': ['KWID', 'TRIBER', 'KIGER', 'LIGER']
}

df = pd.DataFrame(data)
print(df)

# TO REMOVE SPECIFIC COLUMN
data = {
    'TATA': ['ALTROZ', 'NANO', 'NEXON', 'INDICA'],
    'TOYOTA': ['INNOVA', 'FORTUNER', 'GLANZA', 'CRYSTA'],
    'MARUTI': ['ALTO', 'WAGONR', 'BREEZA', 'BALENO'],
    'HYUNDAI': ['EON', 'VERNA', 'SANTRO', 'I20'],
    'RENAULT': ['KWID', 'TRIBER', 'KIGER', 'LIGER']
}

df = pd.DataFrame(data)
removecolu = df.drop(['RENAULT'], axis=1)
print(removecolu)

# TO REMOVE SPECIFIC(MULTIPLE COLUMNS)
data = {
    'TATA': ['ALTROZ', 'NANO', 'NEXON', 'INDICA'],
    'TOYOTA': ['INNOVA', 'FORTUNER', 'GLANZA', 'CRYSTA'],
    'MARUTI': ['ALTO', 'WAGONR', 'BREEZA', 'BALENO'],
    'HYUNDAI': ['EON', 'VERNA', 'SANTRO', 'I20'],
    'RENAULT': ['KWID', 'TRIBER', 'KIGER', 'LIGER']
}

df = pd.DataFrame(data)
removecolu = df.drop(['RENAULT', 'MARUTI'], axis=1)
print(removecolu)

# TO REMOVE COLUMNS BASED ON COLUMN INDEX
data = {
    'TATA': ['ALTROZ', 'NANO', 'NEXON', 'INDICA'],
    'TOYOTA': ['INNOVA', 'FORTUNER', 'GLANZA', 'CRYSTA'],
    'MARUTI': ['ALTO', 'WAGONR', 'BREEZA', 'BALENO'],
    'HYUNDAI': ['EON', 'VERNA', 'SANTRO', 'I20'],
    'RENAULT': ['KWID', 'TRIBER', 'KIGER', 'LIGER']
}

df = pd.DataFrame(data)
removecolu = df.drop(df.columns[[1]], axis=1, inplace=True)
print("REMOVE COLUMNS BASED ON COLUMN INDEX")
print(removecolu)

# x = input("Type a number: ")
# y = input("Type another number: ")

# sum = int(x) + int(y)

# print("The sum is: ", sum)

# Read csv files using Pandas.Read_csv()
# Syntax
# pd.read_csv(filepath,sep='',header='infer',index_col=None,usecols=None,engine=None,nrows=None)
print("Print the NBA FILE")
data = pd.read_csv(r'D:\Filehandling\nba.csv', encoding='latin1')
print(data)

# usecols in read_csv - read/load specific columns
# purpose - Load the specific Columns
# Name,Team,Salary
print("Load Specific Columns - NAME,TEAM,SALARY")
data = pd.read_csv(r'D:\Filehandling\nba.csv', encoding='latin1',
                   header=0, usecols=["Name", "Team", "Salary"])
print(data)

# using index_col in read_csv()
# purpose - reindex the header using the above function
print("REINDEX THE HEADER")
data = pd.read_csv(r'D:\Filehandling\nba.csv', encoding='latin1', header=0,
                   index_col=["Name", "Salary"],
                   usecols=["Name", "Team", "Salary"])
print(data)

# using nrows in read_csv()
# purpose - Display only 5 Rows

data = pd.read_csv(r'D:\FileHandling\nba.csv', encoding='latin1',
                   header=0, usecols=["Name", "Team", "Salary"],
                   index_col=["Name", "Salary"],
                   nrows=2)
print(data)

# using skiprows()
# purpose - Skip some rows in csv file
#skiprows = [1,12]

data = pd.read_csv(r'D:\FileHandling\nba.csv', encoding='latin1',
                   header=0, usecols=["Name", "Team", "Salary"],
                   skiprows=[1])

print(data)

# Saving a PANDAS DATAFRAME AS A CSV

# List data
name = ['ANIL', 'Virat', 'Yuvraj', 'Peter Dinklage']
deg = ['BTECH', 'MBA', 'MCA', 'BCOM']
score = [80, 90, 78, 88]

# Dict of lists

dict = {'Name': name,
        'Degree': deg,
        'Score': score
        }
df = pd.DataFrame(dict)
df.to_csv(r'D:\Filehandling\profiledata.csv', encoding='latin1')
print("DICT TO DATAFRAME")
print(df)

# HOW TO APPEND PANDAS DATAFRAME TO EXISTING CSV FILE
# SYNTAX
#df.to_csv('Existing CSV FILE', Mode= 'a', index = False, header = False)

data = {
    'Name': ['Jadeja', 'Arshadeep', 'Shami', 'Bumrah'],
    'Runs': [25, 10, 5, 0],
    'Wickets': [1, 2, 1, 2],
    'Catch': [1, 0, 1, 0]
}
df = pd.DataFrame(data)
df.to_csv(r'D:\Filehandling\Append.csv', encoding='latin1',
          mode='a', index=False, header=False)
print("Data Append Successfully")


import os
import json
import gzip
import time
import tempfile
import warnings

import torch

from functools import partial

from markovdwp.source.datasets import utils

from markovdwp.runtime.trainer import get_trainer
from markovdwp.runtime.utils.common import linear
from markovdwp.runtime.utils.reconstruction_logger \
    import SliceReconstructionLogger

from markovdwp.utils.dicttools import flatten, unflatten
from markovdwp.utils.runtime import get_datasets, get_dataloaders
from markovdwp.utils.runtime import register, get_class, get_instance

from pytorch_lightning.loggers import WandbLogger
from markovdwp.utils.vendor.pytorch_lightning import GradInformation

class NoTargetWarning(UserWarning):
    pass

def get_vae(encoder, decoder, options):
    return {
        'encoder': get_instance(**encoder, **options),
        'decoder': get_instance(**decoder, **options)
    }

def apply_resampling(datasets, resampling):
    """Apply the specified resampling stratefy."""
    resampled = {}
    for name, spec in resampling.items():
        if isinstance(spec, dict):
            dataset, kind = datasets[spec['source']], spec['kind']
            if kind not in ('subset', 'undersample', 'stratified'):
                raise ValueError(f'Unrecognized resampling `{kind}`')

            if kind == 'stratified':
                dataset, _ = utils.stratified_split(
                    dataset, spec['size'], spec.get('random_state'))

            elif kind == 'undersample':
                dataset, _ = utils.undersampled_split(
                    dataset, spec['size'], spec.get('random_state'))

            elif kind == 'subset':
                dataset = utils.subset(
                    dataset, spec['size'], spec.get('random_state'))

        else:
            dataset = datasets[spec]

        resampled[name] = dataset
    return resampled

def configure_optimizers(pl_module):
    optim = torch.optim.Adam(pl_module.parameters(), lr=pl_module.lr)

    sched = torch.optim.lr_scheduler.LambdaLR(
        optim, partial(linear, t0=0, t1=pl_module.trainer.max_epochs))

    return [optim], [{'scheduler': sched, 'monitor': 'loss'}]

def train(gpus, config, logger=None):
    # select the specified runtime and attach the dynamic methods
    Runtime = register(
        '_VAERuntime', GradInformation, get_class(config['runtime']),
        configure_optimizers=configure_optimizers)

    vae = get_vae(**config['vae'])
    pl_module = Runtime(**vae, **config['options'])

    pl_trainer = get_trainer(gpus=gpus, logger=logger, **config['trainer'])

    datasets = get_datasets(config['dataset'])
    if 'resampling' in config:
        datasets.update(apply_resampling(datasets, config['resampling']))
    feeds = get_dataloaders(datasets, config['feeds'])

    # if 'reference' dataset exists, then we create a reconstruction logger
    if 'reference' in datasets:
        X, y, *rest = zip(*datasets['reference'])

        order = sorted(range(len(y)), key=y.__getitem__)
        ref_x = torch.stack([X[i] for i in order], dim=0)

        ref_z = pl_module.prior.sample([len(ref_x)])

        pl_trainer.callbacks.append(
            SliceReconstructionLogger(ref_x.unsqueeze(1), ref_z,
                                      n_draws_is=1000, scatter=False))

    # last-minute update of the config before training
    logger.experiment.config.update(
        flatten(config, delim='__'),
        allow_val_change=True)

    # do the training
    try:
        pl_trainer.fit(pl_module, train_dataloader=feeds.get('train'))

    except ValueError as e:
        # it would be better is pl raised special exceptions from
        # `detect_nan_tensors`, rather than the same ValueError...
        if 'nan or inf' in str(e) or 'nan and/or inf' in str(e):
            raise FloatingPointError(str(e)) from e

        raise

    pl_module.cpu().eval()
    return pl_module.encoder, pl_module.decoder, pl_module.prior

def pack(module):
    from inspect import signature

    parameters = {}
    # adopt sklearn's convention: save arguments in instance's `__dict__`
    for name, p in signature(type(module)).parameters.items():
        # ignore variable keyworded args
        if p.kind == p.VAR_KEYWORD:
            continue

        parameters[name] = getattr(module, p.name)

    return {
        'model': {'cls': str(type(module)), **parameters},
        'state': module.state_dict(),
    }

def main(manifest, target=None, gpus=[0], debug=False, tags=None):
    breakpoint() if debug else None

    assert tags is None or isinstance(tags, str)
    tags = tags.split(',') if tags is not None else []

    # the manifest must be complete and ready to go
    parameters = json.load(open(manifest, 'rt'))

    if target is None:
        # do not save anything
        warnings.warn('No target path specified, the model will not be saved',
                      NoTargetWarning)

    elif os.path.isdir(target):
        # consume the first tag
        tag, *tags = tags if tags else [None]

        # save under a random name if target is a directory
        fid, target = tempfile.mkstemp(dir=target, suffix='.gz',
                                       prefix=tag + '__' if tag else tag)
        os.close(fid)

    elif os.path.exists(target):
        raise ValueError(f'`{target}` already exists! Refusing to proceed.')

    # pl's Wandb logger uses reinit=true!
    # wandb.init(project='DWP Slice Replication Machine', reinit=False)
    logger = WandbLogger(project='Variatonal Autoencoders',
                         tags=tags)

    # sync with wandb's agent's arguments and rebuild the config
    # XXX wandb's config keys should not collide with meaningful manifest's keys
    config = unflatten({
        **flatten(parameters, delim='__'),  # defaults from the manifest
        **logger.experiment.config          # overrides from wandb
    }, delim='__')

    # train the model
    encoder, decoder, prior = train(gpus, config, logger)
    if target is not None:
        with gzip.open(target, 'wb', compresslevel=9) as fout:
            torch.save({
                '__dttm__': time.strftime('%Y%m%d %H%M%S'),
                'config': config,
                'encoder': pack(encoder),
                'decoder': pack(decoder),
                'prior': pack(prior) if isinstance(prior, torch.nn.Module) else {},
            }, fout)

    return encoder, decoder, prior

if __name__ == '__main__':
    import argparse

    parser = argparse.ArgumentParser(
        description='Train a single VAE from .models on the specified dataset.',
        add_help=True)

    parser.add_argument(
        '--manifest', type=str, required=True,
        help='The manifest of the experiment.')

    parser.add_argument(
        '--target', type=str, required=False, default=None,
        help='The path where to store the trained model under a '
             'unique name, or the name of the snapshot wherein the '
             'model will be saved, or omitted, if model snapshot is '
             'not needed.')

    parser.add_argument(
        '--gpus', type=int, nargs='+', required=False, default=None,
        help='Device ids to occupy by the experiment.')

    parser.add_argument(
        '--tags', type=str, required=False,
        help='Optional comma-separated tags for the experiment being run. '
             'If `target` is a directory, then the first tag is used as a '
             'prefix to in model names.')

    parser.add_argument(
        '--debug', required=False, dest='debug', action='store_true',
        help='Enter trace mode.')

    parser.set_defaults(
        target=None, gpus=[0], tags=None, debug=False)

    args, _ = parser.parse_known_args()
    main(**vars(args))


import sys
input = sys.stdin.readline

n, m, l = map(int, input().rstrip().split())
arr = [0 for _ in range(n)]
arr[0] = 1
cnt = 0
now = 0
while max(arr) < m:
    if arr[now] % 2 == 1:
        now = (now + l) % n
    else:
        now = now - l
        while now < 0:
            now += n
    arr[now] += 1
    cnt += 1

print(cnt)

백준/Bronze/1592. 영식이와 친구들/영식이와 친구들.py


import copy

import django_filters
from django_filters.filterset import FilterSetMetaclass, BaseFilterSet

from app.articles.models import Article, Comment
from app.authentication.models import User

class CustomBaseFilterSet(BaseFilterSet):

    def __init__(self, data=None, queryset=None, *, request=None, prefix=None):
        if queryset is None:
            queryset = self._meta.model._default_manager.all()
        if not hasattr(queryset, 'model'):
            model = self._meta.model
        else:
            model = queryset.model

        self.is_bound = data is not None
        self.data = data or {}
        self.queryset = queryset
        self.request = request
        self.form_prefix = prefix

        self.filters = copy.deepcopy(self.base_filters)

        # propagate the model and filterset to the filters
        for filter_ in self.filters.values():
            filter_.model = model
            filter_.parent = self

    @property
    def qs(self):
        if not hasattr(self, '_qs'):
            qs = self.queryset
            if self.is_bound:
                # ensure form validation before filtering
                self.errors
                qs = self.filter_queryset(qs)
            self._qs = qs
        return self._qs

class CustomFilterSet(CustomBaseFilterSet, metaclass=FilterSetMetaclass):
    pass

# class ArticleFilter(CustomFilterSet):
class ArticleFilter(django_filters.FilterSet):
    class Meta:
        model = Article
        fields = (
            "slug", "title", "content", "creator", "creator__username"
        )
        ordering = ('-datetime_created', '-datetime_updated')

    slug = django_filters.CharFilter(lookup_expr='exact')
    title = django_filters.CharFilter(lookup_expr='contains')
    content = django_filters.CharFilter(lookup_expr='contains')
    creator = django_filters.ModelChoiceFilter(queryset=User.objects.filter(is_active=True).all())
    creator__username = django_filters.CharFilter(lookup_expr='exact')

    order_by = django_filters.OrderingFilter(
        fields=(
            ('datetime_created', 'datetime_updated', 'title', 'content')
        )
    )

class CommentFilter(django_filters.FilterSet):
    class Meta:
        model = Comment
        fields = (
            "content", "creator", "datetime_created", "datetime_updated"
        )

    article = django_filters.ModelChoiceFilter(queryset=Article.objects.filter().all())


#!/usr/bin/env python

import os
import re
import sys
import nibabel
import pandas
import json

from glob import glob

# These arguments come from the command line. You should first
# run this interactively (eg with ipython in a terminal) and
# type/copy paste the commands one at a time.
# /home/vanessa/Documents/Work/pipelines/ryan/sub-01
data_folder = sys.argv[1]
output_folder = sys.argv[2]

# Here we are making sure that output folders and data folders exist
# and making them if necessary
if not os.path.exists(output_folder):
    os.mkdir(output_folder)
    print("Creating output folder %s" %(output_folder))

if not os.path.exists(data_folder):
    print("Cannot find %s. Check path and try again" %(data_folder))

# This is the subject id, and we are extracting from the folder name
sub_id = os.path.basename(data_folder) # You can also extract this from the data

# Here we are preparing output BIDS folders
bids_folder = "%s/%s" %(output_folder,sub_id)
if not os.path.exists(bids_folder):
    print("Making bids output folder %s" %(bids_folder))
    os.mkdir(bids_folder)

for folder in ['anat','pet']:
    modality_folder = "%s/%s" %(bids_folder,folder)
    if not os.path.exists(modality_folder):
        os.mkdir(modality_folder)

# S1 has the anatomicals
anat_files = glob('%s/S1/*.nii.gz' %data_folder)

# S2 has the pet
pet_file = glob('%s/S2/*.nii.gz' %data_folder)[0]

# Let's use this anatomical
anat_file = [x for x in anat_files if re.search('^co',os.path.basename(x))][0]
anat_bids = "%s/anat/%s_T1w.nii.gz" %(bids_folder,sub_id)
os.rename(anat_file,anat_bids)

# And rename the pet
pet_bids = "%s/pet/%s_pet.nii.gz" %(bids_folder,sub_id)
os.rename(pet_file,pet_bids)

# RYAN: here is where you start!
# Now we want to generate a json data structure for each of these files to be finished.
# Step 1: Download this example pet data in BIDS Format: https://drive.google.com/file/d/0B2JWN60ZLkgkOHdxRk5BUUlQelE/view?usp=sharing
# Step 2: Look at the json file in /pet_phno/sub-000005/pet/. This is the file that you will want to create for your pet data,
# and the equivalent for the T1 (see in the anat folder).
# Step 3: Read in your nifti output files generated above as follows:

anat = nibabel.load(anat_bids)
pet = nibabel.load(pet_bids)

# Take a look at pet.header.keys() that can be accessed in the header, and read about
# nibabel here: http://nipy.org/nibabel/
# Your goal is to generate that json file, name equivalently as the example, and save
# each one to the anat / pet folder respectively. Use the write_json function below
# to save your dictionary. So for example, you could do:

anat_dict = dict()
anat_dict["Info"] = dict()
anat_dict["Info"]["BodyPart"] = "brain"

# FILL IN THE REST HERE

# Save, each of anat and pet

# Final Step
# Generation of BIDS information

bids_description = { "BIDSVersion": "1.1.0-pet",
                     "Name": "FLUMAZENILAUTISM" }
bids_description_file = "%s/dataset_description.json" %bids_folder

# Here is a function to write a json file
def write_json(json_obj,filename,mode="w",print_pretty=True):
    '''write_json will (optionally,pretty print) a json object to file
    :param json_obj: the dict to print to json
    :param filename: the output file to write to
    :param pretty_print: if True, will use nicer formatting
    '''
    with open(filename,mode) as filey:
        if print_pretty == True:
            filey.writelines(json.dumps(json_obj, indent=4, separators=(',', ': ')))
        else:
            filey.writelines(json.dumps(json_obj))
    return filename

# Write the file
write_json(bids_description,bids_description_file)

# Write participants file
participants_file = "%s/participants.tsv" %(bids_folder)
if os.path.exists(participants_file):
    participants = pandas.read_csv(participants_file,index=True,sep="\t")
else:
    participants = pandas.DataFrame(columns=["participant_id","species","strain","population",
                                             "bodyWeight","bodyWeightUnits","age","ageUnits","gender"])

participants.loc[sub_id,"participant_id"] = sub_id
participants.to_csv(participants_file,sep="\t")


from datetime import datetime
from django.contrib import admin
from counsellor.forms import CounsellorAdminCreationForm, UserAdminCreationForm
from django.contrib import messages
from counsellor.models import *
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.shortcuts import redirect

# Register your models here.
admin.site.register(Consent)
admin.site.register(CounsellingType)

class UserAdmin(BaseUserAdmin):
    # The forms to add and change user instances
    # form = UnPriviledgedUserForm
    add_form = UserAdminCreationForm
    # The fields to be used in displaying the User model.
    # These override the definitions on the base UserAdmin
    # that reference specific fields on auth.User
    list_display = [
        "email",
        "first_name",
        "last_name",
        "other_names",
        "is_active",
        "is_staff",
        "is_superuser",
        "user_type",
        "sex",
        "religion",
        "marital_status",
        "phone",
    ]

    list_display_links = ['email', 'first_name', 'last_name']

    search_fields = ['first_name', 'last_name', 'email', 'phone']

    ordering = ['-created_at']
    list_filter = []

    fieldsets = (
        (None, {'fields': ('email', 'password')}),
        ('Personal info', {'fields': (
            'first_name',
            'last_name',
            'other_names',
            'phone',
            'address',
            'sex',
            'religion',
            'marital_status',
        )}),
        ('Permissions', {'fields': (
            'is_active',
            'is_staff',
            'is_superuser',
        )}),
        (None, {'fields': (
            'user_type',
            'avatar',
        )}),
    )

    # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
    # overrides get_fieldsets to use this attribute when creating a user.
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': (
                'email',
                'first_name',
                'last_name',
                'password',
                'password2'
                )
            }
        ),
    )

class CounsellorAdmin(UserAdmin):
    add_form = CounsellorAdminCreationForm

    list_display = [
        "email",
        "first_name",
        "last_name",
        "other_names",
        "is_active",
        "is_staff",
        "is_superuser",
        "sex",
        "phone",
    ]

    list_display_links = ['email', 'first_name', 'last_name']

    search_fields = ['first_name', 'last_name', 'email', 'phone']
    filter_horizontal = ['fields','availability']
    ordering = ['-created_at']
    list_filter = []

    fieldsets = (
        (None, {'fields': ('email', 'password')}),
        ('Personal info', {'fields': (
            'title',
            'first_name',
            'last_name',
            'other_names',
            'phone',
            'address',
            'sex',
            'description',
        )}),
        ('Permissions', {'fields': (
            'is_active',
            'is_staff',
            'is_superuser',
        )}),
        (None, {'fields': (
            'available',
            'profile',
            'fields',
            'availability',
        )}),
    )

    # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
    # overrides get_fieldsets to use this attribute when creating a user.
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': (
                'email',
                'first_name',
                'last_name',
                'password',
                'password2'
                )
            }
        ),
    )

@admin.register(Booking)
class BookingAdmin(admin.ModelAdmin):
    list_display = [
        "client",
        "counsellor",
        "status",
        "created_at"
    ]

    list_display_links = ['client', 'counsellor', 'status']

    search_fields = ['client', 'counsellor', 'status']
    ordering = ['-created_at']
    list_filter = ["status"]

    def save_model(self, request, obj, form, change):
        start_time   = datetime.combine(obj.start_date, obj.start_time).replace(hour=0,minute=0, second=0, microsecond=0)
        current_time = datetime.now().replace(hour=0,minute=0, second=0, microsecond=0)

        if start_time < current_time:
            messages.error(request, "Starting date cannot be any day before current")
            return redirect('.')

        elif obj.start_time > obj.end_time:
            messages.error(request, "Starting time cannot be more than ending time.")
            return redirect('.')

        elif obj.start_time == obj.end_time:
            messages.error(request, "Starting time cannot be same as ending time.")
            return redirect('.')

        else:
            return super(BookingAdmin, self).save_model(request, obj, form, change)

@admin.register(AvailableDay)
class AvailableDayAdmin(admin.ModelAdmin):
    list_display = ['day']

    def has_change_permission(self, request, obj=None):
        return True

    def has_delete_permission(self, request, obj=None):
        return True

    def has_add_permission(self, request, obj=None):
        return True

admin.site.register(User, UserAdmin)
admin.site.register(Counsellor, CounsellorAdmin)


# SW Expert Academy
# 4864. [파이썬 S/W 문제해결 기본] 3일차 - 문자열 비교 D2
# https://swexpertacademy.com/main/learn/course/subjectDetail.do?courseId=AVuPDN86AAXw5UW6&subjectId=AWOVGOEKqeoDFAWg

### 보이어-무어 알고리즘 이용 버전 ###

T = int(input())

for test_case in range(1, T +1):
    N = list(input())
    M = list(input())

    n = len(N)
    m = len(M)

    # skip 배열 생성
    skip = dict()
    for i in range(n):
        skip[N[i]] = n-1-i

    result = 0
    i = n - 1
    cur = n - 1
    while i < m:
        if cur == -1: # N을 뒤에서부터 처음까지 다 비교한 뒤
            result = 1
            break
        if M[i] == N[cur]:
            # 패턴의 끝 원소와 일치하면
            i -= 1
            cur -= 1
        else:
            # 패턴의 끝 원소와 일치하지 않으면
            if (skip.get(M[i]) != None): # skip 배열에 원소가 있으면 해당 값을 더한다.
                i += int(skip.get(M[i]))
            else: # skip 배열에 원소가 없으면 패턴의 길이만큼 더한다.
                i += n
            cur = n - 1

    print(f"#{test_case} {result}")


import numpy as np
from sklearn.linear_model import LogisticRegression
import utils
import pandas as pd
import pickle
from sklearn.model_selection import train_test_split
import argparse
import torch

def get_data(region_dset, imagenet_dset, imagenet_indexsample, imagenet_dset_excluded, ratio):
    print('Building Training Sets ... ', flush=True)

    region_num_images = 4970

    print("Percentage of Appen Images: " + str(ratio))

    full_region_random_sample = np.random.choice(len(region_dset['train'][0]), region_num_images, replace=False) #4970 images

    region_num_images = np.floor(region_num_images * ratio).astype(int) #0.5
    region_random_sample = np.random.choice(full_region_random_sample, region_num_images, replace=False) # gives indices corr to region_dset

    excluded_pics = np.array([i for i in full_region_random_sample if i not in region_random_sample]) # appen excluded from training from org 4970

    checkpoint1 = len(full_region_random_sample) - len(region_random_sample)

    print("Number of Images Taken out of Appen Checkpoint 1: " + str(checkpoint1))
    print("Number of Images Taken out of Appen Checkpoint 2: " + str(len(excluded_pics)))

    imagenet_addOn = set() # imagenet images added on to supplement appen being taken out
    imagenet_excluded = set() # images excluded from 33383
    for obj in range(38):
        for image in imagenet_dset_excluded[str(obj)][0]:
            imagenet_excluded.add(image)
        excluded = set()
        for pic_index in excluded_pics: # for each index in pics excluded from appen 4970
            excluded_obj = region_dset['train'][1][pic_index]
            if excluded_obj == obj:
                excluded.add(pic_index)
        if len(imagenet_dset_excluded[str(obj)][0]) < len(excluded):
            addOn_sample = np.random.choice(imagenet_dset_excluded[str(obj)][0], len(imagenet_dset_excluded[str(obj)][0]), replace=False)
        else:
            addOn_sample = np.random.choice(imagenet_dset_excluded[str(obj)][0], len(excluded), replace=False)
        for image in addOn_sample:
            imagenet_addOn.add(image)

    available_imagenet = np.array([i for i in imagenet_excluded if i not in imagenet_addOn])
    addon_subset = np.random.choice(available_imagenet, (len(excluded_pics) - len(imagenet_addOn)), replace=False)
    for image in addon_subset:
        imagenet_addOn.add(image)

    print("Number of Images Taken out of Appen Checkpoint 3: " + str(len(imagenet_addOn)))

    imagenet_random_sample = [*imagenet_indexsample['index'][0], *imagenet_addOn]

    region_train_names = [region_dset['train'][0][i] for i in region_random_sample]
    region_train_obj = [region_dset['train'][1][i] for i in region_random_sample]
    print("Appen Training Size: " + str(len(region_train_names)))

    imagenet_train_names = [imagenet_dset['train'][0][i] for i in imagenet_random_sample]
    imagenet_train_obj = [imagenet_dset['train'][1][i] for i in imagenet_random_sample]
    print("Imagenet Training Size: " + str(len(imagenet_train_names)))

    train_names = [*imagenet_train_names, *region_train_names]
    train_obj = [*imagenet_train_obj, *region_train_obj]
    print("Total Training Size: " + str(len(train_names)))

    val_names = [*imagenet_dset['val'][0], *region_dset['val'][0]]
    val_obj = [*imagenet_dset['val'][1], *region_dset['val'][1]]
    val = [val_names, val_obj]

    return train_names, train_obj, val_names, val_obj

parser = argparse.ArgumentParser()

parser.add_argument('--reg', type=int, default=0, metavar='reg',
                    help='region number')
parser.add_argument('--perc', type=float, default=0, metavar='reg',
                    help='percent to use for training')
parser.add_argument('--save', type=str, default='test', metavar='reg',
                    help='save directory')
parser.add_argument('--test', action='store_true')

args = parser.parse_args()

params_train = {'batch_size': 32,
         'shuffle': True,
         'num_workers': 0}

params_valtest = {'batch_size': 32,
         'shuffle': False,
         'num_workers': 0}

region_to_name = {0:'africa', 1:'americas', 2:'eastasia', 3:'europe', 4:'southeastasia', 5:'westasia'}

print('Region:{}, perc: {}'.format(region_to_name[args.reg], args.perc))

region_dset = pickle.load(open('data/appen_prep_{}.pkl'.format(region_to_name[args.reg]), 'rb')) # change for region
imagenet_dset = pickle.load(open('data/imagenet_prep.pkl', 'rb'))
imagenet_indexsample = pickle.load(open('data/imagenet_33383indices.pkl', 'rb'))
imagenet_dset_excluded = pickle.load(open('data/imagenet33383_excludedIndices.pkl', 'rb'))

train_names, train_obj, val_names, val_obj = get_data(region_dset,
                                                      imagenet_dset,
                                                      imagenet_indexsample,
                                                      imagenet_dset_excluded,
                                                      args.perc)

appen = pickle.load(open('data/appen/PASS_features/region{}.pkl'.format(args.reg), 'rb'))

appen_features = {}

for o in appen.keys():
    for s in ['train', 'test']:
        appen_features.update(appen[o][s])

imagenet_features = {}
import os

for obj in os.listdir('data/im/PASS_features/'):
    print(obj)
    imagenet_features.update(pickle.load(open('data/im/PASS_features/{}'.format(obj), 'rb')))

imagenet_features_2 = {}
for a in imagenet_features:
    #print(a, imagenet_features[a].shape)
    #break
    imagenet_features_2[a.split('/')[-1]] = imagenet_features[a]

features_dict = appen_features
features_dict.update(imagenet_features_2)

train_features = []

for a in train_names:
    if a in features_dict:
        train_features.append(features_dict[a])
    elif a.split('/')[-1] in features_dict:
        train_features.append(features_dict[a.split('/')[-1]])
    else:
        print('missing :{}'.format(a))
train_features = torch.Tensor(np.concatenate(train_features)).squeeze()
print(train_features.shape)
val_features = []

for a in val_names:
    if a in features_dict:
        val_features.append(features_dict[a])
    elif a.split('/')[-1] in features_dict:
        val_features.append(features_dict[a.split('/')[-1]])
    else:
        print('missing :{}'.format(a))

val_features = torch.Tensor(np.concatenate(val_features)).squeeze()
print(val_features.shape)

criterion = torch.nn.CrossEntropyLoss()
#acc_function = compute_acc
ydtype = torch.long

m = torch.nn.Linear(2048, 38)

optimizer_setting = {
    'optimizer': torch.optim.SGD,
    'lr': 0.1,
    'momentum': 0.9
}
optimizer = optimizer_setting['optimizer'](
                    params=m.parameters(),
                    lr=optimizer_setting['lr'], momentum=optimizer_setting['momentum'])
count=0
if torch.cuda.is_available():
    device = torch.device('cuda')
    m = m.to(device)
else:
    device = torch.device('cpu')

batch_size = params_train['batch_size']
N = len(train_names)//batch_size + 1

if not os.path.exists(args.save):
    os.makedirs(args.save)

train_obj = torch.Tensor(train_obj)
val_obj = torch.Tensor(val_obj)

dtype = torch.float32
best_acc = 0.0

if not args.test:

    batch_size = 512
    N = len(train_features)//batch_size+1
    for e in range(500):
        m.train()
        rand_perm = np.random.permutation(len(train_features))

        train_features = train_features[rand_perm]
        train_obj = train_obj[rand_perm]
        train_names = [train_names[i] for i in rand_perm]

        for t in range(N):
            feat_batch = train_features[t*batch_size:(t+1)*batch_size].to(device=device, dtype = dtype)
            target_batch = train_obj[t*batch_size:(t+1)*batch_size].to(device=device, dtype = ydtype)

            sc = m(feat_batch)

            optimizer.zero_grad()

            loss = criterion(sc, target_batch)
            loss.backward()

            optimizer.step()

            #if t%100==0:
            #    print(e, t, loss, flush=True)

        m.eval()

        val_scores = m(val_features.to(device))
        loss_val = criterion(val_scores, val_obj.to(device, ydtype))

        val_pred = np.argmax(val_scores.squeeze().detach().cpu().numpy(), axis=1)
        acc = np.where(val_pred==val_obj.numpy(), 1, 0).mean()

        print(e, loss, acc, flush=True)

        if acc>best_acc:
            best_acc =acc
            torch.save({'model':m.state_dict(), 'optimizer':optimizer.state_dict(), 'epoch': e, 'loss':loss, 'acc':acc},
                        '{}/final.pth'.format(args.save)
                        )

        torch.save({'model':m.state_dict(), 'optimizer':optimizer.state_dict(), 'epoch': e, 'loss':loss, 'acc':best_acc},
                    '{}/current.pth'.format(args.save)
                    )

m.load_state_dict(torch.load('{}/final.pth'.format(args.save))['model'])
m = m.to(device)
europe_dset = pickle.load(open('data/appen_prep_{}.pkl'.format('europe'), 'rb')) # change for region

europe = pickle.load(open('data/appen/PASS_features/region{}.pkl'.format(3), 'rb'))

eur_features_dict = {}

for o in europe.keys():
    for s in ['train', 'test']:
        eur_features_dict.update(europe[o][s])

val_europe = []

for a in europe_dset['val'][0]:
    val_europe.append(eur_features_dict[a])

val_europe = torch.Tensor(np.concatenate(val_europe)).squeeze()
m.eval()
softmax = torch.nn.Softmax(dim=1)
sc_europe = softmax(m(val_europe.to(device))).detach().cpu().numpy()

pred_europe = np.argmax(sc_europe, axis=1).squeeze()

acc_europe = np.where(pred_europe==np.array(europe_dset['val'][1]), 1, 0).mean()

with open('{}/europe_val_scores.pkl'.format(args.save), 'wb+') as handle:
    pickle.dump(sc_europe, handle)
print('Europe val scores: ', 100*acc_europe)

val_region = []

for a in region_dset['val'][0]:
    val_region.append(appen_features[a])

val_region = torch.Tensor(np.concatenate(val_region)).squeeze()
m.eval()
sc_region = softmax(m(val_region.to(device))).detach().cpu().numpy()

pred_region = np.argmax(sc_region, axis=1).squeeze()

acc_region = np.where(pred_region==np.array(region_dset['val'][1]), 1, 0).mean()

with open('{}/region{}_val_scores.pkl'.format(args.save, args.reg), 'wb+') as handle:
    pickle.dump(sc_region, handle)
print('Region val scores: ', 100*acc_region)

test_europe = []

for a in europe_dset['test'][0]:
    test_europe.append(eur_features_dict[a])

test_europe = torch.Tensor(np.concatenate(test_europe)).squeeze()
m.eval()
softmax = torch.nn.Softmax(dim=1)
sc_europe = softmax(m(test_europe.to(device))).detach().cpu().numpy()

pred_europe = np.argmax(sc_europe, axis=1).squeeze()

acc_europe = np.where(pred_europe==np.array(europe_dset['test'][1]), 1, 0).mean()

with open('{}/europe_test_scores.pkl'.format(args.save), 'wb+') as handle:
    pickle.dump(sc_europe, handle)
print('Europe test scores: ', 100*acc_europe)

test_region = []

for a in region_dset['test'][0]:
    test_region.append(appen_features[a])

test_region = torch.Tensor(np.concatenate(test_region)).squeeze()
m.eval()
sc_region = softmax(m(test_region.to(device))).detach().cpu().numpy()

pred_region = np.argmax(sc_region, axis=1).squeeze()

acc_region = np.where(pred_region==np.array(region_dset['test'][1]), 1, 0).mean()

with open('{}/region{}_test_scores.pkl'.format(args.save, args.reg), 'wb+') as handle:
    pickle.dump(sc_region, handle)
print('Region test scores: ', 100*acc_region)


#!/usr/bin/env python3

# for kubeedge only.

import re, os

def delete(i):
    os.system("rm -rf /var/lib/edged/pods/" + i)
    print("delete %s" % i)

with os.popen("mount") as m:
    d_info = m.read().split("\n")

def umount(uuid):
    global d_info
    ret = tuple(filter(lambda u:uuid in u, d_info))
    if ret:
        drv = ret[0].split()[2]
        print("umounting %s" % drv)
        os.system("umount "+drv)

with open("log") as f:
    deleted = set()
    compiled = re.compile(r'Orphaned pod "([a-f0-9-]+)"')
    for line in f.readlines():
        g = compiled.search(line)
        if g is None:
            continue
        g = g.groups()
        if g[0] not in deleted and os.path.exists("/var/lib/edged/pods/"+g[0]):
            umount(g[0])
            delete(g[0])
            deleted.add(g[0])
print("%d volumes have been deleted." % len(deleted))


import tensorflow as tf

def map_gradients(gradient_map, gis, length):
    index_tensor = tf.reshape(tf.concat([
        tf.reshape(tf.tile(tf.expand_dims(gis, 1), [1, 3]), [length * 3, 1]),
        tf.expand_dims(tf.tile(tf.range(0, limit=3), [length]), 1)
    ], 1), [length, 3, 2])
    return tf.gather_nd(gradient_map, index_tensor)

def tf_repeat(x, num_repeats):
    x = tf.reshape(x, [-1, 1])
    x = tf.tile(x, [1, num_repeats])
    return tf.reshape(x, [-1])

def get_input_vectors(shape, phases, scaling, offset):
    x = tf.reshape(tf_repeat(offset[0] + tf.linspace(0.0, float(shape[0]) - 1., shape[0]) / float(scaling),
                             shape[1] * phases),
                   [shape[0], shape[1], phases]) * tf.pow(2.0, tf.linspace(0.0, float(phases) - 1., phases))
    y = tf.reshape(tf_repeat(tf.tile(
        offset[1] + tf.linspace(0.0, float(shape[1]) - 1., shape[1]) / scaling,
        [shape[0]]
    ), phases), [shape[0], shape[1], phases]) * tf.pow(2.0, tf.linspace(0.0, float(phases) - 1., phases))
    z = tf.reshape(
        tf.tile(offset[2] + 10. * tf.linspace(0.0, float(phases) - 1., phases), [shape[0] * shape[1]]),
        [shape[0], shape[1], phases, 1])
    x = tf.reshape(x, [shape[0], shape[1], phases, 1])
    y = tf.reshape(y, [shape[0], shape[1], phases, 1])

    return tf.reshape(tf.concat([x, y, z], 3), [shape[0] * shape[1] * phases, 3])

def get_simplex_vertices(offsets, vertex_table, length):
    vertex_table_x_index = tf.cast((offsets[:, 0] >= offsets[:, 1]), tf.int32)
    vertex_table_y_index = tf.cast((offsets[:, 1] >= offsets[:, 2]), tf.int32)
    vertex_table_z_index = tf.cast((offsets[:, 0] >= offsets[:, 2]), tf.int32)

    index_list = tf.concat([
        tf.reshape(tf.tile(tf.concat([
            tf.expand_dims(vertex_table_x_index, 1),
            tf.expand_dims(vertex_table_y_index, 1),
            tf.expand_dims(vertex_table_z_index, 1),
        ], 1), [1, 6]), [6 * length, 3]),
        tf.expand_dims(tf.tile(tf.range(0, limit=6), [length]), 1)], 1)
    vertices = tf.reshape(tf.gather_nd(vertex_table, index_list), [-1, 2, 3])
    return vertices

def calculate_gradient_contribution(offsets, gis, gradient_map, length):
    t = 0.5 - offsets[:, 0] ** 2. - offsets[:, 1] ** 2. - offsets[:, 2] ** 2.
    mapped_gis = map_gradients(gradient_map, gis, length)
    dot_products = tf.reduce_sum(mapped_gis * offsets, 1)
    return tf.cast(tf.math.greater_equal(t, 0.), tf.float32) * t ** 4. * dot_products

def noise3d(input_vectors, perm, grad3, vertex_table, length):
    skew_factors = (input_vectors[:, 0] + input_vectors[:, 1] + input_vectors[:, 2]) * 1.0 / 3.0
    skewed_vectors = tf.floor(input_vectors + tf.expand_dims(skew_factors, 1))
    unskew_factors = (skewed_vectors[:, 0] + skewed_vectors[:, 1] + skewed_vectors[:, 2]) * 1.0 / 6.0
    offsets_0 = input_vectors - (skewed_vectors - tf.expand_dims(unskew_factors, 1))
    simplex_vertices = get_simplex_vertices(offsets_0, vertex_table, length)  # divided it by 2, doesn't error now
    offsets_1 = offsets_0 - simplex_vertices[:, 0, :] + 1.0 / 6.0
    offsets_2 = offsets_0 - simplex_vertices[:, 1, :] + 1.0 / 3.0
    offsets_3 = offsets_0 - 0.5
    masked_skewed_vectors = tf.cast(skewed_vectors, tf.int32) % 256
    gi0s = tf.gather_nd(
        perm,
        tf.expand_dims(masked_skewed_vectors[:, 0], 1) +
        tf.expand_dims(tf.gather_nd(
            perm,
            tf.expand_dims(masked_skewed_vectors[:, 1], 1) +
            tf.expand_dims(tf.gather_nd(
                perm,
                tf.expand_dims(masked_skewed_vectors[:, 2], 1)), 1)), 1)
    ) % 12
    gi1s = tf.gather_nd(
        perm,
        tf.expand_dims(masked_skewed_vectors[:, 0], 1) +
        tf.expand_dims(tf.cast(simplex_vertices[:, 0, 0], tf.int32), 1) +
        tf.expand_dims(tf.gather_nd(
            perm,
            tf.expand_dims(masked_skewed_vectors[:, 1], 1) +
            tf.expand_dims(tf.cast(simplex_vertices[:, 0, 1], tf.int32), 1) +
            tf.expand_dims(tf.gather_nd(
                perm,
                tf.expand_dims(masked_skewed_vectors[:, 2], 1) +
                tf.expand_dims(tf.cast(simplex_vertices[:, 0, 2], tf.int32), 1)), 1)), 1)
    ) % 12
    gi2s = tf.gather_nd(
        perm,
        tf.expand_dims(masked_skewed_vectors[:, 0], 1) +
        tf.expand_dims(tf.cast(simplex_vertices[:, 1, 0], tf.int32), 1) +
        tf.expand_dims(tf.gather_nd(
            perm,
            tf.expand_dims(masked_skewed_vectors[:, 1], 1) +
            tf.expand_dims(tf.cast(simplex_vertices[:, 1, 1], tf.int32), 1) +
            tf.expand_dims(tf.gather_nd(
                perm,
                tf.expand_dims(masked_skewed_vectors[:, 2], 1) +
                tf.expand_dims(tf.cast(simplex_vertices[:, 1, 2], tf.int32), 1)), 1)), 1)
    ) % 12
    gi3s = tf.gather_nd(
        perm,
        tf.expand_dims(masked_skewed_vectors[:, 0], 1) +
        1 +
        tf.expand_dims(tf.gather_nd(
            perm,
            tf.expand_dims(masked_skewed_vectors[:, 1], 1) +
            1 +
            tf.expand_dims(tf.gather_nd(
                perm,
                tf.expand_dims(masked_skewed_vectors[:, 2], 1) +
                1), 1)), 1)
    ) % 12
    n0s = calculate_gradient_contribution(offsets_0, gi0s, grad3, length)
    n1s = calculate_gradient_contribution(offsets_1, gi1s, grad3, length)
    n2s = calculate_gradient_contribution(offsets_2, gi2s, grad3, length)
    n3s = calculate_gradient_contribution(offsets_3, gi3s, grad3, length)
    return 23.0 * tf.squeeze(
        tf.expand_dims(n0s, 1) + tf.expand_dims(n1s, 1) + tf.expand_dims(n2s, 1) + tf.expand_dims(n3s, 1))

def calculate_image(noise_values, phases, shape):
    val = tf.floor((tf.add_n(tf.split(
        tf.reshape(noise_values, [shape[0], shape[1], phases]) / tf.pow(
            2.0,
            tf.linspace(0.0, float(phases) - 1., phases)), phases, 2)) + 1.0) * 128.)
    return tf.concat([val, val, val], 2)


class Solution:
    def rotate(self, nums: list, k: int) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        k = k % len(nums)
        for i in range(0, k):
            tmp = nums[-1]
            for j in range(0, len(nums) - 1):
                nums[len(nums) - 1 - j] = nums[len(nums) - 2 - j]
            nums[0] = tmp

    def rotate1(self, nums, k):
        if k is None or k <= 0:
            return
        k, end = k % len(nums), len(nums) - 1
        self.reverse(nums, 0, end - k)
        self.reverse(nums, end - k + 1, end)
        self.reverse(nums, 0, end)

    def reverse(self, nums, start, end):
        while start < end:
            nums[start], nums[end] = nums[end], nums[start]
            start, end = start + 1, end - 1

    def rotate2(self, nums, k):
        copy = nums.copy()
        for i in range(len(nums)):
            nums[i] = copy[(i-k) % len(nums)]

if __name__ == '__main__':
    print(Solution().rotate1([1, 2, 3, 4, 5, 6, 7], 3))


import random
from turtle import color
import pygame
width=600
height=500
window=pygame.display.set_mode((width,height))
pixel=50
player_x=width/2-pixel
player_y=450-pixel
player_xchange=0
ball_x=width/2-pixel
ball_y=height/2-pixel
ball_xchange=random.choice((1,-1))
vel=2
color='white'
ball_ychange=1
def collision():
    global ball_xchange
    global ball_ychange
    if player_y <(ball_y+pixel):
        if player_x > ball_x and player_x+pixel <ball_x+pixel or player_x+pixel>ball_x and player_x+pixel<ball_x+pixel:
            ball_xchange*=-1
            ball_ychange*=-1
run=True
while run:
    window.fill(color)
    # window.blit(text_1,)
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            run=False
    if ball_x>=width or ball_x<=0:
        ball_xchange*=-1
    if ball_y>=height or ball_y<=0:
        ball_ychange*=-1
    ball_x+=ball_xchange
    ball_y+=ball_ychange
    pygame.draw.circle(window,'red',(ball_x,ball_y),10)

    key=pygame.key.get_pressed()
    if key[pygame.K_LEFT] and player_x>0:
        player_x-=vel
    if key[pygame.K_RIGHT] and player_x<600-100:
        player_x+=vel
    pygame.draw.rect(window,'red',(player_x,player_y,100,30))
    collision()
    if ball_y==height:
        pygame.display.quit()
    # print(ball_x,ball_y)
    pygame.display.update()


from transformers import MBartForConditionalGeneration, MBart50TokenizerFast

model = MBartForConditionalGeneration.from_pretrained("facebook/mbart-large-50-one-to-many-mmt")
tokenizer = MBart50TokenizerFast.from_pretrained("facebook/mbart-large-50-one-to-many-mmt", src_lang="en_XX" )

class txt2translate:
    def txt2translate(ref,text,language):
        article_en = text
        model_inputs = tokenizer(article_en, return_tensors="pt")
        generated_tokens = model.generate(**model_inputs, forced_bos_token_id=tokenizer.lang_code_to_id[language+"_IN"])
        translation = tokenizer.batch_decode(generated_tokens, skip_special_tokens=True)
        # print(translation[0])
        translated = translation[0]
        return translated

# og = txt2translate()
# txt = "How are you ?"
# gt = og.txt2translate(txt)


from typing import Iterator

from tqdm import tqdm

from datalabs.operations.aggregate import Aggregating, aggregating

class KGLinkPredictionAggregating(Aggregating):
    def __init__(self, *args, **kwargs):

        super(KGLinkPredictionAggregating, self).__init__(*args, **kwargs)
        self._data_type = "ag_news"

class kg_link_prediction_aggregating(aggregating):
    def __init__(self, *args, **kwargs):

        super(kg_link_prediction_aggregating, self).__init__(*args, **kwargs)
        # print(self.__dict__)

    def __call__(self, *param_arg):
        if callable(self.name):

            tf_class = KGLinkPredictionAggregating(
                name=self.name.__name__, func=self.name
            )
            return tf_class(*param_arg)
        else:
            f = param_arg[0]
            name = self.name or f.__name__
            tf_cls = KGLinkPredictionAggregating(
                name=name,
                func=f,
                resources=self.resources,
                contributor=self.contributor,
                task=self.task,
                description=self.description,
            )
            return tf_cls

"""
from datalabs import load_dataset
dataset = load_dataset('./ag_news')
from ag_news.featurize import *
get_number_of_tokens.__dict__
res = dataset['test'].apply(get_number_of_tokens)
print(next(res))
"""

@kg_link_prediction_aggregating(
    name="get_statistics",
    contributor="datalab",
    task="kg-link-prediction",
    description="aggregation function",
)
def get_statistics(samples: Iterator):
    dict_head = {}
    dict_link = {}
    dict_tail = {}

    for sample in tqdm(samples):

        if sample["tail"] not in dict_tail.keys():
            dict_tail[sample["tail"]] = 1
        else:
            dict_tail[sample["tail"]] += 1

        if sample["head"] not in dict_head.keys():
            dict_head[sample["head"]] = 1
        else:
            dict_head[sample["head"]] += 1

        if sample["link"] not in dict_link.keys():
            dict_link[sample["link"]] = 1
        else:
            dict_link[sample["link"]] += 1

    return {
        "head_fre": dict_head,
        "link_fre": dict_link,
        "tail_fre": dict_tail,
    }


fname = 'Cap 10\mbox-short.txt'

file = open(fname)

emails = dict()

for line in file:
    words = line.split()
    if len(words) > 0 and words[0] == 'From':
        emails[words[1]] = emails.get(words[1], 0) + 1

lst_emails = list()
#lst_emails = list(emails.items())
for email, contador in list(emails.items()):
    lst_emails.append((contador, email))

lst_emails.sort(reverse=True)

for contador, email in lst_emails[:1]:
    print(contador, email)


try:
	from setuptools import setup
except ImportError:
	from distutils.core import setup

config = {
	'description': 'Psyduck Encrypted Chat',
	'author': '12CSSXX',
	'url': 'https://github.com/zishanAhmad/psyduck',
	'download_url': 'https://github.com/zishanAhmad/psyduck',
	'author_email': 'zishanrbp@gmail.com',
	'version': '0.1',
	'install_requires': ['nose'],
	'packages': ['PSYDUCK'],
	'scripts': [],
	'name': 'psyduck'
}

setup(**config)


import requests
def main():
    cep = input("Digite o Cep para consulta: ")
    if len(cep) != 8:
        print("quantidade de digitos inválido")
        main()

    request = requests.get('https://viacep.com.br/ws/{}/json/'.format(cep))
    endereco = request.json()

    if 'erro' not in endereco:
        print(" ==> Cep Encontrado <==")
        print("-"*20)
        print('CEP: {}'.format(endereco['cep']))
        print('Rua: {}'.format(endereco['logradouro']))
        print('Bairro: {}'.format(endereco['bairro']))
        print('Cidade: {}'.format(endereco['localidade']))
        print('Estado: {}'.format(endereco['uf']))
    else:
        print("{}: Cep invalido".format(cep))
    opcao = int(input("deseja realizar uma nova consulta?\n1. Sim\n2. Sair\n"))

    if opcao == 1:
        main()
    else:
        print('saindo...')
if __name__ == "__main__":
    main()


from skimage.io import imread,imsave
import os, glob
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
day = '2012.10.17'
rl = '3R1'
filename = '/media/xuan/SP PHD U3/project/PROJECT/project/GT/slight/'+day+'/'+ rl +'/'
save_path = '/media/xuan/SP PHD U3/project/PROJECT/project/testgt/'
#filename1 = 'C:/Users/tommy/Desktop/AMDc/noextended/Non-AMD/'
file = []
file.append(filename)
#file.append(filename1)
X,y = [], []
for i in file:
    X.append(glob.glob(i + '/'+ '*.bmp'))
X = X[0]
for j in X:
    y.append((j.split('/')[-1]))
l = len(y)
c = 512
for i in range (0,l):
#    gt = imread(filename+'{}'.format(y[i]))
    ori = imread('/media/xuan/SP PHD U3/project/PROJECT/project/GT/slight/'+day+'/'+ rl +'/'+ y[i])
    imsave(save_path+'slight_'+str(c)+'.bmp', ori )
#    imsave(save_path+str(c) +'/masks_serious/'+str(c)+'.bmp', gt )
    c = c+1


import os
import tempfile
import shutil
import errno

def create_temp_folder():
    temp_folder = tempfile.mkdtemp(prefix='germanium_', suffix='install')

    def temp(subpath=''):
        return os.path.join(temp_folder, subpath)

    return temp

def get_germanium_folder(germanium_home):
    def ge_folder(subpath=''):
        return os.path.join(germanium_home, subpath)

    return ge_folder

def get_desktop_folder():
    home_folder = os.environ['USERPROFILE']

    def desktop_folder(subpath=''):
        return os.path.join(home_folder, 'Desktop', subpath)

    return desktop_folder

def mkdir_p(path):
    try:
        os.makedirs(path)
    except OSError as exc:
        if exc.errno == errno.EEXIST and os.path.isdir(path):
            pass
        else:
            raise

def rm_rf(*paths):
    for path in paths:
        if os.path.isdir(path) and not os.path.islink(path):
            shutil.rmtree(path)
        elif os.path.exists(path):
            os.remove(path)

def create_desktop_link(title, application, icon=None, workdir=None):
    desktop_folder = get_desktop_folder()

    if not icon:
        icon = application

    if not workdir:
        workdir = os.path.dirname(application)

    path = desktop_folder("%s.lnk" % title)

    try:
        from win32com.client import Dispatch

        shell = Dispatch('WScript.Shell')
        shortcut = shell.CreateShortCut(path)
        shortcut.Targetpath = application
        shortcut.WorkingDirectory = workdir
        shortcut.IconLocation = icon
        shortcut.save()
    except ImportError as e:
        pass


from __future__ import print_function

import json
import logging

import argparse
from tabulate import tabulate

from courseraresearchexports.exports import api
from courseraresearchexports.constants.api_constants import \
    ANONYMITY_LEVEL_COORDINATOR, EXPORT_TYPE_CLICKSTREAM, \
    EXPORT_TYPE_TABLES, SCHEMA_NAMES
from courseraresearchexports.models.ClickstreamDownloadLinksRequest import \
    ClickstreamDownloadLinksRequest
from courseraresearchexports.models.ExportRequest import ExportRequest
from courseraresearchexports.exports import utils

def request_clickstream(args):
    """
    Create and send an clickstream data export request with Coursera. Only
    available for data coordinators.
    """
    export_request = ExportRequest.from_args(
        course_id=args.course_id,
        course_slug=args.course_slug,
        partner_id=args.partner_id,
        partner_short_name=args.partner_short_name,
        group_id=args.group_id,
        anonymity_level=ANONYMITY_LEVEL_COORDINATOR,
        statement_of_purpose=args.purpose,
        export_type=EXPORT_TYPE_CLICKSTREAM,
        interval=args.interval,
        ignore_existing=args.ignore_existing)

    export_request_with_metadata = api.post(export_request)[0]

    logging.info('Successfully created clickstream export request {id}.'
                 .format(id=export_request_with_metadata.id))
    logging.debug('Request created with json body:\n{json}'
                  .format(json=json.dumps(
                      export_request_with_metadata.to_json(), indent=2)))

def request_tables(args):
    """
    Create and send a tables data export request with Coursera.
    """
    export_request = ExportRequest.from_args(
        course_id=args.course_id,
        course_slug=args.course_slug,
        partner_id=args.partner_id,
        partner_short_name=args.partner_short_name,
        group_id=args.group_id,
        user_id_hashing=args.user_id_hashing,
        statement_of_purpose=args.purpose,
        export_type=EXPORT_TYPE_TABLES,
        schema_names=args.schemas)

    export_request_with_metadata = api.post(export_request)[0]

    logging.info('Successfully created tables export request {id}.'
                 .format(id=export_request_with_metadata.id))
    logging.debug('Request created with json body:\n{json}'
                  .format(json=json.dumps(
                      export_request_with_metadata.to_json(), indent=2)))

def get(args):
    """
    Get the details and status of a data export request using a job id.
    """
    export_request = api.get(args.id)[0]

    export_request_info = [
        ['Export Job Id:', export_request.id],
        ['Export Type:', export_request.export_type_display],
        ['Status:', export_request.status],
        ['Scope Context:', export_request.scope_context],
        ['Scope Id:', export_request.scope_id],
        ['Scope Name:', export_request.scope_name],
        ['User id Hashing: ', export_request.formatted_anonymity_level],
        ['Created:', export_request.created_at.strftime('%c')]]

    if export_request.schema_names:
        export_request_info.append(
            ['Schemas:', export_request.schema_names_display])

    if export_request.download_link:
        export_request_info.append(
            ['Download Link:', export_request.download_link])

    if export_request.interval:
        export_request_info.append(
            ['Interval:', ' to '.join(export_request.interval)])

    print(tabulate(export_request_info, tablefmt="plain"))

def get_all(args):
    """
    Get the details and status of your data export requests.
    """
    export_requests = api.get_all()

    export_requests_table = [['Created', 'Request Id', 'Status', 'Type',
                              'User Id Hashing', 'Scope', 'Schemas']]
    for export_request in sorted(export_requests, key=lambda x: x.created_at):
        export_requests_table.append([
            export_request.created_at.strftime('%Y-%m-%d %H:%M'),
            export_request.id,
            export_request.status,
            export_request.export_type_display,
            export_request.formatted_anonymity_level,
            export_request.scope_id,
            export_request.schema_names_display])

    print(tabulate(export_requests_table, headers='firstrow'))

def download(args):
    """
    Download a data export job using a request id.
    """
    try:
        export_request = api.get(args.id)[0]
        dest = args.dest
        utils.download(export_request, dest)
    except Exception as err:
        logging.error('Download failed with exception:\n{}'.format(err))
        raise

def get_clickstream_links(args):
    """
    Generate links for clickstream data exports
    """
    clickstream_links_request = ClickstreamDownloadLinksRequest.from_args(
        course_id=args.course_id,
        course_slug=args.course_slug,
        partner_id=args.partner_id,
        partner_short_name=args.partner_short_name,
        group_id=args.group_id,
        interval=args.interval)

    clickstream_download_links = api.get_clickstream_download_links(
        clickstream_links_request)

    # TODO: add more descriptive information or option write to text file
    print(tabulate(
        [[link] for link in clickstream_download_links],
        tablefmt="plain"))

def parser(subparsers):
    parser_jobs = subparsers.add_parser(
        'jobs',
        help='Get status of current/completed research export job(s)',
        description='Command line tools for requesting and reviewing the '
        'status of Coursera research data exports. Please first authenticate '
        'with the OAuth2 client before making requests (courseraoauth2client '
        'config authorize --app manage-research-exports).',
        epilog='Please file bugs on github at: '
        'https://github.com/coursera/courseraresearchexports/issues. If you '
        'would like to contribute to this tool\'s development, check us out '
        'at: https://github.com/coursera/courseraresarchexports')

    jobs_subparsers = parser_jobs.add_subparsers()

    create_request_parser(jobs_subparsers)

    parser_get_all = jobs_subparsers.add_parser(
        'get_all',
        help=get_all.__doc__,
        description=get_all.__doc__)
    parser_get_all.set_defaults(func=get_all)

    parser_get = jobs_subparsers.add_parser(
        'get',
        help=get.__doc__,
        description=get.__doc__)
    parser_get.set_defaults(func=get)

    parser_get.add_argument(
        'id',
        help='Export request ID')

    parser_download = jobs_subparsers.add_parser(
        'download',
        help=download.__doc__,
        description=download.__doc__)
    parser_download.set_defaults(func=download)

    parser_download.add_argument(
        'id',
        help='Export request ID')

    parser_download.add_argument(
        '--dest',
        default='.',
        help='Destination folder')

    parser_clickstream_links = jobs_subparsers.add_parser(
        'clickstream_download_links',
        help='Get download links for completed eventing exports.')
    parser_clickstream_links.set_defaults(func=get_clickstream_links)

    create_scope_subparser(parser_clickstream_links)

    parser_clickstream_links.add_argument(
        '--interval',
        nargs=2,
        metavar=('START', 'END'),
        help='Interval of exported clickstream data, inclusive. '
        '(i.e. 2016-08-01 2016-08-04).')

    return parser_jobs

def create_scope_subparser(parser):
    scope_subparser = parser.add_mutually_exclusive_group(
        required=True)
    scope_subparser.add_argument(
        '--course_id',
        help='Export rows corresponding to learners within a course according '
        'to the unique id assigned by Coursera.')
    scope_subparser.add_argument(
        '--course_slug',
        help='Export rows corresponding to learners within a course according '
        'to the unique name of your course defined as the part after '
        '/learn in the course url. (e.g. machine-learning for '
        'https://www.coursera.org/learn/machine-learning).')
    scope_subparser.add_argument(
        '--partner_id',
        type=int,
        help='Export rows corresponding to learners within a partner.')
    scope_subparser.add_argument(
        '--partner_short_name',
        help='Export rows corresponding to learners within a partner.')
    scope_subparser.add_argument(
        '--group_id',
        help='Export rows corresponding to learners without a group.')

def create_request_parser(subparsers):
    parser_request = subparsers.add_parser(
        'request',
        help='Create and send a data export request with Coursera.',
        description='Create and send a data export request with Coursera. '
        'Use subcommands to specify the export request type.')
    request_subparsers = parser_request.add_subparsers()

    # common arguments between schema and eventing exports
    request_args_parser = argparse.ArgumentParser(add_help=False)

    create_scope_subparser(request_args_parser)

    request_args_parser.add_argument(
        '--purpose',
        required=True,
        help='Please let us know how you plan to use the '
        'data, what types of research questions you\'re asking, who will '
        'be working with the data primarily, and with whom you plan to '
        'share it.')

    # tables subcommand
    parser_tables = request_subparsers.add_parser(
        'tables',
        help=request_tables.__doc__,
        description=request_tables.__doc__,
        parents=[request_args_parser])
    parser_tables.set_defaults(func=request_tables)

    parser_tables.add_argument(
        '--user_id_hashing',
        choices=['linked', 'isolated'],
        default='isolated',
        help='The level of user_id hashing in the data export. With \'linked\''
        ' user_id hashing, users can be identified between table schemas. '
        'With \'isolated\' user_id hashing, users have independent ids in'
        'different schemas and cannot be linked. Only data coordinators have '
        'access to \'linked\' users_ids to restrict PII.')

    parser_tables.add_argument(
        '--schemas',
        choices=SCHEMA_NAMES,
        nargs='+',
        default=SCHEMA_NAMES,
        help='Data schemas to export. Any combination of: {}. By default this '
        'will be all available schemas.'.format(
            ', '.join(SCHEMA_NAMES)))

    # clickstream subcommand
    parser_clickstream = request_subparsers.add_parser(
        'clickstream',
        help=request_clickstream.__doc__,
        description=request_clickstream.__doc__,
        parents=[request_args_parser])
    parser_clickstream.set_defaults(func=request_clickstream)

    parser_clickstream.add_argument(
        '--interval',
        nargs=2,
        metavar=('START', 'END'),
        help='Interval of clickstream data to be exported '
        '(i.e. 2016-08-01 2016-08-04). By default this will be the past day.')

    parser_clickstream.add_argument(
        '--ignore_existing',
        action='store_true',
        help='If flag is set, we will recompute clickstream data for all dates'
        'in the interval. Otherwise, previously computed days are skipped.')


def visualizza_listino(articoli, prezzi):
    for i in range(len(articoli)):
        articolo, prezzo = articoli[i], prezzi[i]
        print("{}: €{}".format(articolo, prezzo))

def visualizza_ordine(articoli, prezzi, ordine):
    totale_ordine = 0
    for i in range(len(articoli)):
        quantità = ordine[i]
        if quantità > 0:
            articolo = articoli[i]
            prezzo = prezzi[i]
            prezzo_totale = quantità * prezzo
            print("Articolo: {}, prezzo €{}, quantità: {}. Totale {}".format(articolo, prezzo, quantità, prezzo_totale))
            totale_ordine += prezzo_totale

    print("Totale ordine: €{}".format(totale_ordine))

articoli = ["Pinza", "Martello", "Trapano", "Chiodo", "Vite"]
prezzi = [15, 10, 70, 0.1, 0.2]
#visualizza_listino(articoli, prezzi)

ordine = [1, 2, 1, 10, 10]
visualizza_ordine(articoli, prezzi, ordine)


import numpy as np
import sys
import math
from colors import colors
import random
import copy

LIGNES = 6
COLONNES = 7
PLAYER_ONE = 1
PLAYER_AI = 2
IA_COMMENTAIRES = ["Tu peux faire mieux!","Mauvais choix...","Tu t'améliores...","C'est bien trop facile","Je m'ennuie","Oh non!","Les humains sont tellement bêtes...","N'essaye pas de me battre","Est-ce que je t'ai déjà dit que j'étais champion du monde?","Tu devrais peut-être te mettre au morpion, tu aurais peut-être plus de chances","C'est tout ce que tu peux faire?","Décevant..."]

'''
ANCHOR function tableau()
REVIEW creating a tab with numpy module
'''
def tableau():
	tableau = np.zeros((LIGNES,COLONNES))
	return tableau

'''
ANCHOR function addPiece()
REVIEW adding player piece into a position
NOTE
@tableau
@ligne
@column
@playerPiece : PLAYER_ONE or PLAYER_AI
'''
# playerPiece is either 1 or 2
def addPiece(tableau, ligne, column, playerPiece):
	# TODO add color for last piece
	tableau[ligne][column] = playerPiece

'''
ANCHOR function estPosition()
REVIEW checking if position is empty
NOTE
@tableau
@column
'''
def estPosition(tableau, column):
	# Checking if position is empty
	return tableau[LIGNES-1][column] == 0
	# - 1 cause array starts at 0

'''
ANCHOR function getLigne()
REVIEW for a given column, check what's the current line available
NOTE
@tableau
@column
'''
def getLigne(tableau, column):
	# We check in A SPECIFIC column what's the current line
	for l in range(LIGNES):
		if tableau[l][column] == 0:
			return l

'''
ANCHOR function isGagnant()
REVIEW checking for a winning position
NOTE
@tableau
@playerPiece : PLAYER_ONE or PLAYER_AI
'''
def isGagnant(tableau, playerPiece):
	for c in range(COLONNES-3): # Check horizontal
		for l in range(LIGNES):
			if tableau[l][c] == playerPiece and tableau[l][c+1] == playerPiece and tableau[l][c+2] == playerPiece and tableau[l][c+3] == playerPiece:
				return True

	for c in range(COLONNES): # Check vertical
		for l in range(LIGNES-3):
			if tableau[l][c] == playerPiece and tableau[l+1][c] == playerPiece and tableau[l+2][c] == playerPiece and tableau[l+3][c] == playerPiece:
				return True

	for c in range(COLONNES-3): # check / diagonale
		for l in range(LIGNES-3):
			if tableau[l][c] == playerPiece and tableau[l+1][c+1] == playerPiece and tableau[l+2][c+2] == playerPiece and tableau[l+3][c+3] == playerPiece:
				return True

	for c in range(COLONNES-3): # check \ diagonale
		for l in range(3, LIGNES):
			if tableau[l][c] == playerPiece and tableau[l-1][c+1] == playerPiece and tableau[l-2][c+2] == playerPiece and tableau[l-3][c+3] == playerPiece:
				return True

"""
ANCHOR positionsValides()
REVIEW we're looking for available positions into the Tab
NOTE
@tableau
"""
def positionsValides(tableau):
	pos = []
	for c in range(COLONNES):
		if estPosition(tableau,c):
			pos.append(c)
	return pos

"""
ANCHOR scorePos()
REVIEW getting score per position
NOTE
@tableau
@piece : PLAYERPIECE
"""
def scorePos(tableau, piece):
	score = 0
	puissance = 4
	## Score center column
	center_array = [int(i) for i in list(tableau[:, COLONNES//2])]
	center_count = center_array.count(piece)
	score += center_count * 3

	## Score Horizontal
	for r in range(LIGNES):
		row_array = [int(i) for i in list(tableau[r,:])] # Get row as []
		for c in range(COLONNES-3):
			window = row_array[c:c+puissance] # de n° colonne à taille de Puissance (4)
			score += getScore(window, piece)

	## Score Vertical
	for c in range(COLONNES):
		col_array = [int(i) for i in list(tableau[:,c])] # Get colonne as []
		for r in range(LIGNES-3):
			window = col_array[r:r+puissance]
			score += getScore(window, piece)

	## Score posiive sloped diagonal
	for r in range(LIGNES-3):
		for c in range(COLONNES-3):
			window = [tableau[r+i][c+i] for i in range(puissance)]
			score += getScore(window, piece)

	for r in range(LIGNES-3):
		for c in range(COLONNES-3):
			window = [tableau[r+3-i][c+i] for i in range(puissance)]
			score += getScore(window, piece)

	return score

"""
ANCHOR getScore()
REVIEW for given window (col,row,diagonal...) check the score for best result
NOTE
@window : given array of pieces
@piece : PLAYERPIECE
"""
def getScore(window, piece):
	score = 0
	empty = 0
	opp_piece = PLAYER_ONE
	if piece == PLAYER_ONE:
		opp_piece = PLAYER_AI

	if window.count(piece) == 4: # biggest score
		score += 100
	elif window.count(piece) == 3 and window.count(empty) == 1:
		score += 5
	elif window.count(piece) == 2 and window.count(empty) == 2:
		score += 2

	if window.count(opp_piece) == 3 and window.count(empty) == 1:
		score -= 4

	return score

"""
ANCHOR estTerminal()
REVIEW check if there's a winning pos for either player or no more valid positions
NOTE
@tableau
"""
def estTerminal(tableau):
	return isGagnant(tableau, PLAYER_ONE) or isGagnant(tableau, PLAYER_AI) or len(positionsValides(tableau)) == 0

"""
ANCHOR minmax()
REVIEW use minmax algorithm to simulate AI thinking and get best play
NOTE
@tableau
@profondeur : how far does it have to look for best play
@maxJoueur : maxi player chances
TODO comment inner blocks
FIXME math.inf
"""
def minmax(tableau,profondeur,maxJoueur):
	if profondeur == 0 or estTerminal(tableau):
		if estTerminal(tableau):
			if isGagnant(tableau,PLAYER_AI): # AI
				return (None,100000000)
			if isGagnant(tableau,PLAYER_ONE):
				return (None,-100000000) # None cause no more columns
			else:
				print(str(profondeur) + " " + str(estTerminal))
				return (None,0) # plus de place dans le tableau
		else:
			score = scorePos(tableau,PLAYER_AI)
			return (None,score)
	if maxJoueur:
		val = -math.inf
		col = random.choice(positionsValides(tableau))
		for c in positionsValides(tableau):
			ligne = getLigne(tableau,c)
			copieTab = tableau.copy() # on fait une copie du tableau pour pas vraiment drop une piece
			addPiece(copieTab,ligne,c,PLAYER_AI)
			#print(".")
			newVal = minmax(copieTab,profondeur-1,False)[1]
			#max(val, minmax(copieTab,profondeur-1,False))
			#print(newVal)
			if newVal > val:
				val = newVal
				col = c
		return col, val
	else:
		val = math.inf
		col = random.choice(positionsValides(tableau))
		for c in positionsValides(tableau):
			ligne = getLigne(tableau,c)
			copieTab = tableau.copy()
			addPiece(copieTab,ligne,c,PLAYER_ONE)
			#print("!")
			newVal = minmax(copieTab,profondeur-1,True)[1]
			#print(newVal)
			if newVal < val:
				val = newVal
				col = c
		return col, val

"""
ANCHOR printTab()
REVIEW printing the tab
"""
def printTab(tableau):
	tab = copy.deepcopy(tableau)
	for l in range(LIGNES):
		for c in range(COLONNES):
			if tab[l][c] == 1:
				print("X",end='')
			elif tab[l][c] == 2:
				print("O",end='')
			else:
				print("|",end='')
		print()
	tab = None

tableau = tableau()
print(np.flip(tableau, 0))
gameOver = False
turn = 0

print("TAP 0 at any moment to quit")
opponent = int(input("\nPlay against - Player 2 (tap 0) - AI (tap 1): ").replace(" ",""))
if opponent == 1:
	level = int(input("\n[VERY] Easy (tap 0) - Average (tap 1) - Hard (tap 2): ").replace(" ",""))

while not gameOver:
	if turn == 0:
		print()
		print(colors.bg.red, "PLAYER 1", colors.fg.lightgrey)
		col = int(input("Player 1, make your choice: ").replace(" ",""))
		col -= 1 # we sub 1 because user will think of first column as column 1 not column 0
		if col == -1:
			print(colors.reset)
			exit()
		if estPosition(tableau, col): # check if position is available
			row = getLigne(tableau, col)
			addPiece(tableau, row, col, 1)

			if isGagnant(tableau, 1):
				gameOver = True
				print("Player 1 a gagné!")
		else:
			print("Tu vois bien qu'il n'y a plus de place dans cette colonne...")
			continue
		turn = 1

	else:
		if random.randint(0,1):
			print("AI: "+random.choice(IA_COMMENTAIRES))
		if opponent != 0:
			if level == 0:
				col, value = random.choice(positionsValides(tableau)), None
			if level == 1:
				if not random.randint(0,3):
					print("AI: Oh non j'ai fait une erreur!")
					col , value = random.choice(positionsValides(tableau)), None
				else:
					col, value = minmax(tableau,2,True)
			else:
				col, value = minmax(tableau, 5, True)
			print("\nAI choosed column: "+str(col+1))
		else:
			print(colors.bg.blue, "PLAYER 2", colors.fg.lightgrey)
			col = int(input("Player 2, make your choice: "))
			col -= 1
			if col == -1:
				print(colors.reset)
				exit()
		if estPosition(tableau, col):
			row = getLigne(tableau, col)
			addPiece(tableau, row, col, 2)

			if isGagnant(tableau, 2):
				gameOver = True
				print("AI a gagné!")
		turn = 0

	print(np.flip(tableau, 0))
	print(colors.reset)
	#printTab(tableau)


import theano
import theano.tensor as T
from theano.sandbox.cuda.basic_ops import (as_cuda_ndarray_variable,
                                           host_from_gpu,
                                           gpu_contiguous, HostFromGpu,
                                           gpu_alloc_empty)
from theano.sandbox.cuda.dnn import GpuDnnConvDesc, GpuDnnConv, GpuDnnConvGradI, dnn_conv, dnn_pool
from theano.sandbox.rng_mrg import MRG_RandomStreams as RandomStreams

from .rng import t_rng

def l2normalize(x, axis=1, e=1e-8, keepdims=True):
    return x / l2norm(x, axis=axis, e=e, keepdims=keepdims)

def l2norm(x, axis=1, e=1e-8, keepdims=True):
    return T.sqrt(T.sum(T.sqr(x), axis=axis, keepdims=keepdims) + e)

def cosine(x, y):
    d = T.dot(x, y.T)
    d /= l2norm(x).dimshuffle(0, 'x')
    d /= l2norm(y).dimshuffle('x', 0)
    return d

def euclidean(x, y, e=1e-8):
    xx = T.sqr(T.sqrt((x * x).sum(axis=1) + e))
    yy = T.sqr(T.sqrt((y * y).sum(axis=1) + e))
    dist = T.dot(x, y.T)
    dist *= -2
    dist += xx.dimshuffle(0, 'x')
    dist += yy.dimshuffle('x', 0)
    dist = T.sqrt(dist)
    return dist

def dropout(X, p=0.):
    """
    dropout using activation scaling to avoid test time weight rescaling
    """
    if p > 0:
        retain_prob = 1 - p
        X *= t_rng.binomial(X.shape, p=retain_prob, dtype=theano.config.floatX)
        X /= retain_prob
    return X

def conv_cond_concat(x, y):
    """
    concatenate conditioning vector on feature map axis
    """
    return T.concatenate([x, y * T.ones((x.shape[0], y.shape[1], x.shape[2], x.shape[3]))], axis=1)

def batchnorm(X, g=None, b=None, u=None, s=None, a=1., e=1e-8):
    """
    batchnorm with support for not using scale and shift parameters
    as well as inference values (u and s) and partial batchnorm (via a)
    will detect and use convolutional or fully connected version
    """
    if X.ndim == 4:
        if u is not None and s is not None:
            b_u = u.dimshuffle('x', 0, 'x', 'x')
            b_s = s.dimshuffle('x', 0, 'x', 'x')
        else:
            b_u = T.mean(X, axis=[0, 2, 3]).dimshuffle('x', 0, 'x', 'x')
            b_s = T.mean(T.sqr(X - b_u), axis=[0, 2, 3]).dimshuffle('x', 0, 'x', 'x')
        if a != 1:
            b_u = (1. - a) * 0. + a * b_u
            b_s = (1. - a) * 1. + a * b_s
        X = (X - b_u) / T.sqrt(b_s + e)
        if g is not None and b is not None:
            X = X * g.dimshuffle('x', 0, 'x', 'x') + b.dimshuffle('x', 0, 'x', 'x')
    elif X.ndim == 2:
        if u is None and s is None:
            u = T.mean(X, axis=0)
            s = T.mean(T.sqr(X - u), axis=0)
        if a != 1:
            u = (1. - a) * 0. + a * u
            s = (1. - a) * 1. + a * s
        X = (X - u) / T.sqrt(s + e)
        if g is not None and b is not None:
            X = X * g + b
    else:
        raise NotImplementedError
    return X

def deconv(X, w, subsample=(1, 1), border_mode=(0, 0), conv_mode='conv'):
    """
    sets up dummy convolutional forward pass and uses its grad as deconv
    currently only tested/working with same padding
    """
    img = gpu_contiguous(X)
    kerns = gpu_contiguous(w)
    desc = GpuDnnConvDesc(border_mode=border_mode, subsample=subsample,
                          conv_mode=conv_mode)(gpu_alloc_empty(img.shape[0], kerns.shape[1], img.shape[2] * subsample[0], img.shape[3] * subsample[1]).shape, kerns.shape)
    out = gpu_alloc_empty(img.shape[0], kerns.shape[1], img.shape[2] * subsample[0], img.shape[3] * subsample[1])
    d_img = GpuDnnConvGradI()(kerns, img, out, desc)
    return d_img


class Parser:

    _COMMAND_TYPES = {
        v: k for k, vs in {
            "C_ARITHMETIC": ["add", "sub", "neg", "eq", "gt", "lt", "and", "or", "not"],
            "C_PUSH": ["push"],
            "C_POP": ["pop"],
            "C_LABEL": ["label"],
            "C_GOTO": ["goto"],
            "C_IF": ["if-goto"],
            "C_CALL": ["call"],
            "C_FUNCTION": ["function"],
            "C_RETURN": ["return"],
            }.items() for v in vs
    }

    def __init__(self, vm_lines):
        self.vm_lines = self._preprocess(vm_lines)
        self.current_line_id = -1

    def _preprocess(self, lines):
        lines =  [
            line[:line.find("//")].strip() if "//" in line else line. replace("\r", "").replace("\n", "")
            for line in lines if not line.startswith("//")
        ]
        return [line.strip() for line in lines if line]

    def has_more_commands(self):
        return (self.current_line_id < len(self.vm_lines) - 1)

    def advance(self):
        self.current_line_id += 1

    def command_type(self):
        return self._COMMAND_TYPES[self.vm_lines[self.current_line_id].split()[0]]

    def arg1(self):
        if self.command_type() == "C_ARITHMETIC":
            return self.vm_lines[self.current_line_id].split()[0]
        elif self.command_type() in ["C_PUSH", "C_POP", "C_LABEL", "C_GOTO", "C_IF", "C_CALL", "C_FUNCTION"]:
            return self.vm_lines[self.current_line_id].split()[1]
        else:
            raise NotImplementedError(f"Arg 1 not implemented for other functions! Input line was {self.vm_lines[self.current_line_id]}")

    def arg2(self):
        if self.command_type() == "C_ARITHMETIC":
            raise ValueError("No arg 2 for arithmetic commands!!")
        elif self.command_type() in ["C_PUSH", "C_POP", "C_CALL", "C_FUNCTION"]:
            return int(self.vm_lines[self.current_line_id].split()[2])
        else:
            raise NotImplementedError(f"Arg 2 not implemented for other functions! Input line was {self.vm_lines[self.current_line_id]}")