import os
import sys
import sqlite3
import numpy as np
import pandas as pd
import textwrap
from util.datamanage import fwrite

pd.set_option('display.min_rows', 30)
pd.set_option('display.max_rows', 30)
pd.set_option('display.max_columns', 20)
pd.set_option('display.width', 400)

# User-Scheme のテーブルを作成する
def create_US_table(filename, work_id):
    # index: user (一度も工夫を採用したことのないユーザは除く)
    # Column: scheme (一度も採用されたことのない工夫は除く)
    dbname = filename
    conn = sqlite3.connect(dbname)
    cur = conn.cursor()

    # 各ユーザごとに処理をループ
    # Users df (without duplicates)
    Users = pd.read_sql(
        f"""
            SELECT id , name
            FROM Users
            GROUP BY id, name
            ORDER BY id
        """ ,conn)

    # UsersWorks df without duplicates
    UsersWorks = pd.read_sql(
        f"""
            SELECT id, UserId, WorkId
            FROM UsersWorks
            WHERE WorkId = {work_id}
            GROUP BY UserId, WorkId
        """, conn)

    # UsersSchemes df without duplicates
    UsersSchemes = pd.read_sql(
        f"""
            SELECT UsersWorkId , SchemeId
            FROM UsersSchemes
            GROUP BY UsersWorkId, SchemeId
            ORDER BY SchemeId
        """, conn)

    # Schemes_during_use df without duplicates
    Schemes_during_use = pd.read_sql(
        f"""
            SELECT SchemeId
            FROM UsersSchemes
            GROUP BY SchemeId
            ORDER BY SchemeId
        """, conn)

    # Schemes df without duplicates
    Schemes = pd.read_sql(
        f"""
            SELECT id, label
            FROM Schemes
            GROUP BY id, label
            ORDER BY id
        """, conn)

    # UsersWorks - UsersSchemes でINNER JOIN
    # UsersWork-UsersSchemes df without duplicates
    uw_us = pd.merge(UsersWorks, UsersSchemes, left_on="id", right_on="UsersWorkId").drop(columns=['id', 'UsersWorkId'])

    # User - Scheme の行列を作成
    schemes_labels = Schemes[Schemes['id'].isin(Schemes_during_use['SchemeId'])]['label']
    users_ids = Users[Users['id'].isin(uw_us['UserId'])]['id']
    User_Scheme_matrix = pd.DataFrame(index=users_ids.to_numpy(), columns=schemes_labels.to_numpy())

    # 行列の値を計算
    for id in User_Scheme_matrix.index:
        users_schemes = uw_us.loc[uw_us['UserId'] == id, 'SchemeId']
        User_Scheme_matrix.loc[id] = Schemes_during_use['SchemeId'].isin(users_schemes).values * 1
    cur.close()
    conn.close()
    return User_Scheme_matrix

"""
    ユーザに工夫を推薦する
    引数：
        matrix:
            pandas Dataframe型の(User x Scheme)行列
            index: schemes name, column: user id
            工夫の採用有無を表現する（採用していれば1, していなければ0)
        user_id:
            推薦を受け取る対象ユーザのuser id
    戻り値：
        推薦を受け取る対象ユーザの未採用工夫に対する予測評価付き配列
"""
def recommend(matrix, user_id):
    # 推薦を受け取る対象ユーザの列を取得
    u_i = matrix[user_id]
    others = matrix.drop(columns=user_id)
    s_i_others = pd.Series(name="similarity")
    # 対象ユーザとその他ユーザとの類似度を計算

    #(おまけ)自身との類似度も出してみる
    # myself = pd.concat([u_i,u_i], axis=1)
    # s_myself = myself.corr(method='pearson')
    # s_myself = s_myself.iat[0,1]
    # print(f"me: {s_myself}")
    for _id, u_k in others.items():
        u_ik = pd.concat([u_i, u_k], axis=1)
        s_ik = u_ik.corr(method='pearson')
        s_ik = s_ik.iat[0,1]
        s_i_others[_id] = s_ik

    # 類似したユーザ集合を用意
    threshold = 0.05
    sim_set = s_i_others[s_i_others >= threshold].sort_values(ascending=False)
    # _show = textwrap.indent(sim_set.to_string(), '        ')
    # fwrite(f"similar user set(user id, similarity):\n{_show}\n", end="")

    # 未採用の工夫に対して採用スコアを予測
    # 予測方法は平均による閾値処理（オリジナル）
    predict_values = pd.Series(name="Predicted effect of schemes")
    if sim_set.shape[0] == 0:
        return predict_values
    for index in u_i[u_i == 0].index:
        # print(f"index:{index}")
        others_index_score = others[sim_set.index].loc[index]
        # 単純平均
        mean = others_index_score.mean()
        # print(f"単純平均: {round(mean,3)}")
        # 加重平均
        weight = np.arange(others_index_score.shape[0],0,-1)
        wma = sum(others_index_score * weight) / sum(weight)
        # print(f"加重平均: {round(wma,3)}")
        predict_values[index] = round(wma,3)
    return predict_values.sort_values(ascending=False)

def main(sqlite_path, user_id, work_id):
    try:
        # ユーザ×工夫の行列を取得
        us_table = create_US_table(sqlite_path, work_id)
        # 行列をcsvとして保存
        table_output = "/app/log/user_scheme_matrix.csv"
        us_table.to_csv(table_output)
        fwrite(f"ユーザ×工夫行列を'{table_output}'に保存しました")
        # 推薦を実施
        res_ps = recommend(us_table.T, user_id)
        if res_ps.shape[0] == 0:
            fwrite(f"user id {user_id} におすすめできる工夫が存在しません．")
            return None
        fwrite(f"user id {user_id} におすすめの工夫: {list(res_ps.to_dict().keys())[:10]}")
        return res_ps.to_dict()

    except Exception as e:
        fwrite(e)

if __name__ == "__main__":
    print("Don't exec this program from command line")


#  Q2. Perform the following preprocessing tasks on the dirty_iris dataset.
# i) Calculate the number and percentage of observations that are complete.
# ii) Replace all the special values in data with NA.
# iii) Define these rules in a separate text file and read them.
# (Use editfile function in R (package editrules). Use similar function in Python).
# Print the resulting constraint object.
# – Species should be one of the following values: setosa, versicolor or virginica.
# – All measured numerical properties of an iris should be positive.
# – The petal length of an iris is at least 2 times its petal width.
# – The sepal length of an iris cannot exceed 30 cm.
# – The sepals of an iris are longer than its petals.
# iv)Determine how often each rule is broken (violatedEdits). Also summarize and plot the
# result.
# v) Find outliers in sepal length using boxplot and boxplot.stats

# Solution
import matplotlib.pyplot as plt
import copy

class iris:
    def __init__(self, sepalLength, sepalWidth, petalLength, petalWidth, species):
        self.sepalLength = sepalLength
        self.sepalWidth = sepalWidth
        self.petalWidth = petalWidth
        self.petalLength = petalLength
        self.species = species

    def value(self):
        temp = self.sepalLength + ',' + self.sepalWidth + ',' + \
            self.petalLength + ',' + self.petalWidth + ',' + self.species
        return temp

    def checkConstraiont(self):
        temp = [0, 0, 0, 0, 0]
        speciesValue = ['"setosa"\n', '"versicolor"\n', '"virginica"\n']

        if (self.sepalLength == 'NA' or self.sepalWidth == 'NA' or self.petalLength == 'NA' or self.petalWidth == 'NA'):
            return temp
        if (self.species in speciesValue):
            temp[0] = 0
        else:
            temp[0] = 1

        if (float(self.sepalLength) < 0 or float(self.sepalWidth) < 0 or float(self.petalLength) < 0 or float(self.petalWidth) < 0):
            temp[1] = 1
        if (float(self.petalLength) < 2*float(self.petalWidth)):
            temp[2] = 1
        if (float(self.sepalLength) > 30.0):
            temp[3] = 1
        if (float(self.sepalLength) < float(self.petalLength) or float(self.sepalWidth) < float(self.petalWidth)):
            temp[4] = 1

        return temp

irisList = []
fileLine = []
originalIrisList = []

file = open("dirty_iris.csv", "r")
for x in file:
    fileLine.append(x)

file.close()

for x in range(0, len(fileLine)):
    temp = fileLine[x].split(',')
    irisList.append(iris(temp[0], temp[1], temp[2], temp[3], temp[4]))

originalIrisList = copy.deepcopy(irisList)
irisLength = len(irisList)-1

incompleteData = 0

for x in irisList:
    if (x.sepalLength == "NA" or x.sepalWidth == "NA" or x.petalLength == "NA" or x.petalWidth == "NA" or x.species == "NA"):
        incompleteData = incompleteData + 1

print("Total no. of Data : ", irisLength)
print("No. of Incomplete Data : ", incompleteData)

try:
    print("Percentage of Incomplete Data : ", (incompleteData/irisLength)*100)
except:
    print("File is Empty")

# (ii) part starts Here.

for l in range(0, len(irisList)):
    try:
        if (float(irisList[l].sepalLength) <= 0.000 or irisList[l].sepalLength == 'Inf'):
            irisList[l].sepalLength = "NA"
        if (float(irisList[l].sepalWidth) <= 0.0000 or irisList[l].sepalWidth == 'Inf'):
            irisList[l].sepalWidth = "NA"
        if (float(irisList[l].petalLength) <= 0.0000 or irisList[l].petalLength == 'Inf'):
            irisList[l].petalLength = "NA"
        if (float(irisList[l].petalWidth) <= 0.0000 or irisList[l].petalWidth == 'Inf'):
            irisList[l].petalWidth = "NA"
    except:
        continue

fileWrite = open("dirty_iris.csv", "w")

for l in range(0, len(irisList)):
    fileWrite.write(irisList[l].value())

fileWrite.close()

ruleVoilation = [0, 0, 0, 0, 0]

for l in range(1, len(irisList)):
    result = originalIrisList[l].checkConstraiont()
    for k in range(0, 5):
        ruleVoilation[k] = ruleVoilation[k] + result[k]

print("Species Rule Voilation : " , ruleVoilation[0])
print("Positive Value Rule Voilation : " , ruleVoilation[1])
print("Petal Length Rule Voilation : " , ruleVoilation[2])
print("Sepal Length Rule Voilation : " , ruleVoilation[3])
print("Sepal and Petal Length Rule Voilation : " , ruleVoilation[4])

Options = ["Species Rule Voilation" ,"Positive Value Rule Voilation","Petal Length Rule Voilation","Sepal Length Rule Voilation","Sepal and Petal Length Rule Voilation"]

plt.bar(Options, ruleVoilation, color ='maroon',
        width = 0.4)
plt.ylabel('No. of Rule Voilation')
plt.title("No. of Record : " + str(len(irisList)-1))

plt.show()

sepalLengthList = []

for l in range(1 , len(irisList)):
    try:
     sepalLengthList.append(float(irisList[l].sepalLength))
    except:
        continue

graph = plt.boxplot(sepalLengthList)
plt.title("Sepal Length")
plt.show()
print(graph)


import os

import torch
from torch import nn
from torch.nn import functional as F
from torch.utils.data import DataLoader, random_split

import pytorch_lightning as pl
from pytorch_lightning.metrics.functional import accuracy

# self attention with lstm
class AttentionModel(pl.LightningModule):
    def __init__(self, trial,batch_size,input_dim, output_dim):
        super(AttentionModel, self).__init__()

        self.batch_size = batch_size
        self.input_dim = input_dim
        self.output_dim = output_dim

        self.hidden_dim = 40
        self.recurrent_layers = 2
        self.dropout_p = 0.1

        self.input_embeded = nn.Linear(input_dim, self.hidden_dim//2)
        self.dropout = nn.Dropout(self.dropout_p)
        self.lstm = nn.LSTM(input_size=self.hidden_dim//2, hidden_size=self.hidden_dim, num_layers=self.recurrent_layers,
                            bidirectional=True)

        self.self_attention = nn.Sequential(
            nn.Linear(self.hidden_dim*2, self.hidden_dim*2),
            nn.ReLU(True),
            nn.Linear(self.hidden_dim*2, 1)
        )

        self.scale = 1.0/np.sqrt(self.hidden_dim)

        # initialize LSTM forget gate bias to be 1 as recommanded by http://proceedings.mlr.press/v37/jozefowicz15.pdf
        for names in self.lstm._all_weights:
            for name in filter(lambda n: "bias" in n, names):
                bias = getattr(self.lstm, name)
                n = bias.size(0)
                start, end = n // 4, n // 2
                bias.data[start:end].fill_(1.)

        self.output_linear = nn.Linear(self.hidden_dim * 2, self.hidden_dim)
        self.label = nn.Linear(self.hidden_dim*4, output_dim)

    def forward(self, input_sentences, batch_size=None):
        input = self.dropout(torch.tanh(self.input_embeded(input_sentences)))
        input = input.permute(1, 0, 2)
        if batch_size is None:
            h_0 = Variable(torch.zeros(2*self.recurrent_layers,
                                       self.batch_size, self.hidden_dim).to(device))
            c_0 = Variable(torch.zeros(2*self.recurrent_layers,
                                       self.batch_size, self.hidden_dim).to(device))
        else:
            h_0 = Variable(torch.zeros(2*self.recurrent_layers,
                                       batch_size, self.hidden_dim).to(device))
            c_0 = Variable(torch.zeros(2*self.recurrent_layers,
                                       batch_size, self.hidden_dim).to(device))

        self.lstm.flatten_parameters()

        output, (final_hidden_state, final_cell_state) = self.lstm(
            input, (h_0, c_0))
        output = output.permute(1, 0, 2)

        attn_ene = self.self_attention(output)
        attn_ene = attn_ene.reshape(
            self.batch_size, -1)

        # scale
        attn_ene.mul_(self.scale)
        attns = F.softmax(attn_ene, dim=1).unsqueeze(2)

        final_inputs = (output * attns).sum(dim=1)
        final_inputs2 = output.sum(dim=1)

        combined_inputs = torch.cat([final_inputs, final_inputs2], dim=1)
        logits = self.label(combined_inputs)

        return logits

    def training_step(self, batch, batch_idx):
        x, y = batch
        logits = self(x)
        loss = F.nll_loss(logits, y)
        return loss

    def validation_step(self, batch, batch_idx):
        x, y = batch
        logits = self(x)
        loss = F.nll_loss(logits, y)
        preds = torch.argmax(logits, dim=1)
        acc = accuracy(preds, y)

        # Calling self.log will surface up scalars for you in TensorBoard
        self.log('val_loss', loss, prog_bar=True)
        self.log('val_acc', acc, prog_bar=True)
        return loss

    def test_step(self, batch, batch_idx):
        # Here we just reuse the validation_step for testing
        return self.validation_step(batch, batch_idx)

    def configure_optimizers(self):
        optimizer = torch.optim.Adam(self.parameters(), lr=self.learning_rate)
        return optimizer

    ####################
    # DATA RELATED HOOKS
    ####################

    def prepare_data(self):
        # download
        MNIST(self.data_dir, train=True, download=True)
        MNIST(self.data_dir, train=False, download=True)

    def setup(self, stage=None):

        # Assign train/val datasets for use in dataloaders
        if stage == 'fit' or stage is None:
            mnist_full = MNIST(self.data_dir, train=True, transform=self.transform)
            self.mnist_train, self.mnist_val = random_split(mnist_full, [55000, 5000])

        # Assign test dataset for use in dataloader(s)
        if stage == 'test' or stage is None:
            self.mnist_test = MNIST(self.data_dir, train=False, transform=self.transform)

    def train_dataloader(self):
        return DataLoader(self.mnist_train, batch_size=32)

    def val_dataloader(self):
        return DataLoader(self.mnist_val, batch_size=32)

    def test_dataloader(self):
        return DataLoader(self.mnist_test, batch_size=32)

from LSTM_Classification_V3 import AttentionModel, clip_gradient
# from LSTM_Classification import AttentionModel, clip_gradient
from loss import LabelSmoothingCrossEntropy
from imblearn.over_sampling import RandomOverSampler
from sklearn.metrics import accuracy_score, cohen_kappa_score
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from catalyst.utils import set_global_seed
from catalyst.dl import SupervisedRunner, Runner
from catalyst.utils import metrics
from catalyst.dl.callbacks import AccuracyCallback, AUCCallback, F1ScoreCallback, EarlyStoppingCallback, CriterionCallback

import torch
import torch.nn as nn
from torch.utils.data import Dataset as BaseDataset
from torch.utils.data import DataLoader, TensorDataset
from torch.nn import functional as F

from collections import OrderedDict
import matplotlib.pyplot as plt
import os
import time
import numpy as np
import pandas as pd
np.set_printoptions(threshold=np.inf)
pd.options.display.width = 0

# reproduce
SEED = 15
set_global_seed(SEED)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# read csv files
def data_together(filepath):
    csvs = []
    dfs = []

    for subdir, dirs, files in os.walk(filepath):
        for file in files:
            # print os.path.join(subdir, file)
            filepath = subdir + os.sep + file
            if filepath.endswith(".csv"):
                csvs.append(filepath)

    for f in csvs:
        dfs.append(pd.read_csv(f))

    return dfs, csvs

# determine the supported device

def get_device():
    if torch.cuda.is_available():
        device = torch.device('cuda:0')
    else:
        device = torch.device('cpu')  # don't have GPU
    return device

# convert a df to tensor to be used in pytorch

def numpy_to_tensor(ay, tp):
    device = get_device()
    return torch.from_numpy(ay).type(tp).to(device)

# count model parameters

def count_parameters(model):
    return sum(p.numel() for p in model.parameters() if p.requires_grad)

class CustomRunner(Runner):

    def _handle_batch(self, batch):
        x, y = batch
        # y_hat, attention = self.model(x)
        outputs = self.model(x)

        loss = F.cross_entropy(outputs['logits'], y)
        accuracy01, accuracy02 = metrics.accuracy(
            outputs['logits'], y, topk=(1, 2))
        self.batch_metrics = {
            "loss": loss,
            "accuracy01": accuracy01,
            "accuracy02": accuracy02,
        }

        if self.is_train_loader:
            loss.backward()
            self.optimizer.step()
            self.optimizer.zero_grad()

# classification label smoothing
class LabelSmoothingCrossEntropy(nn.Module):
    def __init__(self):
        super(LabelSmoothingCrossEntropy, self).__init__()

    def forward(self, x, target, smoothing=0.1):
        confidence = 1. - smoothing
        logprobs = F.log_softmax(x, dim=-1)
        nll_loss = -logprobs.gather(dim=-1, index=target.unsqueeze(1))
        nll_loss = nll_loss.squeeze(1)
        smooth_loss = -logprobs.mean(dim=-1)
        loss = confidence * nll_loss + smoothing * smooth_loss
        return loss.mean()

# self attention with lstm
class AttentionModel(torch.nn.Module):
    def __init__(self, trial,batch_size,input_dim, output_dim):
        super(AttentionModel, self).__init__()

        self.batch_size = batch_size
        self.input_dim = input_dim
        self.output_dim = output_dim

        self.hidden_dim = trial.suggest_int("hidden_dim", 40, 80,step=4,log=False)
        self.recurrent_layers = trial.suggest_int("recurrent_layers", 1, 3)
        self.dropout_p = trial.suggest_float("dropout_rate", 0, 0.3,step=0.1,log=False)

        self.input_embeded = nn.Linear(input_dim, self.hidden_dim//2)
        self.dropout = nn.Dropout(self.dropout_p)
        self.lstm = nn.LSTM(input_size=self.hidden_dim//2, hidden_size=self.hidden_dim, num_layers=self.recurrent_layers,
                            bidirectional=True)

        self.self_attention = nn.Sequential(
            nn.Linear(self.hidden_dim*2, self.hidden_dim*2),
            nn.ReLU(True),
            nn.Linear(self.hidden_dim*2, 1)
        )

        self.scale = 1.0/np.sqrt(self.hidden_dim)

        # initialize LSTM forget gate bias to be 1 as recommanded by http://proceedings.mlr.press/v37/jozefowicz15.pdf
        for names in self.lstm._all_weights:
            for name in filter(lambda n: "bias" in n, names):
                bias = getattr(self.lstm, name)
                n = bias.size(0)
                start, end = n // 4, n // 2
                bias.data[start:end].fill_(1.)

        self.output_linear = nn.Linear(self.hidden_dim * 2, self.hidden_dim)
        self.label = nn.Linear(self.hidden_dim*4, output_dim)

    def forward(self, input_sentences, batch_size=None):

        input = self.dropout(torch.tanh(self.input_embeded(input_sentences)))
        input = input.permute(1, 0, 2)
        if batch_size is None:
            h_0 = Variable(torch.zeros(2*self.recurrent_layers,
                                       self.batch_size, self.hidden_dim).to(device))
            c_0 = Variable(torch.zeros(2*self.recurrent_layers,
                                       self.batch_size, self.hidden_dim).to(device))
        else:
            h_0 = Variable(torch.zeros(2*self.recurrent_layers,
                                       batch_size, self.hidden_dim).to(device))
            c_0 = Variable(torch.zeros(2*self.recurrent_layers,
                                       batch_size, self.hidden_dim).to(device))

        self.lstm.flatten_parameters()

        output, (final_hidden_state, final_cell_state) = self.lstm(
            input, (h_0, c_0))
        output = output.permute(1, 0, 2)

        attn_ene = self.self_attention(output)
        attn_ene = attn_ene.reshape(
            self.batch_size, -1)

        # scale
        attn_ene.mul_(self.scale)
        attns = F.softmax(attn_ene, dim=1).unsqueeze(2)

        final_inputs = (output * attns).sum(dim=1)
        final_inputs2 = output.sum(dim=1)

        combined_inputs = torch.cat([final_inputs, final_inputs2], dim=1)
        logits = self.label(combined_inputs)

        return logits

if __name__ == "__main__":
    # sample data

    data_path = 'R:/CROPPHEN-Q2067/MoDS/Dabang_Sheng/Data/cleaned_data_25753.csv'
    df_all = pd.read_csv(data_path)
    labels = df_all.iloc[:, 2]
    df_all = df_all.iloc[:, 12:210].copy()
    # remove bigger than 1
    mask = (df_all <= 1).all(axis=1)
    df_all = df_all[mask]
    labels = labels[mask]

    # print((df_all.values >1).any())
    X = df_all
    y = labels

    le = LabelEncoder()
    le.fit(y)
    print(le.classes_)
    class_names = le.classes_
    y = le.transform(y)

    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.3, random_state=SEED, stratify=y)

    # # normalizeation
    # scaler = StandardScaler()
    # scaler.fit(X_train)

    # scaler_data_ = np.array([scaler.scale_, scaler.mean_, scaler.var_])
    # np.save("standard_scaler_2019filtered.npy", scaler_data_)

    # Using the standard deviation, mean and variance results from above.

    # X_train = scaler.transform(X_train)
    # X_test = scaler.transform(X_test)

    X_train_resampled, y_train_resampled = X_train, y_train

    # DataLoader definition
    # model hyperparameters
    INPUT_DIM = 1
    OUTPUT_DIM = 5
    HID_DIM = 64
    DROPOUT = 0.1
    RECURRENT_Layers = 2
    # LR = 0.001  # learning rate
    EPOCHS = 400
    BATCH_SIZE = 32
    num_classes = 5

    unique_elements, counts_elements = np.unique(y_train, return_counts=True)
    weights = [1/i for i in counts_elements]
    weights[2] = weights[2]/10
    print(np.asarray((unique_elements, counts_elements)))
    print(weights)
    samples_weight = np.array([weights[t] for t in y_train])
    samples_weights = torch.FloatTensor(samples_weight).to(device)
    class_weights = torch.FloatTensor(weights).to(device)
    sampler = torch.utils.data.sampler.WeightedRandomSampler(
        samples_weights, len(X_train_resampled), replacement=True)

    # # check sample no.
    # unique_elements, counts_elements = np.unique(y, return_counts=True)
    # print("Frequency of unique values of the said array:")
    # print(np.asarray((unique_elements, counts_elements)))

    # prepare PyTorch Datasets

    X_train_tensor = numpy_to_tensor(
        X_train_resampled.to_numpy(), torch.FloatTensor)
    y_train_tensor = numpy_to_tensor(y_train_resampled, torch.long)
    X_test_tensor = numpy_to_tensor(X_test.to_numpy(), torch.FloatTensor)
    y_test_tensor = numpy_to_tensor(y_test, torch.long)

    X_train_tensor = torch.unsqueeze(X_train_tensor, 2)
    X_test_tensor = torch.unsqueeze(X_test_tensor, 2)

    train_ds = TensorDataset(X_train_tensor, y_train_tensor)
    valid_ds = TensorDataset(X_test_tensor, y_test_tensor)

    train_dl = DataLoader(train_ds, batch_size=BATCH_SIZE,
                          sampler=sampler, drop_last=True, num_workers=0)
    valid_dl = DataLoader(valid_ds, batch_size=BATCH_SIZE,
                          shuffle=False, drop_last=True, num_workers=0)

    ground_truth = []
    for i in valid_dl:
        ground_truth.append(i[1].cpu().numpy().tolist())

    # print(ground_truth.flatten())
    ground_truth = [item for sublist in ground_truth for item in sublist]

    # Catalyst loader:

    loaders = OrderedDict()
    loaders["train"] = train_dl
    loaders["valid"] = valid_dl

    # model, criterion, optimizer, scheduler

    model = AttentionModel(BATCH_SIZE, INPUT_DIM, HID_DIM,
                           OUTPUT_DIM, RECURRENT_Layers, DROPOUT).to(device)

    print(model)
    count = count_parameters(model)
    print(count)

    criterion = torch.nn.CrossEntropyLoss()
    # criterion = LabelSmoothingCrossEntropy()
    optimizer = torch.optim.Adam(model.parameters(), lr=0.006)
    scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, [10, 40, 60])


from django.urls import path
from . import views

urlpatterns = [
    path('hod',views.hodash, name='hodash'),
    path('hod/create-faculty', views.create_faculty, name="create_faculty"),
    path('hod/create-faculty1', views.create_faculty1, name="create_faculty1"),
    path('hod/create-course', views.create_course, name="create_course"),
    path('hod/create-class', views.create_class, name="create_class"),
    path('hod/assign_subject', views.assign_subject, name="assign_subject"),
    path('hod/assign_class', views.create_course, name="assign_class"),

    path('faculty',views.facdash, name='facdash'),
    path('faculty/add-students', views.add_students,name="add_students"),
    path('faculty/list-students', views.list_students,name="list_students"),
    path('faculty/list-students', views.list_students,name="list_students"),
    path('faculty/attendance', views.mark_attendance,name="mark_attendance"),
    path('faculty/timtable', views.add_timetable, name="add_timetable"),
    path('faculty/showreport', views.showreport, name="showreport"),
    path('sendwarning', views.sendwarning,name="sendwarning"),
]


"""!@brief GUI prediction for Binary Neural Network, used to demonstrate progress to client.
Used as a demonstration of the neural network at the end of Sprint 2. GUI interface which allows a user to select an image. This image is then classified by the
neural network, and the certainty is displayed. If the file exists in the kaggle dataset CSV file, the correct class will be displayed, and a
tick or a cross will represent whether the classification was accurate.
"""

import sys
import os
import csv
import tkinter as tk
from tkinter.filedialog import askopenfilename
from keras.models import load_model
import numpy as np
from PIL import Image, ImageTk

imglist = []
window = tk.Tk()
window.withdraw()

# For usage, change MODEL_LOCATION and CSV_LOCATION to = "<.H5 OR CSV FILE PATH>"
MODEL_LOCATION = ""
CSV_LOCATION = ""

# Since binary classification, only 2 class names required.
class_to_name = ["cloudy", "clear"]

# Show an "Open" dialog box for user to select image, and return the path to the selected file
filename = askopenfilename()

def modelLoader(model_loc):
    """Given the path to a .h5 model file, loads and compiles the model."""
    model = load_model(model_loc)
    model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])
    return model

def initImage(filename):
    """Converts image to suitable format to be input into the model.
    Rescales by 1/255 to account for RGB value coefficients."""
    size = 150, 150
    # Convert image to suitable format to be input into the model.
    # Rescale by 1/255 to account for RGB value coefficients.
    img = Image.open(filename)
    img = img.resize(size, Image.ANTIALIAS)
    img = img.convert('RGB')
    x = np.asarray(img, dtype='float32')
    x = np.expand_dims(x, axis=0)
    x = x/255
    return x

def predictImage(image, model):
    """Given an augmented image, the function returns the prediction from the model,
    the class name of the prediction and the certainty percentage."""
    # Get the prediction from the model and obtain the class name.
    choice = model.predict(image)
    print(choice)
    classString = class_to_name[model.predict_classes(image)[0][0]]

    # Checking if the prediction is substantial evidence to use that class.
    # Display as certainty percentage
    if (choice >= 0.5):
        certainty= str(round(choice[0][0]*100, 2)) + "%"
    # If not display as uncertainty percentage
    else:
        certainty = str(round((1 - choice[0][0])*100, 2)) + "%"
    return choice, classString, certainty

def format(category):
    """Given a category name, returns the category name with spaces instead of underscores,
    and formatted to Title Case. clear_primary -> Clear Primary"""
    return category.replace("_", " ").title()

def restart_program():
    """Restarts the current program, so user can select another image to predict."""
    python = sys.executable
    os.execl(python, python, * sys.argv)

def getvals(filename):
    """Returns the actual image classification, specified in the given CSV. If not present "None" returned."""
    csvFile=open(CSV_LOCATION)
    reader=csv.reader(csvFile)
    for item in reader:
        if item[0] == filename:
            return item[1]
    return "None"

model = modelLoader(MODEL_LOCATION)
scaledImage = initImage(filename)
choice, out1, out2 = predictImage(scaledImage, model)

#getting the actual classes for the image
check = (getvals(os.path.basename(filename).split(".")[0]))

#just getting width and height in order to centre window
screen_width = int((window.winfo_screenwidth()/2) - 200)
screen_height = int((window.winfo_screenheight()/2) - 175)

window.geometry("400x425+" + str(screen_width) + "+" + str(screen_height))
window.deiconify()
window.title("CNN Predictions")

#importing image to the window
img = ImageTk.PhotoImage(Image.open(filename))
panel = tk.Label(window, image = img, height = "256", width = "256").pack()
T = tk.Text(window, height = 2)
T.config(font=("Arial"))
T.pack()
T.insert(tk.END,"I'm about " + out2 + " sure that is " + format(out1))
T.insert(tk.END, "\nActual: " + check + "\n")
T.tag_add("start", "1.10", "1.16")

T.tag_config("center", justify='center')
T.tag_add("center", 1.0, "end")

#highlights colour of certainty with colour codes
num = float(out2[:-1])
if(num >= 80):
    T.tag_config("start", foreground="green")
elif(num >= 70):
    T.tag_config("start", foreground="orange")
else:
    T.tag_config("start", foreground="red")

#output if the image is *actually* cloudy or clear
if (format(out1).lower() in check):
    result = tk.Label(window, text = "✓", fg = "green", font=(None, 50)).pack()
else:
    result = tk.Label(window, text = "✗", fg = "red", font=(None, 50)).pack()

b = tk.Button(window, text="Choose Another", command=restart_program, pady = '3', font=("Arial")).pack()
window.mainloop()


############################################
# Name: Bryan John Baker
# Student ID: bake1358
# Email: bake1358@umn.edu
# Collaborators:
# File Name: hw4_adaboost.py
############################################

import numpy as np
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
import matplotlib.pyplot as plt

def plot_margin(data, learner_lst, alpha_lst):
    """
    Create a margin plot.
    :param data: The dataset used to create the model.
    :param learner_lst: A list of weak learners.
    :param alpha_lst: A list of alphas to use in the Adaboost model.
    :return: A margin plot.
    """
    margin = []
    for i in range(data.shape[0]):
        f_x = 0
        for j in range(len(learner_lst)):
            f_x += (alpha_lst[j] * learner_lst[j].predict(np.array(data.iloc[i]).reshape(1, -1)))
        margin.append(f_x[0])
    margin = margin / sum(alpha_lst)
    margin = train_y.reshape(-1) * margin
    margin.sort()
    cumulative = np.cumsum(margin)
    cumulative = cumulative / sum(margin)
    plt.plot(margin, cumulative)
    plt.title("Adaboost Margin Plot for " + str(len(learner_lst)) + " learners")
    plt.xlabel("Margin")
    plt.ylabel("Cumulative Distribution")
    plt.xlim(-1, 1)
    plt.ylim(0, 1)
    plt.grid()
    plt.show()

# Read and prepare training dataset
training_data = pd.read_csv("cancer_train.csv")
train_y = np.array(training_data["y"])
train_y = train_y.reshape(-1, 1)
train_y[train_y == 0] = -1
train_x = training_data
train_x = train_x.drop("y", axis=1)

# Read and prepare testing dataset
testing_data = pd.read_csv("cancer_test.csv")
test_y = np.array(testing_data["y"])
test_y = test_y.reshape(-1, 1)
test_y[test_y == 0] = -1
test_x = testing_data
test_x = test_x.drop("y", axis=1)

# Initialize weights and lists to store alpha_lst and learner_lst
D_train = np.full(train_y.shape, 1/train_y.shape[0]).reshape(-1)
D_train = D_train / np.sum(D_train)
D_test = np.full(test_y.shape, 1/test_y.shape[0]).reshape(-1)
D_test = D_test / np.sum(D_test)
trees = []
alphas = []
iter = []
train_error_lst = []
test_error_lst = []

# Run Adaboost algorithm using 100 weak learners
for i in range(100):
    iter.append(i)
    # Train the weak learner using the sample weights we calculated
    decision_tree = DecisionTreeClassifier(max_depth=1, criterion="gini")
    decision_tree = decision_tree.fit(train_x, train_y, sample_weight=D_train)
    # Store the learner
    trees.append(decision_tree)
    # Calculate epsilon
    epsilon = np.sum(D_train * (decision_tree.predict(train_x) != train_y.reshape(-1)))
    # Calculate alpha
    alpha = 0.5 * np.log((1 - epsilon) / (epsilon))
    print("Model " + str(i) + "; epsilon: " + str(epsilon) + "; alpha: " + str(alpha))
    # Store alpha
    alphas.append(alpha)
    # Calculate the new training weights and normalize them
    D_train = D_train * np.exp(-alpha * train_y.reshape(-1) * decision_tree.predict(train_x))
    D_train = D_train / np.sum(D_train)
    # Find the training set predictions and misclassification error
    f_x = 0
    for j in iter:
        f_x += (alphas[j] * trees[j].predict(train_x))
    y_train_preds = np.sign(f_x)
    train_error = np.mean(np.not_equal(y_train_preds, train_y.reshape(-1)))
    train_error_lst.append(train_error)
    # Find the testing set predictions and misclassification error
    f_x = 0
    for j in iter:
        f_x += (alphas[j] * trees[j].predict(test_x))
    y_test_preds = np.sign(f_x)
    test_error = np.mean(np.not_equal(y_test_preds, test_y.reshape(-1)))
    test_error_lst.append(test_error)
    print("Training error: " + str(train_error) + "; Testing error: " + str(test_error))
    if i in [24, 49, 74, 99]:
        plot_margin(train_x, trees, alphas)

# Create the misclassification plot
plt.xlabel('Number of Weak Learners')
plt.ylabel('Misclassification Error')
plt.title('Adaboost Misclassification Error on Cancer Dataset')
plt.grid()
plt.plot(train_error_lst)
plt.plot(test_error_lst)
plt.gca().legend(('Training Data', 'Testing Data'))
plt.show()


from typing import List
class Solution:
    # Time complexity: O(n)
    # Space complexity: O(n)
    def productExceptSelf(self, nums: List[int]) -> List[int]:
        if all(num == 0 for num in nums):
            return nums

        length = len(nums)
        left_prod = [1] * length
        right_prod = [1] * length

        for i in range(1, length):
            left_prod[i] = left_prod[i-1] * nums[i-1]
            right_prod[length-i-1] = right_prod[length-i] * nums[length-i]

        result = [left_prod[i] * right_prod[i] for i in range(length)]
        return result
    # Time complexity: O(n)
    # Space complexity: O(1)
    def productExceptSelf(self, nums: List[int]) -> List[int]:
        if all(num == 0 for num in nums):
            return nums

        length = len(nums)
        result = [1] * length
        for i in range(1, length):
            result[i] = result[i-1] * nums[i-1]

        right_prod = 1
        for i in range(length-1, -1, -1):
            result[i] *= right_prod
            right_prod *= nums[i]

        return result

Arrays and Hashing/Product of Array Except Self.py


# On-the-fly-CT Reco
version =  "Version 2021.12.22 b"

import numpy
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QPixmap
from PyQt5.uic import loadUiType
from PIL import Image
import h5py
import tomopy
import math
import time
import os
import csv
import qimage2ndarray
from scipy.ndimage.filters import gaussian_filter, median_filter

Ui_on_the_fly_Window, Q_on_the_fly_Window = loadUiType('on_the_fly_CT_reco_hdf.ui')  # connect to the GUI for the program

class On_the_fly_CT_tester(Ui_on_the_fly_Window, Q_on_the_fly_Window):

    def __init__(self):
        super(On_the_fly_CT_tester, self).__init__()
        self.setupUi(self)
        self.setWindowTitle('On_the_fly_CT_tester')

        #connect buttons to actions
        self.pushLoad.clicked.connect(self.load)
        self.pushReconstruct.clicked.connect(self.reconstruct)
        self.pushReconstruct_all.clicked.connect(self.reconstruct_all)
        self.push_Crop_volume.clicked.connect(self.crop_volume)
        #self.slice_number.valueChanged.connect(self.reconstruct)
        #self.COR.valueChanged.connect(self.reconstruct)
        #self.Offset_Angle.valueChanged.connect(self.reconstruct)
        #self.brightness.valueChanged.connect(self.reconstruct)
        #self.speed_W.valueChanged.connect(self.reconstruct)
        #self.algorithm_list.currentIndexChanged.connect(self.reconstruct)
        #self.filter_list.currentIndexChanged.connect(self.reconstruct)

        self.block_size = 128        #volume will be reconstructed blockwise to reduce needed RAM
        self.extend_FOV = 0.05      #the reconstructed area will be enlarged in order to allow off axis scans
        self.crop_offset = 0        #needed for proper volume cropping

    def buttons_deactivate_all(self):
        self.spinBox_ringradius.setEnabled(False)
        self.Offset_Angle.setEnabled(False)
        self.spinBox_DF.setEnabled(False)
        self.pushLoad.setEnabled(False)

        self.slice_number.setEnabled(False)
        self.COR.setEnabled(False)
        self.Offset_Angle.setEnabled(False)
        self.brightness.setEnabled(False)
        self.speed_W.setEnabled(False)
        self.pushReconstruct.setEnabled(False)
        self.algorithm_list.setEnabled(False)
        self.filter_list.setEnabled(False)

        self.checkBox_phase_2.setEnabled(False)
        self.doubleSpinBox_distance_2.setEnabled(False)
        self.doubleSpinBox_Energy_2.setEnabled(False)
        self.doubleSpinBox_alpha_2.setEnabled(False)

        self.spinBox_first.setEnabled(False)
        self.spinBox_last.setEnabled(False)
        self.push_Crop_volume.setEnabled(False)

        self.pushReconstruct_all.setEnabled(False)
        self.int_low.setEnabled(False)
        self.int_high.setEnabled(False)
    def buttons_activate_load(self):
        self.spinBox_ringradius.setEnabled(True)
        self.spinBox_DF.setEnabled(True)
        self.pushLoad.setEnabled(True)
    def buttons_activate_reco(self):
        self.slice_number.setEnabled(True)
        self.COR.setEnabled(True)
        self.Offset_Angle.setEnabled(True)
        self.brightness.setEnabled(True)
        self.speed_W.setEnabled(True)
        self.pushReconstruct.setEnabled(True)
        self.algorithm_list.setEnabled(True)
        self.filter_list.setEnabled(True)

        self.checkBox_phase_2.setEnabled(True)
        self.doubleSpinBox_distance_2.setEnabled(True)
        self.doubleSpinBox_Energy_2.setEnabled(True)
        self.doubleSpinBox_alpha_2.setEnabled(True)
    def buttons_activate_reco_all(self):
        self.pushReconstruct_all.setEnabled(True)
        self.int_low.setEnabled(True)
        self.int_high.setEnabled(True)
    def buttons_activate_crop_volume(self):
        self.spinBox_first.setEnabled(True)
        self.spinBox_last.setEnabled(True)
        self.push_Crop_volume.setEnabled(True)

    def load(self):

        #grey out the buttons while program is busy
        self.buttons_deactivate_all()

        #ask for first flat field
        path_klick_FF = QtWidgets.QFileDialog.getOpenFileName(self, 'Select first FF-file, please.', "C:\Fly_and_Helix_Test\Flying-CT_Test\MEA_Flying-CT_2x2_crop_normalized")
        self.path_klickFF = path_klick_FF[0]
        print(self.path_klickFF)

        #analyse and cut the path in pieces
        htapFF = self.path_klickFF[::-1]
        self.path_inFF = self.path_klickFF[0: len(htapFF) - htapFF.find('/') - 1: 1]
        self.namepartFF = self.path_klickFF[len(htapFF) - htapFF.find('/') - 1: len(htapFF) - htapFF.find('.') - 5: 1]
        self.counterFF = int(self.path_klickFF[len(htapFF) - htapFF.find('.') - 5: len(htapFF) - htapFF.find('.') - 1:1])
        self.filetypeFF = self.path_klickFF[len(htapFF) - htapFF.find('.') - 1: len(htapFF):1]
        print(self.path_inFF)
        print(self.namepartFF)
        print(self.counterFF)
        print(self.filetypeFF)

        #open file to get the image dimensions
        if self.filetypeFF == '.tif':
            referenceFF = Image.open(self.path_klickFF)
            referenceFF = numpy.array(referenceFF)
            referenceFF = numpy.transpose(referenceFF)
        elif self.filetypeFF == '.h5':
            with h5py.File(self.path_klickFF, 'r') as hdf:
                entry = hdf.get('entry')
                data = entry.get('/entry/data/data')
                referenceFF = numpy.array(data)
                referenceFF = numpy.transpose(referenceFF)
        else:
            print('Error loading file type')

        self.full_sizeFF = referenceFF.shape
        print(self.full_sizeFF)

        #check how many flat fields there are
        for i in range(self.counterFF,999999):
            print(i)
            lastFF = i
            filenameFF = self.path_inFF + self.namepartFF + str(i).zfill(4) + self.filetypeFF

            if os.path.exists(filenameFF) != True:
                break

        print(lastFF)

        #create array to fill FFs in there
        self.FF = numpy.zeros((lastFF - self.counterFF + 1, referenceFF.shape[1], referenceFF.shape[0]), dtype=float)

        #open each flat field and collect in array
        i = self.counterFF
        while i < lastFF:
            self.progressBar.setValue((i + 1) * 100 / lastFF)

            filenameFF = self.path_inFF + self.namepartFF + str(i).zfill(4) + self.filetypeFF

            QtWidgets.QApplication.processEvents()
            print('LoadingFF ', filenameFF)

            if self.filetypeFF == '.tif':
                projFF = Image.open(filenameFF)
                proj_FF = numpy.array(projFF)
            elif self.filetypeFF == '.h5':
                with h5py.File(self.path_klickFF, 'r') as hdf:
                    entry = hdf.get('entry')
                    data = entry.get('/entry/data/data')
                    proj_FF = numpy.array(data)
            else:
                print('Error loading file type')

            self.FF[i - self.counterFF, :, :] = proj_FF

            i = i + 1

        #average all flat fields
        FFavg = numpy.mean(self.FF, axis=0)
        FFavg_df = FFavg - self.spinBox_DF.value()

        #ask for first projection file
        path_klick_raw = QtWidgets.QFileDialog.getOpenFileName(self, 'Select first projection, please.', self.path_klickFF)
        self.path_klick = path_klick_raw[0]
        print(self.path_klick)

        #analyse and cut the path in pieces
        htap = self.path_klick[::-1]
        self.path_in = self.path_klick[0: len(htap) - htap.find('/') - 1: 1]
        ni_htap = self.path_in[::-1]
        self.folder_name = self.path_klick[len(htap) - htap.find('/') - ni_htap.find('/') -1 :len(htap) - htap.find('/') - 1 : 1]
        self.namepart = self.path_klick[len(htap) - htap.find('/') - 1: len(htap) - htap.find('.') - 5: 1]
        self.counter = int(self.path_klick[len(htap) - htap.find('.') - 5: len(htap) - htap.find('.') - 1:1])
        self.filetype = self.path_klick[len(htap) - htap.find('.') - 1: len(htap):1]
        self.Sample.setText(self.path_in)

        #open projection file to get dimensions - (probably not necessary)
        if self.filetype == '.tif':
            reference = Image.open(self.path_klick)
            reference = numpy.array(reference)
            reference = numpy.transpose(reference)
        elif self.filetype == '.h5':
            with h5py.File(self.path_klick, 'r') as hdf:
                entry = hdf.get('entry')
                data = entry.get('/entry/data/data')
                reference = numpy.array(data)
                reference = numpy.transpose(reference)
        else:
            print('Error loading file type')

        self.full_size = reference.shape
        print(self.full_size)

        #check how many files there are
        for i in range(self.counter,999999):
            print('finding last image ',i)
            last = i
            filename = self.path_in + self.namepart + str(i).zfill(4) + self.filetype

            if os.path.exists(filename) != True:
                break

        print(last)

        #create array for all projections and for the angles
        self.A = numpy.zeros((last - self.counter + 1, reference.shape[1], reference.shape[0]), dtype=numpy.uint16)
        self.w = numpy.zeros(last - self.counter + 1, dtype=numpy.float64)

        #open each projection, normalize and store in array
        i = self.counter
        while i < last:
            #update progress bar
            self.progressBar.setValue((i + 1) * 100 / last)

            filename = self.path_in + self.namepart + str(i).zfill(4) + self.filetype

            QtWidgets.QApplication.processEvents()
            print('Loading ', filename)

            #open file
            if self.filetype == '.tif':
                proj = Image.open(filename)
                proj_ = numpy.array(proj)
                self.last_zero_proj = 0
            elif self.filetype == '.h5':
                with h5py.File(filename, 'r') as hdf:
                    entry = hdf.get('entry')
                    data = entry.get('/entry/data/data')
                    proj_ = numpy.array(data)
                    w_data = entry.get('/entry/instrument/NDAttributes/CT_MICOS_W')       #get angles from hdf5-file
                    self.w[i - self.counter] = numpy.array(w_data)
                    print('w', self.w[i - self.counter])
                    if round(self.w[i - self.counter]) == 0:                              #notice the last projection at zero degree
                        self.last_zero_proj = i - self.counter + 3                        #assumes 3 images for speeding up the motor
            else:
                print('Error loading file type')

            #normalize
            proj_df = proj_ - self.spinBox_DF.value()
            proj_norm = numpy.divide(proj_df, FFavg_df)
            proj_norm = numpy.clip(proj_norm, 0.03, 4)
            proj_norm = proj_norm * 16000
            proj_norm = numpy.nan_to_num(proj_norm, copy=True, nan=1.0, posinf=1.0, neginf=1.0)
            proj_norm_16 = numpy.uint16(proj_norm)

            #store in array
            self.A[i - self.counter,:,:] = proj_norm_16

            #collect sum of all normalized projections for ring filtering
            if self.spinBox_ringradius.value() != 0:

                if i == self.counter:
                    self.proj_sum = numpy.array(proj_norm_16, dtype=numpy.single)
                else:
                    self.proj_sum = self.proj_sum + proj_norm_16

            i = i + 1

        print('A', self.A.shape, 'A min vs max', numpy.amin(self.A), numpy.amax(self.A))

        #Ring artifact handling
        if self.spinBox_ringradius.value() != 0:
            print('proj_sum dimensions', self.proj_sum.shape)

            #correction map = (sum of projections) / median filter of (sum of projections)
            proj_sum_filtered = median_filter(self.proj_sum, size = self.spinBox_ringradius.value())
            correction_map = numpy.divide(self.proj_sum, proj_sum_filtered)
            correction_map = numpy.clip(correction_map, 0.9, 1.1)

            print('correction_map dimensions', correction_map.shape, 'correction_map min vs max', numpy.amin(correction_map), numpy.amax(correction_map))

            #apply correction map for ring handling
            i=0
            while i < self.A.shape[0]:
                self.A[i, :, :] = numpy.uint16(numpy.divide(self.A[i, :, :], correction_map))
                self.progressBar.setValue((i + 1) * 100 / self.A.shape[0])
                QtWidgets.QApplication.processEvents()
                i = i+1

        print('A dimensions',self.A.shape, 'A min vs max', numpy.amin(self.A), numpy.amax(self.A))

        #prefill slice number, COR, cropping
        self.slice_number.setMaximum(reference.shape[1]-1)
        self.slice_number.setMinimum(0)
        self.slice_number.setValue(round(reference.shape[1]/2))
        self.COR.setValue(round(reference.shape[0]/2))
        self.spinBox_first.setValue(0)
        self.spinBox_last.setValue(reference.shape[1]-1)

        #prefill rotation-speed[°/img]
        print('found angular values for ',self.w.shape, 'projections')
        print(self.w)
        poly_coeff =  numpy.polyfit(numpy.arange(len(self.w[round((last - self.counter + 1) /4) : round((last - self.counter + 1) * 3/4) ])), self.w[round((last - self.counter + 1) /4) : round((last - self.counter + 1) * 3/4) ], 1, rcond=None, full=False, w=None, cov=False)
        print('Plynom coefficients',poly_coeff)
        self.speed_W.setValue(poly_coeff[0])
        print('Last projection at 0 degree/still speeding up: number', self.last_zero_proj)

        #ungrey the buttons for further use of the program
        self.buttons_activate_load()
        self.buttons_activate_reco()
        #self.buttons_activate_crop_volume()
        #self.buttons_activate_reco_all()
        print('Loading/Normalizing complete!')

    def crop_volume(self):
        #grey out the buttons while program is busy
        self.buttons_deactivate_all()

        #crop the top and/or bottom of the data. store the offset value for saving slices under the right number
        self.A = self.A[:,self.spinBox_first.value():self.spinBox_last.value()+1,:]
        self.crop_offset = self.crop_offset + self.spinBox_first.value()
        self.spinBox_first.setValue(0)
        self.spinBox_last.setValue(self.A.shape[1]-1)
        self.slice_number.setMaximum(self.A.shape[1]-1)
        print('Volume Cropped')
        print('A', self.A.shape)

        #ungrey the buttons for further use of the program
        self.buttons_activate_load()
        self.buttons_activate_reco()
        self.buttons_activate_crop_volume()
        self.buttons_activate_reco_all()

    def reconstruct(self):

        # grey out the buttons while program is busy
        self.buttons_deactivate_all()

        QtWidgets.QApplication.processEvents()
        print('def reconstruct')

        self.full_size = self.A.shape[2]
        self.number_of_projections = self.A.shape[0]

        #determine how far to extend field of view (FOV), 0.0 no extension, 0.5 half extension to both sides (for off center 360 degree scan!!!)
        self.extend_FOV = 2* (abs(self.COR.value() - self.A.shape[2]/2))/ (1 * self.A.shape[2]) + 0.05
        print('extend_FOV ', self.extend_FOV)

        #check if the scan was 180° or 360°
        if self.number_of_projections * self.speed_W.value() >= 270:
            self.number_of_used_projections = round(360 / self.speed_W.value())
        else:
            print('smaller than 3/2 Pi')
            self.number_of_used_projections = round(180 / self.speed_W.value())
        print('number of used projections', self.number_of_used_projections)

        #create list with x-positions of projections
        new_list = (numpy.arange(self.number_of_used_projections) * self.speed_W.value() + self.Offset_Angle.value()) * math.pi / 180
        print('x_list ',new_list.shape)

        #create list with all projection angles
        center_list = [self.COR.value() + round(self.extend_FOV * self.full_size)] * (self.number_of_used_projections)
        print('COR_list ',len(center_list))

        #create one sinogram in the form [z, y, x]
        transposed_sinos = numpy.zeros((min(self.number_of_used_projections, self.A.shape[0]), 1, self.full_size), dtype=float)
        #transposed_sinos[:,0,:] = self.A[0:min(self.number_of_used_projections, self.A.shape[0]), self.slice_number.value(),:]
        transposed_sinos[:,0,:] = self.A[self.last_zero_proj : min(self.last_zero_proj + self.number_of_used_projections, self.A.shape[0]), self.slice_number.value(),:]
        print('transposed_sinos_shape', transposed_sinos.shape)

        #extend data with calculated parameter, compute logarithm, remove NaN-values
        extended_sinos = tomopy.misc.morph.pad(transposed_sinos, axis=2, npad=round(self.extend_FOV * self.full_size), mode='edge')
        extended_sinos = tomopy.minus_log(extended_sinos)
        extended_sinos = (extended_sinos + 9.68) * 1000  # conversion factor to uint
        extended_sinos = numpy.nan_to_num(extended_sinos, copy=True, nan=1.0, posinf=1.0, neginf=1.0)

        #apply phase retrieval if desired
        if self.checkBox_phase_2.isChecked() == True:
            extended_sinos = tomopy.prep.phase.retrieve_phase(extended_sinos, pixel_size=0.0001, dist=self.doubleSpinBox_distance_2.value(), energy=self.doubleSpinBox_Energy_2.value(), alpha=self.doubleSpinBox_alpha_2.value(), pad=True, ncore=None, nchunk=None)

        #reconstruct one slice
        if self.algorithm_list.currentText() == 'FBP_CUDA':
            options = {'proj_type': 'cuda', 'method': 'FBP_CUDA'}
            slices = tomopy.recon(extended_sinos, new_list, center=center_list, algorithm=tomopy.astra, options=options)
        else:
            slices = tomopy.recon(extended_sinos, new_list, center=center_list, algorithm=self.algorithm_list.currentText(),
                                  filter_name=self.filter_list.currentText())

        #cut reconstructed slice to original size
        slices = slices[:,round(self.extend_FOV * self.full_size /2) : -round(self.extend_FOV * self.full_size /2) , round(self.extend_FOV * self.full_size /2) : -round(self.extend_FOV * self.full_size /2)]
        slices = tomopy.circ_mask(slices, axis=0, ratio=1.0)
        original_reconstruction = slices[0, :, :]

        #find and display minimum and maximum values in reconstructed slice
        print(numpy.amin(original_reconstruction))
        print(numpy.amax(original_reconstruction))
        self.min.setText(str(numpy.amin(original_reconstruction)))
        self.max.setText(str(numpy.amax(original_reconstruction)))
        print('reconstructions done')

        #display reconstructed slice
        myarray = (original_reconstruction - numpy.amin(original_reconstruction)) * self.brightness.value() / (numpy.amax(original_reconstruction) - numpy.amin(original_reconstruction))
        myarray = myarray.repeat(2, axis=0).repeat(2, axis=1)
        yourQImage = qimage2ndarray.array2qimage(myarray)
        self.test_reco.setPixmap(QPixmap(yourQImage))

        #ungrey the buttons for further use of the program
        self.buttons_activate_load()
        self.buttons_activate_reco()
        self.buttons_activate_crop_volume()
        self.buttons_activate_reco_all()

    def reconstruct_all(self):
        #grey out the buttons while program is busy
        self.buttons_deactivate_all()

        QtWidgets.QApplication.processEvents()
        print('def reconstruct complete volume')

        #ask for the output path and create it
        self.path_out_reconstructed_ask = QtWidgets.QFileDialog.getExistingDirectory(self, 'Select folder for reconstructions.', self.path_klick)

        #create a folder when saving reconstructed volume as tif-files
        if self.save_tiff.isChecked() == True:
            self.path_out_reconstructed_full = self.path_out_reconstructed_ask + '/'+ self.folder_name
            os.mkdir(self.path_out_reconstructed_full)
        if self.save_hdf5.isChecked() == True:
            self.path_out_reconstructed_full = self.path_out_reconstructed_ask

        self.full_size = self.A.shape[2]
        self.number_of_projections = self.A.shape[0]
        print('X-size', self.A.shape[2])
        print('Nr of projections', self.A.shape[0])
        print('Nr of slices', self.A.shape[1])

        #calculate extension of projections to the sides
        self.extend_FOV = 2* (abs(self.COR.value() - self.A.shape[2]/2))/ (1 * self.A.shape[2]) + 0.05    # extend field of view (FOV), 0.0 no extension, 0.5 half extension to both sides (for half sided 360 degree scan!!!)
        print('extend_FOV ', self.extend_FOV)

        #check if 180° or 360°-scan
        if self.number_of_projections * self.speed_W.value() >= 270:
            self.number_of_used_projections = round(360 / self.speed_W.value())
        else:
            print('smaller than 3/2 Pi')
            self.number_of_used_projections = round(180 / self.speed_W.value())
        print('number of used projections', self.number_of_used_projections)

        #create list with x-positions
        new_list = (numpy.arange(self.number_of_used_projections) * self.speed_W.value() + self.Offset_Angle.value()) * math.pi / 180
        print(new_list.shape)

        #create list with projection angles
        center_list = [self.COR.value() + round(self.extend_FOV * self.full_size)] * (self.number_of_used_projections)
        print(len(center_list))

        #save parameters in csv-file
        file_name_parameter = self.path_out_reconstructed_full + '/' + self.folder_name + '_parameter.csv'
        with open(file_name_parameter, mode = 'w', newline='') as parameter_file:
            csv_writer = csv.writer(parameter_file, delimiter = ' ', quotechar=' ')
            csv_writer.writerow(['Path input                    ', self.path_in,' '])
            csv_writer.writerow(['Path output                   ', self.path_out_reconstructed_full,' '])
            csv_writer.writerow(['Number of used projections    ', str(self.number_of_used_projections),' '])
            csv_writer.writerow(['Center of rotation            ', str(self.COR.value()), ' '])
            csv_writer.writerow(['Dark field value              ', str(self.spinBox_DF.value()),' '])
            csv_writer.writerow(['Ring handling radius          ', str(self.spinBox_ringradius.value()),' '])
            csv_writer.writerow(['Rotation offset               ', str(self.Offset_Angle.value()), ' '])
            csv_writer.writerow(['Rotation speed [°/image]      ', str(self.speed_W.value()), ' '])
            csv_writer.writerow(['Phase retrieval               ', str(self.checkBox_phase_2.isChecked()), ' '])
            csv_writer.writerow(['Phase retrieval distance      ', str(self.doubleSpinBox_distance_2.value()), ' '])
            csv_writer.writerow(['Phase retrieval energy        ', str(self.doubleSpinBox_Energy_2.value()), ' '])
            csv_writer.writerow(['Phase retrieval alpha         ', str(self.doubleSpinBox_alpha_2.value()), ' '])
            csv_writer.writerow(['16-bit                        ', str(self.radioButton_16bit_integer.isChecked()), ' '])
            csv_writer.writerow(['16-bit integer low            ', str(self.int_low.value()), ' '])
            csv_writer.writerow(['16-bit integer high           ', str(self.int_high.value()), ' '])
            csv_writer.writerow(['Reconstruction algorithm      ', self.algorithm_list.currentText(), ' '])
            csv_writer.writerow(['Reconstruction filter         ', self.filter_list.currentText(), ' '])
            csv_writer.writerow(['Software Version              ', version, ' '])
            csv_writer.writerow(['binning                       ', '1x1x1', ' '])

        #divide volume into blocks and reconstruct them one by one in order to save RAM
        i = 0
        while (i < math.ceil(self.A.shape[1] / self.block_size)):

            print('Reconstructing block', i + 1, 'of', math.ceil(self.A.shape[1] / self.block_size))

            #extend data, take logarithm, remove NaN-values
            ###extended_sinos = self.A[0:min(self.number_of_used_projections, self.A.shape[0]), i * self.block_size: (i + 1) * self.block_size, :]
            extended_sinos = self.A[self.last_zero_proj : min(self.last_zero_proj + self.number_of_used_projections, self.A.shape[0]), i * self.block_size: (i + 1) * self.block_size, :]

            extended_sinos = tomopy.misc.morph.pad(extended_sinos, axis=2, npad=round(self.extend_FOV * self.full_size), mode='edge')
            extended_sinos = tomopy.minus_log(extended_sinos)
            extended_sinos = (extended_sinos + 9.68) * 1000  # conversion factor to uint
            extended_sinos = numpy.nan_to_num(extended_sinos, copy=True, nan=1.0, posinf=1.0, neginf=1.0)

            #apply phase retrieval if desired
            if self.checkBox_phase_2.isChecked() == True:
                extended_sinos = tomopy.prep.phase.retrieve_phase(extended_sinos, pixel_size=0.0001, dist=self.doubleSpinBox_distance_2.value(), energy=self.doubleSpinBox_Energy_2.value(), alpha=self.doubleSpinBox_alpha_2.value(), pad=True, ncore=None, nchunk=None)

            #reconstruct
            if self.algorithm_list.currentText() == 'FBP_CUDA':
                options = {'proj_type': 'cuda', 'method': 'FBP_CUDA'}
                slices = tomopy.recon(extended_sinos, new_list, center=center_list, algorithm=tomopy.astra,
                                      options=options)
            else:
                slices = tomopy.recon(extended_sinos, new_list, center=center_list,
                                      algorithm=self.algorithm_list.currentText(),
                                      filter_name=self.filter_list.currentText())

            #crop reconstructed data
            slices = slices[:, round(self.extend_FOV * self.full_size /2): -round(self.extend_FOV * self.full_size /2), round(self.extend_FOV * self.full_size /2): -round(self.extend_FOV * self.full_size /2)]
            slices = tomopy.circ_mask(slices, axis=0, ratio=1.0)

            #16-bit integer conversion
            if self.radioButton_16bit_integer.isChecked() == True:
                ima3 = 65535 * (slices - self.int_low.value()) / (self.int_high.value() - self.int_low.value())
                ima3 = numpy.clip(ima3, 1, 65534)
                slices_save = ima3.astype(numpy.uint16)

            if self.radioButton_32bit_float.isChecked() == True:
                slices_save = slices

            print('Reconstructed Volume is', slices_save.shape)

            #save data
            if self.save_tiff.isChecked() == True:

                # write the reconstructed block to disk as TIF-file
                a = 1
                while (a < self.block_size + 1) and (a < slices_save.shape[0] + 1):
                    self.progressBar.setValue((a + (i * self.block_size)) * 100 / self.A.shape[1])
                    QtCore.QCoreApplication.processEvents()
                    time.sleep(0.02)
                    filename2 = self.path_out_reconstructed_full + self.namepart + str(
                        a + self.crop_offset + i * self.block_size).zfill(4) + '.tif'
                    print('Writing Reconstructed Slices:', filename2)
                    slice_save = slices_save[a - 1, :, :]
                    img = Image.fromarray(slice_save)
                    img.save(filename2)
                    a = a + 1

            if self.save_hdf5.isChecked() == True:
                if i == 0:
                    # create an an hdf5-file and write the first reconstructed block into it
                    with h5py.File(self.path_out_reconstructed_full + '/' + self.folder_name + '.h5', 'w')  as f:
                        f.create_dataset("Volume", data=slices_save, maxshape=(None, slices_save.shape[1], slices_save.shape[2]))
                else:
                    # write the subsequent blocks into the hdf5-file
                    self.progressBar.setValue((i * self.block_size) * 100 / self.A.shape[1])
                    QtCore.QCoreApplication.processEvents()
                    time.sleep(0.02)
                    f = h5py.File(self.path_out_reconstructed_full + '/' + self.folder_name + '.h5', 'r+')
                    vol_proxy = f['Volume']
                    print('volume_proxy.shape', vol_proxy.shape)
                    vol_proxy.resize((vol_proxy.shape[0] + slices_save.shape[0]), axis=0)
                    vol_proxy[i * self.block_size : i * self.block_size + slices_save.shape[0] ,:,:] = slices_save
                    self.progressBar.setValue((i * self.block_size) * 100 / self.A.shape[1])

            i = i + 1

        #set progress bar to 100%
        self.progressBar.setValue(100)
        QtCore.QCoreApplication.processEvents()
        time.sleep(0.02)

        #ungrey the buttons for further use of the program
        self.buttons_activate_load()
        self.buttons_activate_reco()
        self.buttons_activate_crop_volume()
        self.buttons_activate_reco_all()
        print('Done!')

#no idea why we need this, but it wouldn't work without it ;-)
if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)

    main = On_the_fly_CT_tester()
    main.show()
    sys.exit(app.exec_())

#end of code


import unittest
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from worldoftanks.orm.data_model import Base, DataModel
from worldoftanks.orm.data_model import PlayerPersonalDataDetailsModel, PlayerPersonalDataStatisticsModel, \
    PlayerPersonalVehiclesModel, TankopediaInfoModel, TankopediaAchievementsModel, \
    TankopediaVehiclesModel, TankopediaMapsModel, VehiclesStatisticsModel, VehiclesFragsModel, \
    VehiclesAchievementsModel, TankopediaBadgesModel

test_data = {"id": 10, "account_id": "1234"}

class TestModels(unittest.TestCase):
    engine = create_engine('sqlite:///:memory:')
    Session = sessionmaker(bind=engine)
    session = Session()

    def test_db_setUp(self):
        DataModel.create_tables(self.engine)
        # Add all the data into the models here to be evaluated in the methods below.
        self.session.add(PlayerPersonalDataDetailsModel(id=test_data['id'], account_id=test_data['account_id']))
        self.session.add(PlayerPersonalDataStatisticsModel(id=test_data['id']))
        self.session.add(PlayerPersonalVehiclesModel(id=test_data['id']))
        self.session.add(TankopediaInfoModel(id=test_data['id']))
        self.session.add(TankopediaAchievementsModel(id=test_data['id']))
        self.session.add(TankopediaVehiclesModel(id=test_data['id']))
        self.session.add(TankopediaMapsModel(id=test_data['id']))
        self.session.add(VehiclesStatisticsModel(id=test_data['id']))
        self.session.add(VehiclesFragsModel(id=test_data['id']))
        self.session.add(VehiclesAchievementsModel(id=test_data['id']))
        self.session.add(TankopediaBadgesModel(id=test_data['id']))
        self.session.commit()

    def test_player_personal_details_model(self):
        expected = PlayerPersonalDataDetailsModel(id=test_data['id'], account_id=test_data['account_id'])
        query = self.session.query(PlayerPersonalDataDetailsModel).first()
        self.assertEqual(query.account_id, expected.account_id)

    def test_player_personal_statistics_model(self):
        expected = PlayerPersonalDataStatisticsModel(id=test_data['id'])
        query = self.session.query(PlayerPersonalDataStatisticsModel).first()
        self.assertEqual(query.id,  expected.id)

    def test_player_personal_vehicles_model(self):
        expected = PlayerPersonalVehiclesModel(id=test_data['id'])
        query = self.session.query(PlayerPersonalVehiclesModel).first()
        self.assertEqual(query.id,  expected.id)

    def test_tankopedia_information_model(self):
        expected = TankopediaInfoModel(id=test_data['id'])
        query = self.session.query(TankopediaInfoModel).first()
        self.assertEqual(query.id,  expected.id)

    def test_tankopedia_achievements_model(self):
        expected = TankopediaAchievementsModel(id=test_data['id'])
        query = self.session.query(TankopediaAchievementsModel).first()
        self.assertEqual(query.id,  expected.id)

    def test_tankopedia_vehicles_model(self):
        expected = TankopediaVehiclesModel(id=test_data['id'])
        query = self.session.query(TankopediaVehiclesModel).first()
        self.assertEqual(query.id,  expected.id)

    def test_tankopedia_maps_model(self):
        expected = TankopediaMapsModel(id=test_data['id'])
        query = self.session.query(TankopediaMapsModel).first()
        self.assertEqual(query.id,  expected.id)

    def test_vehicle_statistics_model(self):
        expected = VehiclesStatisticsModel(id=test_data['id'])
        query = self.session.query(VehiclesStatisticsModel).first()
        self.assertEqual(query.id,  expected.id)

    def test_vehicle_frags_model(self):
        expected = VehiclesFragsModel(id=test_data['id'])
        query = self.session.query(VehiclesFragsModel).first()
        self.assertEqual(query.id,  expected.id)

    def test_vehicle_achievement_model(self):
        expected = VehiclesAchievementsModel(id=test_data['id'])
        query = self.session.query(VehiclesAchievementsModel).first()
        self.assertEqual(query.id,  expected.id)

    def test_tankopedia_badges_model(self):
        expected = TankopediaBadgesModel(id=test_data['id'])
        query = self.session.query(TankopediaBadgesModel).first()
        self.assertEqual(query.id,  expected.id)

    def test_xdb_tearDown(self):
        # The 'zdb' is not a typo. The database still needs to be available for the rest of the tests to run.
        # The unittest module is taking the methods in an alphabetical order so it had to be prefixed with a "z".
        Base.metadata.drop_all(self.engine)


import pycls.core.config as config
import pycls.core.distributed as dist
import pycls.core.trainer as trainer
from pycls.core.config import cfg
import argparse,sys,os
import torch
if torch.__version__ >= "1.8":
    import torch_npu

def init_process_group(proc_rank, world_size, device_id, port='29588'):
    """Initializes the default process group."""

    # Initialize the process group
    print('Initialize the process group')
    os.environ['MASTER_ADDR'] = '127.0.0.1'
    os.environ['MASTER_PORT'] = '29588'
    torch.distributed.init_process_group(
        backend=cfg.DIST_BACKEND,
        #init_method="tcp://{}:{}".format(cfg.HOST, port),
        world_size=world_size,
        rank=proc_rank,
        #rank=0
    )
    print("init_process_group done")

    # Set the GPU to use
    #torch.cuda.set_device(proc_rank)
    torch.npu.set_device(device_id)
    print('set_device done.', cfg.DIST_BACKEND, world_size, proc_rank)

def main():
    config.load_cfg_fom_args("Train a classification model.")
    config.assert_and_infer_cfg()
    cfg.freeze()

    dist.multi_proc_run(num_proc=cfg.NUM_GPUS, fun=trainer.train_model)

if __name__ == "__main__":
    """Load config from command line arguments and set any specified options."""
    parser = argparse.ArgumentParser(description="Config file options.")
    help_s = "Config file location"
    parser.add_argument("--cfg", dest="cfg_file", help=help_s, required=True, type=str)
    parser.add_argument("--rank_id", dest="rank_id", default=0, type=int)
    parser.add_argument("--device_id", dest="device_id", default=0, type=int)
    help_s = "See pycls/core/config.py for all options"
    parser.add_argument("opts", help=help_s, default=None, nargs=argparse.REMAINDER)
    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit(1)
    args = parser.parse_args()
    print(args)

    config.merge_from_file(args.cfg_file)
    config._C.merge_from_list(args.opts)
    config.assert_and_infer_cfg()
    cfg.freeze()

    init_process_group(proc_rank=args.rank_id, world_size=cfg.NUM_GPUS,  device_id=args.device_id)
    cur_device = torch.npu.current_device()
    print('cur_device: ', cur_device)

    trainer.train_model()


import requests
import common_functions as common
from datetime import datetime

def get_request(url):
    user_agent = common.get_rand_user_agent_from_file("assets/useragents.txt")
    try:
        request = requests.get(url, {'user-agent':user_agent})
        if request.status_code is not 200: return
        return request
    except requests.exceptions.HTTPError as err:
        print('HTTP Error occured')
        print('Response is: {content}'.format(content=err.response.content))
    except requests.exceptions.RequestException as err:
        print('HTTP Error occured')
    except Exception as e:
        print(e)

def log_not_parsing(url, message):
    try:
        current_datetime = datetime.today().strftime("%d_%m_%y-%H_%M_%S")
        log_file = open("logs\\logfile_"+current_datetime+".txt", 'w')

        log_file.write(message)
        log_file.write(datetime.today().strftime("%d-%m-%y %H:%M:%S")+' Not parsing url: '+url)
        log_file.write("/n")
        log_file.close()
    except Exception as e:
        print('Log writing error: '+str(e))
        raise SystemExit()


#Drew Verenna
#basicUI: A basic user interface
#11/03/2018
from traits.api import *    #Just using star for the traits.api and traitsui.api for now since I don't
from traitsui.api import *  #entirely know which parts will be used yet
import json
import ast
import writeDict
import upToChain
import altrpyget

patientRecords = dict()

class basicUI(HasTraits):
    Create_New_Person = Button()
    Add_New_Medication = Button()
    Add_New_Allergy = Button()
    Add_New_Surgery = Button()
    Add_New_Appointment = Button()
    Post_Dictionary = Button()
    Get_Dictionary = Button()

    #Stuff for initialization
    patient_Name_trait = Str("Patient Name")
    patient_DOB_trait = Str("MM/DD/YYYY")
    patient_BloodType_trait = Str("Patient Blood Type")
    patient_Gender_trait = Str("Patient Gender")

    #New Medication
    medication_type_trait = Str("Enter Name of Medication")
    medication_StartDate_trait = Str("MM/DD/YYYY")
    medication_EndDate_trait = Str("MM/DD/YYYY")

    #New Appointment
    appointment_type_trait = Str("Enter Type of Appointment")
    appointment_Doctor_trait = Str("Enter Doctor Name")
    appointment_Date_trait = Str("MM/DD/YYYY")

    #New Surgery
    surgery_type_trait = Str("Enter Type of Surgery")
    surgery_Surgeon_trait = Str("Enter Surgeon Name")
    surgery_date_trait = Str("MM/DD/YYYY")

    #New Allergy
    allergy_type_trait = Str("Enter the type of Allergy")
    allergy_diagnoseDate_trait = Str("Enter the Date of Diagnosis")

    #Post and Get
    post_output_trait = Str("Output reference token")
    get_input_trait = Str("Input reference token")
    get_output_trait = Str("Get Output")

    #Generics used for multiple things
    edit_Author_trait = Str("Enter the name of the Author")
    buffer_text = Str(" ")

    #View
    view = View(Item('patient_Name_trait',style = 'simple', label = 'Patient Name'),
                 Item('patient_DOB_trait',style = 'simple', label = 'Patient Date of Birth'),
                 Item('patient_BloodType_trait',style = 'simple',label = 'Patient Blood Type'),
                 Item('patient_Gender_trait',style = 'simple', label = 'Patient Gender'),
                 Item('Create_New_Person',show_label = False),
                 #Item('buffer_text',style='readonly', label=' ',show_label = False),
                 Item('allergy_type_trait',style = 'simple',label = 'Allergy Type'),
                 Item('allergy_diagnoseDate_trait',style = 'simple', label = 'Date of Diagonsis'),
                 Item('edit_Author_trait',style = 'simple',label = 'Name of Editor'),
                 Item('Add_New_Allergy',show_label = False),
                 #Item('buffer_text',style='readonly', label=' ',show_label = False),
                 Item('medication_type_trait',style = 'simple', label = "Medication Name"),
                 Item('medication_StartDate_trait',style = 'simple', label = "Medication Start Date"),
                 Item('medication_EndDate_trait',style = 'simple', label = "Medication End Date (Enter '-1' if still taking)"),
                 Item('edit_Author_trait',style = 'simple',label = 'Name of Editor'),
                 Item('Add_New_Medication',show_label = False),
                 #Item('buffer_text',style='readonly', label=' ',show_label = False),
                 Item('surgery_type_trait',style = 'simple', label = "Type of Surgery"),
                 Item('surgery_Surgeon_trait',style = 'simple',label = 'Name of Surgeon'),
                 Item('surgery_date_trait',style = 'simple',label = "Date of Surgery"),
                 Item('edit_Author_trait',style = 'simple',label = 'Name of Editor'),
                 Item('Add_New_Surgery',show_label = False),
                 #Item('buffer_text',style='readonly', label=' ',show_label = False),
                 Item('appointment_type_trait',style = 'simple',label = 'Type of Appointment'),
                 Item('appointment_Doctor_trait',style = 'simple',label = 'Doctor Name'),
                 Item('edit_Author_trait',style = 'simple',label = 'Name of Editor'),
                 Item('appointment_Date_trait',style = 'simple',label = 'Date of Appointment'),
                 Item('Add_New_Appointment',show_label = False),
                 #Item('buffer_text',style='readonly', label=' ',show_label = False),
                 Item('Post_Dictionary',show_label = False),
                 Item('post_output_trait',style='simple',label = 'Response',show_label = True),
                 Item('Get_Dictionary',show_label = False),
                 Item('get_input_trait',style = 'simple',label = 'Input',show_label = True),
                 Item('get_output_trait',style = 'readonly',label = 'Response',show_label = True),

                 style = "custom", resizable = True
    )

    def _Create_New_Person_fired(self):
        global patientRecords
        patientRecords = writeDict.setUpPatient(demo.patient_Name_trait,
                                                demo.patient_DOB_trait,
                                                demo.patient_BloodType_trait,
                                                demo.patient_Gender_trait)
        """
        with open("uiPatient.json","w") as fp:
            json.dump(patientRecords, fp, indent = 4)
        """
        print("New Patient done")

    def _Add_New_Medication_fired(self):
        global patientRecords
        patientRecords = writeDict.addMed(patientRecords,
                                          demo.patient_Name_trait,
                                          demo.medication_type_trait,
                                          demo.edit_Author_trait,
                                          demo.medication_StartDate_trait,
                                          demo.medication_EndDate_trait)
        with open("uiPatient.json","w") as fp:
            json.dump(patientRecords, fp, indent = 4)
        print("New Med done")

    def _Add_New_Allergy_fired(self):
        global patientRecords
        patientRecords = writeDict.addAllergy(patientRecords,
                                              demo.patient_Name_trait,
                                              demo.allergy_type_trait,
                                              demo.edit_Author_trait,
                                              demo.allergy_diagnoseDate_trait)
        with open("uiPatient.json","w") as fp:
            json.dump(patientRecords, fp, indent = 4)
        print("New Al Done")

    def _Add_New_Surgery_fired(self):
        global patientRecords
        patientRecords = writeDict.addSurgery(patientRecords,
                                              demo.patient_Name_trait,
                                              demo.surgery_type_trait,
                                              demo.edit_Author_trait,
                                              demo.surgery_Surgeon_trait,
                                              demo.surgery_date_trait)
        with open("uiPatient.json","w") as fp:
            json.dump(patientRecords, fp, indent = 4)
        print("New Surgery Done")

    def _Add_New_Appointment_fired(self):
        global patientRecords
        patientRecords = writeDict.addAppt(patientRecords,
                                           demo.patient_Name_trait,
                                           demo.appointment_type_trait,
                                           demo.edit_Author_trait,
                                           demo.appointment_Doctor_trait,
                                           demo.appointment_Date_trait)
        with open("uiPatient.json","w") as fp:
            json.dump(patientRecords, fp, indent = 4)
        print("New Appointment Done")

    def _Post_Dictionary_fired(self):
        global patientRecords
        ref = upToChain.post(patientRecords)
        demo.post_output_trait = ref

    def _Get_Dictionary_fired(self):
        print("Get Start")
        ref = demo.get_input_trait
        output = altrpyget.get(ref)
        with open("getOutput.json","w") as fp:
            json.dump(ast.literal_eval(output), fp, indent = 4)
        demo.get_output_trait = "Success"

demo = basicUI()

if __name__ == '__main__':
    demo.configure_traits()


from app.model.employee import EmployeeModel
from app.db.configuration import sa
from flask.testing import FlaskClient
from flask import Flask
from typing import Any

class TestEmployeeResourceDelete:

    def test_when_deleted(self, client: FlaskClient, app: Flask, employee_model_data: dict[str, Any]) -> None:
        with app.app_context():
            sa.session.add(EmployeeModel(**employee_model_data))
            sa.session.commit()

        response = client.delete(f"/employees/{employee_model_data['full_name']}")

        assert 200 == response.status_code
        assert b'Deleted employee with id' in response.data

    def test_when_employee_does_not_exist(self, client: FlaskClient) -> None:
        response = client.delete('/employees/Employee')

        assert 400 == response.status_code
        assert b'Employee not found' in response.data


#!/usr/bin/python
# -*- coding: UTF-8 -*-
import amber_actuator as a
import sys, getopt
import json
import datetime

def getFromActuator(actuatorID=1, ipaddr="127.0.0.1"):
    param = []
    j = a.AmberActuator(actuatorID,ipaddr)

    # param = [
    #    j.position.kp,
    #    j.position.ki,
    #    j.position.up_limit,
    #    j.position.down_limit,
    #    j.speed.kp,
    #    j.speed.ki,
    #    j.speed.acceleration,
    #    j.speed.deceleration,
    #    j.speed.speed_limit,
    #    j.current.kp,
    #    j.current.ki,
    #    j.current.current_limit,
    # ]
    dictparam = {
        'Attribute': {
            'ActuatorID': j.actuator_id,
            'Gear': j.attribute.gear,
            'PoleNumber': j.attribute.pole_number,
        },
        'Position': {
            'Kp': j.position.kp,
            'Ki': j.position.ki,
            'UpLimit': j.position.up_limit,
            'DownLimit': j.position.down_limit,
        },
        'Speed': {
            'Kp': j.speed.kp,
            'Ki': j.speed.ki,
            'Acceleration': j.speed.acceleration,
            'Deceleration': j.speed.deceleration,
            'SpeedLimit': j.speed.speed_limit,
        },
        'Current': {
            'Kp': j.current.kp,
            'Ki': j.current.ki,
            'CurrentLimit': j.current.current_limit,
        }
    }
    return dictparam

def main(argv):
    actuatorID = 1
    t = datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S')

    outputfile = t + '(' + str(actuatorID) + ')' + '.json'
    ipaddr = "127.0.0.1"
    try:
        opts, args = getopt.getopt(argv, "h:j:o:a:", ["actuator=", "ofile=", "ipaddr="])
    except getopt.GetoptError:
        print('backup.py -j <jointID(actuatorID)> -o <outputfile> -a <ipAddress>')
        sys.exit(2)
    for opt, arg in opts:
        if opt == '-h':
            print('backup.py  -j <jointID(actuatorID)> -o <outputfile> -a <ipAddress>')
            sys.exit()
        elif opt in ("-j", "--actuator"):
            actuatorID = arg
            outputfile = t + '-j' + str(actuatorID) + '.json'

        elif opt in ("-o", "--ofile"):
            outputfile = arg
        elif opt in ("-a", "--ipaddr"):
            ipaddr = arg
    dictParam = getFromActuator(actuatorID=int(actuatorID), ipaddr=ipaddr)
    with open(outputfile, 'w', encoding='utf-8') as outfile:
        print(f"Backup Parameter from actuator {actuatorID} to {outputfile}")
        json.dump(dictParam, outfile, indent=4)

if __name__ == "__main__":
    main(sys.argv[1:])


import time

from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys

# Simple Program that logins into github provided username and password are correct
# then opens up cleverbot and enters a message

class Bot:
    def __init__(self):
        self.driver = webdriver.Chrome(executable_path='C:/Users/Xander/Downloads/chromedriver_win32/chromedriver.exe')
        self.driver.get("https://www.pandorabots.com/mitsuku/")
        self.driver.maximize_window()

        self.timeout = 10
        element_present = EC.presence_of_element_located((By.XPATH, '/html/body/div/div/div/div[2]/div[2]/button'))
        WebDriverWait(self.driver, self.timeout).until(element_present)
        self.driver.find_element_by_xpath('/html/body/div/div/div/div[2]/div[2]/button').click()  # click login page button

    def getReponse(self):
        self.driver.implicitly_wait(10)
        message_box = self.driver.find_element_by_xpath('/html/body/div/div/div/div/div[4]/div[2]/div')
        responses = message_box.find_elements_by_class_name('pb-bot-response')
        last_response = responses[len(responses) - 1]
        return last_response.text

    def sendNewResponse(self, message):
        self.driver.find_element_by_xpath('/html/body/div/div/div/div/form/div[1]/input').send_keys(message + Keys.ENTER)

def deEmojify(inputString):
    return inputString.encode('ascii', 'ignore').decode('ascii')

bot1 = Bot()
bot2 = Bot()

bot2.sendNewResponse("Which came first, the chick or the egg?")
time.sleep(10)
# print(bot2.getReponse())

bot1_response = ""
bot2_response = ""

while True:
    try:
        bot2_response = deEmojify(bot2.getReponse())
    except:
        bot2_response = bot1_response
    print("Bot 2: "+bot2_response)
    time.sleep(3)
    bot1.sendNewResponse(bot2_response)
    try:
        bot1_response = deEmojify(bot1.getReponse())
    except:
        bot1_response = bot2_response
    print("Bot 1: "+bot1_response)
    time.sleep(3)
    bot2.sendNewResponse(bot1_response)


#!/usr/bin/env python

import yaml
import boto3
import click
import logging

import botocore

from boto3.session import Session

logging.basicConfig(level=logging.INFO)

def disable_security_hub():
    logging.warn('This script will disassociate all member accounts and then '
                 'disable security hub completely in all accounts and all '
                 'regions defined in the config file!')
    proceed = click.prompt('Proceed?', type=bool)

    if not proceed:
        logging.info('Not proceeding!')
        return

    config = get_config()
    member_account_ids = get_member_account_ids(config=config)
    disassociate_member_accounts_from_master(
        profile_name=config.get('security_hub_master_profile'),
        account_ids=member_account_ids
    )
    delete_member_accounts_from_master(
        profile_name=config.get('security_hub_master_profile'),
        account_ids=member_account_ids
    )
    profile_names = config.get('security_hub_member_profiles')
    disable_security_hub_in_member_accounts(profile_names=profile_names)

def disable_security_hub_in_member_accounts(profile_names):
    logging.info('Disabling Security Hub in all Member accounts')
    config = get_config()
    for profile_name in profile_names:
        for region_name in config.get('regions'):
            disable_security_hub_in_region(
                profile_name=profile_name,
                region_name=region_name
            )

def get_master_account_session(region_name, profile_name):
    return Session(
        region_name=region_name,
        profile_name=profile_name
    )

def disassociate_member_accounts_from_master(profile_name, account_ids):
    config = get_config()
    for region_name in config.get('regions'):
        session = get_master_account_session(
            region_name=region_name,
            profile_name=profile_name
        )
        security_hub_client = session.client('securityhub')

        logging.info('Disassociating all member accounts from master for '
                     'region %s' % region_name)
        try:
            security_hub_client.disassociate_members(AccountIds=account_ids)
        except botocore.exceptions.ClientError as exception:
            if exception.response['Error']['Code'] == 'UnrecognizedClientException':
                logging.info('Ignoring region %s, probably not enabled' % region_name)

def delete_member_accounts_from_master(profile_name, account_ids):
    config = get_config()
    for region_name in config.get('regions'):
        session = get_master_account_session(
            region_name=region_name,
            profile_name=profile_name
        )
        security_hub_client = session.client('securityhub')

        logging.info('Deleting all member accounts from master for '
                     'region %s' % region_name)
        try:
            security_hub_client.delete_members(AccountIds=account_ids)
        except botocore.exceptions.ClientError as exception:
            if exception.response['Error']['Code'] == 'UnrecognizedClientException':
                logging.info('Ignoring region %s, probably not enabled' % region_name)

def get_member_account_ids(config):
    logging.info('Getting all member account IDs from profiles in config')
    return [
        get_account_id_from_profile(profile_name=profile_name)
        for profile_name in config.get('security_hub_member_profiles')
    ]
def get_account_id_from_profile(profile_name):
    session = Session(
        profile_name=profile_name
    )
    sts_client = session.client('sts')
    response = sts_client.get_caller_identity()
    return response['Account']

def disable_security_hub_in_region(profile_name, region_name):
    logging.info('Disabling SecurityHub for %s in %s '
                 'region' % (profile_name, region_name))
    session = Session(
        region_name=region_name,
        profile_name=profile_name
    )
    security_hub_client = session.client('securityhub')
    try:
        security_hub_client.disable_security_hub()
    except botocore.exceptions.ClientError as exception:
        if exception.response['Error']['Code'] == 'UnrecognizedClientException':
            logging.info('Ignoring region %s, probably not enabled' % region_name)

def get_config():
    with open('config.yml') as yaml_file:
        config = yaml.safe_load(yaml_file)
    return config

if __name__ == '__main__':
    disable_security_hub()