import unittest
import mesh
from os import path
from os.path import dirname
from nose.plugins.attrib import attr

@attr(level = 'standard')
class TestMesh(unittest.TestCase):

    def setUp(self):
        pass

    def test_make_simple_hexagonal_mesh(self):
        """create a 2 by 2 hexagonal mesh and test the number
        of elements, their number of nodes, etc"""
        simple_mesh = mesh.creation.generate_hexagonal(2,2)

        # plotting doesn't work without ids assigned to it

        simple_mesh.plot(path.join(dirname(__file__),'output','hexagonal_mesh.pdf'))
        self.assertEqual(simple_mesh.get_num_nodes(), 16)
        self.assertEqual(simple_mesh.get_num_elements(), 4)
        for element in simple_mesh.elements:
            self.assertEqual(element.get_num_nodes(), 6)

    def test_nodes_are_ordered_counter_clockwise_in_each_element(self):
        """Create a simple mesh and make sure that the nodes are ordered clockwise
        in each element.
        """
        simple_mesh = mesh.creation.generate_hexagonal(7,10)
        for element in simple_mesh.elements:
            self.assertEqual(element.calculate_area(), 1.0)

        second_simple_mesh = mesh.creation.generate_hexagonal(3,3)
        for element in second_simple_mesh.elements:
            self.assertEqual(element.calculate_area(), 1.0)

    def test_generate_vornoi_padding_centroids(self):
        """test whether the random mesh generator draws the padding centroids correctly"""

        random_mesh_generator = mesh.creation.RandomTesselationGenerator(5,3)
        padding_centroids = random_mesh_generator.generate_padding_voronoi_centroids()

        for centroid in padding_centroids:
            assert( ( centroid[0] < -3.5 and centroid[0] > -5.5 ) or
                    ( centroid[0] > 9.5 and centroid[0] < 11.5 ) or
                    ( centroid[1] < -3.5 and centroid[1] > -5.5 ) or
                    ( centroid[1] > 7.5 and centroid[1] < 9.5 ) )

            if ( centroid[0] < -3.5 and centroid[0] > -5.5 ) :
                assert( centroid[1] > -5.5 and centroid[1] < 9.5 )
            elif ( ( centroid[0] > 9.5 and centroid[0] < 11.5 ) ):
                assert( centroid[1] > -5.5 and centroid[1] < 9.5 )
            elif ( ( centroid[1] < -3.5 and centroid[1] > -5.5 ) ):
                assert( centroid[0] > -5.505 and centroid[1] < 11.5 )
            elif ( ( centroid[1] > 7.5 and centroid[1] < 9.5 ) ):
                assert( centroid[0] > -5.505 and centroid[1] < 11.5 )

    def test_create_random_tesselation(self):
        """Create a mesh following Luisma Escuderos algorithm for
        mesh creation using voronoi tesselations"""

        random_mesh = mesh.creation.generate_random_tesselation(15,10, 5)

        random_mesh.plot(path.join(dirname(__file__),'output','random_mesh.pdf'))
        for element in random_mesh.elements:
            self.assertGreater(element.calculate_area(), 0.0)
            for node in element.nodes:
                self.assertNotAlmostEqual(node.position[0], -10.101)
                self.assertNotAlmostEqual(node.position[1], -10.101)
            this_centroid = element.calculate_centroid()
            self.assertGreater(this_centroid[0] , 0.0)
            self.assertGreater(this_centroid[1] , 0.0)
            self.assertLess(this_centroid[0] , 15.5)
            self.assertLess(this_centroid[1] , 10.5)

        average_cell_area = random_mesh.calculate_average_element_area()
        self.assertGreater(average_cell_area, 0.9)
        self.assertLess(average_cell_area, 1.1)

        total_area = random_mesh.calculate_total_area()
        self.assertGreater(total_area, 135)
        self.assertLess(total_area, 165.0)

        self.assertGreater(random_mesh.get_num_elements(), 135)
        self.assertLess(random_mesh.get_num_elements(), 165)


import logging
from datetime import timedelta

from django.core.management import BaseCommand
from django.db.models import Max
from django.utils import timezone

from apps.booking.emails import send_pre_booking_cancelled
from apps.booking.models import Booking, Status, update_status_log

PREBOOKING_LIFETIME = 48

logger = logging.getLogger(__name__)

class Command(BaseCommand):
    help = (
        f'Меняет статус бронирования на cancelled, если бронирование '
        'находится в статусе inwork или pending больше {PREBOOKING_LIFETIME} '
        'часов'
    )

    def handle(self, *args, **options):
        # print(logger)
        # self.stdout.write(f"----- Checking bookings... -----")
        logger.debug("Checking bookings...")
        treshold = timezone.now() - timedelta(hours=PREBOOKING_LIFETIME)
        expired_prebookings = Booking.objects.annotate(
            last_record=Max('statuses__created_at')
        ).filter(
            status__in=[Status.inwork, Status.pending],
            last_record__lt=treshold
        )
        # print(prebookings.values())
        # print(f"{treshold=}")
        for booking in expired_prebookings:
            logger.debug(f'Cancelling booking {booking}...')
            booking.status = Status.cancelled
            booking.save()
            logger.debug('Booking cancelled')
            update_status_log(booking=booking, status=Status.cancelled)
            send_pre_booking_cancelled(booking)
            logger.info(f"Автоматическая отмена бронирования '{booking}'")


import os
os.environ["OMP_NUM_THREADS"] = "1"
os.environ["OPENBLAS_NUM_THREADS"] = "1"
os.environ["MKL_NUM_THREADS"] = "1"
os.environ["VECLIB_MAXIMUM_THREADS"] = "1"
os.environ["NUMEXPR_NUM_THREADS"] = "1"
import math
import numpy as np
import torch
from tqdm import trange
from random import random
from torch.utils import data
import torch.nn as nn
import csv
torch.set_num_threads(1)

class ReplayBuffer(object):
    def __init__(self, state_dim, action_dim, device, max_size=int(1e6)):
        self.max_size = max_size
        self.ptr = 0
        self.size = 0

        self.state = np.zeros((max_size, state_dim))
        self.action = np.zeros((max_size, action_dim))
        self.next_state = np.zeros((max_size, state_dim))
        self.reward = np.zeros((max_size, 1))
        self.not_done = np.zeros((max_size, 1))

        # self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
        self.device = device

    def add(self, state, action, next_state, reward, done):
        self.state[self.ptr] = state
        self.action[self.ptr] = action
        self.next_state[self.ptr] = next_state
        self.reward[self.ptr] = reward
        self.not_done[self.ptr] = 1. - done

        self.ptr = (self.ptr + 1) % self.max_size
        self.size = min(self.size + 1, self.max_size)

    def sample(self, batch_size):
        ind = np.random.randint(0, self.size, size=batch_size)

        return (
            torch.FloatTensor(self.state[ind]).to(self.device),
            torch.FloatTensor(self.action[ind]).to(self.device),
            torch.FloatTensor(self.next_state[ind]).to(self.device),
            torch.FloatTensor(self.reward[ind]).to(self.device),
            torch.FloatTensor(self.not_done[ind]).to(self.device)
        )

def apply_norm(dataset, norm):
    """Normalizes data given a (mean, std) tuple"""
    return (dataset - norm[0]) / (norm[1] + 1e-8)

def unapply_norm(dataset, norm):
    """Inverse operation of _apply_norm"""
    return dataset*norm[1] + norm[0]

def train_model_es(model,
                   x_list,
                   y_list,
                   optimizer,
                   criterion=torch.nn.MSELoss(),
                   max_epochs=100,
                   v_size=0.2,
                   patience=10,
                   num_cores=30,
                   device="cpu",
                   checkpoint_name='checkpoint.pt'):
    """Trains a model from given labels with early stopping

    :param model: the model to be trained
    :type model: torch.nn.module
    :param x_list: list of features (same size as y_list)
    :type x_list: list
    :param y_list: list of labels (same size as x_list)
    :type y_list: list
    :param optimizer: optimizer
    :type optimizer: optimizer
    :param criterion: criterion
    :type criterion: criterion
    :param max_epochs: maximum number of epochs
    :type max_epochs: int
    :param v_size: size of validation set [0,1)
    :type v_size: float
    :param patience: number of epochs to wait before early stopping
    :type patience: int
    """
    # for visualizing plots on tensorboard
    # writer = SummaryWriter(log_dir='data/TrainingLogs/'+str(int(random()*100000)))
    class_sample_count = np.array([len(np.where(y_list == t)[0]) for t in np.unique(y_list)])

    valid_size = int(np.floor(len(x_list) * v_size))
    train_size = len(x_list) - valid_size

    # Convert to nd-array
    x_list = np.array(x_list)
    y_list = np.array(y_list)

    # Convert to torch tensor
    x_list = torch.tensor(x_list).float()
    y_list = torch.tensor(y_list).float()

    # Split into training and validation sets
    train_data, valid_data = data.random_split(
        data.TensorDataset(x_list, y_list),
        [train_size, valid_size])

    batch_size = math.floor(1024 / 2.0) * 2  # round batchsize to the nearest even number
    print('BATCH SIZE : ', batch_size)
    drop_bool = np.floor(np.sum(class_sample_count) / batch_size) == np.sum(class_sample_count) / batch_size
    print('drop_last : ', not drop_bool)

    train_loader = data.DataLoader(
        dataset=train_data,
        shuffle=True,
        batch_size=512,
        drop_last=not drop_bool,
        num_workers=0)

    valid_loader = data.DataLoader(
        dataset=valid_data,
        shuffle=False,
        batch_size=512,
        num_workers=0)

    # train the model
    epoch = 0
    best_epoch = 0
    best_loss = None
    while (epoch < max_epochs and
           epoch < best_epoch+patience):
        epoch += 1
        train_losses = []
        valid_losses = []

        # Train for one epoch
        model.train() # prep for training
        for x_batch, y_batch in train_loader:
            x_batch = x_batch.to(device)
            y_batch = y_batch.to(device)
            y_pred = model.forward(x_batch)
            loss = criterion(y_pred, y_batch)
            print('\repoch: '+str(epoch)+ ' loss: '+str(loss.item()), end='')
            # Zero the gradients
            optimizer.zero_grad()
            # perform a backward pass (backpropagation)
            loss.backward()
            # Update the parameters
            optimizer.step()
            train_losses.append(loss.item())

        # Validate model
        model.eval() # prep for evaluation
        for x_batch, y_batch in valid_loader:
            x_batch = x_batch.to(device)
            y_batch = y_batch.to(device)
            y_pred = model.forward(x_batch)
            loss = criterion(y_pred, y_batch)
            valid_losses.append(loss.item())

        train_loss = np.average(train_losses)
        valid_loss = np.average(valid_losses)
        print('\ntraining loss:', train_loss)
        print('validation loss:', valid_loss)
        if best_loss is None or valid_loss < best_loss:
            best_epoch = epoch
            best_loss = valid_loss
            torch.save(model.state_dict(), checkpoint_name+'.pt')
        print('current best:', best_loss, '(epoch', best_epoch, ')')

    model.load_state_dict(torch.load(checkpoint_name+'.pt'))
    os.remove(checkpoint_name+'.pt')

def update_forward_model(model, Ts, checkpoint_name='xyz'):
    """
    function to update the forward dynamics model
    :param model: ANN defining the forward dynamics model
    :param Ts: Transitions stored in a list
    :return: norm of input and output for the current trained model
    """
    print('--- UPDATING THE FORWARD DYNAMICS MODEL --- ')
    print('           --- PARSING DATA ---             ')

    X_list = []
    Y_list = []

    for T in Ts:
        for i in range(len(T)-1):
            X_list.append(np.hstack((T[i][0], T[i][1]))) # current state, current action
            Y_list.append(np.hstack((T[i+1][0]-T[i][0], T[i][2]))) # delta next state, current reward

    X_norm = (np.mean(X_list, axis=0), np.std(X_list, axis=0))
    Y_norm = (np.mean(Y_list, axis=0), np.std(Y_list, axis=0))

    X_list_normalized = apply_norm(X_list ,X_norm)
    Y_list_normalized = apply_norm(Y_list, Y_norm)

    criterion = torch.nn.MSELoss()
    optimizer = torch.optim.Adam(model.parameters(), lr=3e-4)

    print('--- TRAINING THE FORWARD DYNAMICS MODEL --- ')

    train_model_es(model,
                   X_list_normalized,
                   Y_list_normalized,
                   optimizer,
                   criterion,
                   checkpoint_name=checkpoint_name+'_fwd.pt')

    print('            --- FORWARD MODEL TRAINING DONE ---           ')

    return X_norm, Y_norm

def update_backward_model(model, Ts, checkpoint_name='xyz'):
    """
    function to update the backward dynamics model
    :param model: ANN defining the forward dynamics model
    :param Ts: Transitions stored in a list
    :return: norm of input and output for the current trained model
    """
    print('--- UPDATING THE BACKWARD DYNAMICS MODEL --- ')
    print('           --- PARSING DATA ---             ')

    X_list = []
    Y_list = []

    for T in Ts:
        for i in range(len(T)-1):
            # X_list.append(np.hstack((T[i+1][0], T[i][1]))) # next state, current action
            # Y_list.append(np.hstack((T[i][0]-T[i+1][0], T[i][2]))) # delta current state, current reward
            X_list.append(np.hstack((T[i][0], T[i + 1][0])))  # current state, next state
            Y_list.append(np.hstack((T[i][1], T[i][2])))  # current action, current reward

    X_norm = (np.mean(X_list, axis=0), np.std(X_list, axis=0))
    Y_norm = (np.mean(Y_list, axis=0), np.std(Y_list, axis=0))

    X_list_normalized = apply_norm(X_list,X_norm)
    Y_list_normalized = apply_norm(Y_list,Y_norm)

    criterion = torch.nn.MSELoss()
    optimizer = torch.optim.Adam(model.parameters(), lr=3e-4)

    print('--- TRAINING THE INVERSE DYNAMICS MODEL --- ')

    train_model_es(model,
                   X_list_normalized,
                   Y_list_normalized,
                   optimizer,
                   criterion,
                   checkpoint_name=checkpoint_name+'_bwd.pt')

    print('        --- INVERSE MODEL TRAINING DONE ---           ')

    return X_norm, Y_norm

def set_seed(env, seed):
    env.seed(seed)
    torch.manual_seed(seed)
    np.random.seed(seed)

class Logger:
    def __init__(self, log_name, log_root):
        self.log_name = log_name
        self.log_path = log_root + log_name + '/' + 'log.csv'
        if not os.path.exists(log_root + log_name + '/'): os.makedirs(log_root + log_name + '/')
        print('## STARTED LOGGER ##')

    def log(self,
            state,
            action,
            reward,
            done,
            episode_num,
            episode_reward,
            episode_timesteps,
            total_timesteps,):
        with open(self.log_path, 'a', newline='') as csvfile:
            csvwriter = csv.writer(csvfile)
            csvwriter.writerow([reward, done, episode_num, episode_reward, episode_timesteps, total_timesteps])

def _duplicate_batch_wise(arr, batch_size: int, device, return_tensor=False):
    arr = np.asarray(arr).copy()
    if(len(arr.shape)<2) : arr = np.expand_dims(arr, axis=0)
    if return_tensor: return torch.tensor(np.repeat(arr, batch_size, axis=0)).to(device)
    else: return np.repeat(arr, batch_size, axis=0).to(device)


# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render, redirect, HttpResponse
from django.contrib.messages import error
# from datetime import datetime

from .models import User

# Create your VIEWS here.
#Views consist the bulk of your logic. I have basically none but I try.
#Use print statements ALL OVER your code to make sure things are working as they should.
def index(request):
    print ('GGGRRRR... THIS IS THE INDEX!!!!!!!')
    context = {
        'users': User.objects.all()
    } #Dictionary to hold a QUERY for use in the index.html page. We used User.objects.all() because we want to see ALL the data!
    return render(request, 'users_app/index.html', context) #Renders the template and CONTEXT is stated here because you want to pass that info onto the template

def new(request):
    print ('THIS IS THE FORM!!!!') #BLEH!
    return render(request, 'users_app/new.html') #Renders the template

def edit(request, id): #id is stated here because you want the id to be passed onto the URL
#FORM RENDERS BUT DOES NOT DO ANYTHING. EDIT AND UPDATE VIEWS NEEDS WORK!
    print ('THIS IS EDITING!!!!')
    user = User.objects.get(id=id) #QUERY to get specific id and attach it to a variable
    context = {
        'user': user
    } #Dictionary containing user information for use in this template/view
    return render(request, 'users_app/edit.html', context)

def show(request, id): #id is stated here because you want the id to be passed onto the URL
    print ('THIS IS ME SHOWING YOU STUFF!!!!!')
    user = User.objects.get(id=id) #QUERY to get the id of the specific person to be displayed
    context = {
        'user': user
    } #Dictionary containing user information for use in this template/view
    return render(request, 'users_app/show.html', context) #Renders a template and CONTEXT is stated here because you want to pass that info onto the template

def create(request):
#USER IS CREATED BUT ERROR MESSAGES DO NOT APPEAR. FIX!
    errors = User.objects.basic_validator(request.POST)
    if len(errors):
        print ('CREATE IF PATH')
        for error in errors.iteritems():
            messages.error(request, error)
        return redirect('/new') #If errors are prsent, stay in the new.html to flash the error messages
    else: #If there are NO errors, this code will execute and proceed to create a new user which will be added to the index.html
        print ('CREATE ELSE PATH')
        User.objects.create(
            first_name=request.POST['first_name'],
            last_name=request.POST['last_name'],
            email=request.POST['email'],
        ) #QUERY that assigns variable names using the form inputs the user provided
        return redirect('/') #As soon the code is executes, a user is created, go back to index.html

def destroy(request, id): #The id is needed to attach to the URL to keep track of who's being deleted
    user = User.objects.get(id=id) #QUERY to get the specific id
    user.delete() #User with the id is deleted
    return redirect('/') #Goes back to index.html once successful

def update(request, id):
    errors = User.objects.basic_validator(request.POST)
    if len(errors):
        print ('UPDATE IF PATH')
        for error in errors.iteritems():
            messages.error(request, error)
    else:
        print ('UPDATE ELSE PATH')
        user = User.objects.get(id = id)
        user.first_name = request.POST['first_name']
        user.last_name = request.POST['last_name']
        user.email = request.POST['email']
        user.save()
        return redirect('show/')


# To train and test non-isotropic randomized smoothing.

from mnist_train import Net
from smoothing import Smooth
from datasets import get_dataset, imagenet_trainset, get_input_dim, get_num_classes, KittiDataset
from architectures import get_architecture

import argparse
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms, models
from torchvision.utils import save_image
from torch.optim.lr_scheduler import StepLR
from torch.utils.tensorboard import SummaryWriter

# CUSTOM: Add an option for your model
def get_dataset_name(model):
    """Converts model name to corresponding dataset name.
    Args:
        model (str): Name of model.
    Returns:
        (str) Name of dataset.
    """
    if model == "mnist":
        return "mnist"
    elif model == "fashion_mnist":
        return "fashion_mnist"
    elif model == "cifar10" or model == "cifar10_robust":
        return "cifar10"
    elif model == "imagenet" or model == "imagenet_robust":
        return "imagenet"
    elif model == "kitti":
        return "kitti"

# CUSTOM: Add an option for your model
def load_dataset(dataset, batch_size, test_batch_size, use_cuda):
    """Loads the train and test loader for a dataset.
    Args:
        dataset (str): Name of dataset.
        batch_size (int): Batch size of train set.
        test_batch_size (int): Batch size of test set.
        use_cuda (bool): Use cuda if true.
    Returns:
        (torch.utils.data.DataLoader, torch.utils.data.DataLoader)
        Train dataset dataloader, test dataset dataloader.
    """
    if dataset == "mnist":
        kwargs = {'num_workers': 1, 'pin_memory': True} if use_cuda else {}
        train_loader = torch.utils.data.DataLoader(
            datasets.MNIST('../data', train=True, download=True,
                        transform=transforms.Compose([
                            transforms.ToTensor(),
                            transforms.Normalize((0.1307,), (0.3081,))
                        ])),
            batch_size=batch_size, shuffle=True, **kwargs)
        test_loader = torch.utils.data.DataLoader(
            datasets.MNIST('../data', train=False, transform=transforms.Compose([
                            transforms.ToTensor(),
                            transforms.Normalize((0.1307,), (0.3081,))
                        ])),
            batch_size=test_batch_size, shuffle=True, **kwargs)
    elif dataset == "fashion_mnist":
        kwargs = {'num_workers': 1, 'pin_memory': True} if use_cuda else {}
        train_loader = torch.utils.data.DataLoader(
            datasets.FashionMNIST('datasets', train=True, download=True,
                        transform=transforms.Compose([
                            transforms.ToTensor(),
                            transforms.Normalize((0.1307,), (0.3081,))
                        ])),
            batch_size=batch_size, shuffle=True, **kwargs)
        test_loader = torch.utils.data.DataLoader(
            datasets.FashionMNIST('datasets', train=False, transform=transforms.Compose([
                            transforms.ToTensor(),
                            transforms.Normalize((0.1307,), (0.3081,))
                        ])),
            batch_size=test_batch_size, shuffle=True, **kwargs)
    elif dataset == "cifar10":
        kwargs = {'num_workers': 1, 'pin_memory': True} if use_cuda else {}
        train_loader = torch.utils.data.DataLoader(get_dataset("cifar10", "train"), batch_size=batch_size, shuffle=True, **kwargs)
        test_loader = torch.utils.data.DataLoader(get_dataset("cifar10", "test"), batch_size=test_batch_size, shuffle=True, **kwargs)
    elif dataset == "imagenet":
        kwargs = {'num_workers': 1, 'pin_memory': True} if use_cuda else {}
        train_set, test_set = imagenet_trainset()
        train_loader = torch.utils.data.DataLoader(train_set, batch_size=batch_size, shuffle=True, **kwargs)
        test_loader = torch.utils.data.DataLoader(test_set, batch_size=test_batch_size, shuffle=True, **kwargs)
    elif dataset == "kitti":
        kwargs = {'num_workers': 1, 'pin_memory': True} if use_cuda else {}
        data_path = 'data/train/'
        dataset = KittiDataset('../datasets/kitti')
        # print(len(dataset))
        train_set, test_set = torch.utils.data.random_split(dataset, [6733, 748]) # 7481
        train_loader = torch.utils.data.DataLoader(train_set, batch_size=batch_size, shuffle=True, **kwargs)
        test_loader = torch.utils.data.DataLoader(test_set, batch_size=test_batch_size, shuffle=True, **kwargs)
    else:
        raise Exception("Must enter a valid dataset name")
    return train_loader, test_loader

# CUSTOM: Add an option for your model
def load_model(model_name, device):
    """Loads the model.
    Args:
        model_name (str): Name of model.
        device (torch.device): Device to load the model onto.
    Returns:
        (nn.Module) Loaded Pytorch model.
    """
    if model_name == "mnist":
        model = Net().to(device)
        model.load_state_dict(torch.load('models/mnist_cnn.pt'))
    elif model_name == "fashion_mnist":
        model = Net().to(device)
        model.load_state_dict(torch.load('models/fashion_mnist_cnn.pt'))
    elif model_name == "cifar10":
        checkpoint = torch.load("models/pretrained_models/cifar10/finetune_cifar_from_imagenetPGD2steps/PGD_10steps_30epochs_multinoise/2-multitrain/eps_64/cifar10/resnet110/noise_0.12/checkpoint.pth.tar")
        model = get_architecture(checkpoint["arch"], "cifar10")
        # model.load_state_dict(checkpoint['state_dict'])
        model.load_state_dict(torch.load('models/cifar10.pt'))
    elif model_name == "cifar10_robust":
        checkpoint = torch.load("models/pretrained_models/cifar10/finetune_cifar_from_imagenetPGD2steps/PGD_10steps_30epochs_multinoise/2-multitrain/eps_512/cifar10/resnet110/noise_0.12/checkpoint.pth.tar")
        model = get_architecture(checkpoint["arch"], "cifar10")
        model.load_state_dict(checkpoint['state_dict'])
    elif model_name == "imagenet":
        # checkpoint = torch.load("models/pretrained_models/imagenet/PGD_1step/imagenet/eps_127/resnet50/noise_0.25/checkpoint.pth.tar")
        # model = get_architecture(checkpoint["arch"], "imagenet")
        # model.load_state_dict(checkpoint['state_dict'])
        model = models.resnet50(pretrained=True).cuda()
    elif model_name == "imagenet_robust":
        checkpoint = torch.load("models/pretrained_models/imagenet/PGD_1step/imagenet/eps_1024/resnet50/noise_0.25/checkpoint.pth.tar")
        model = get_architecture(checkpoint["arch"], "imagenet")
        model.load_state_dict(checkpoint['state_dict'])
    elif model_name == "kitti":
        model = models.resnet50(pretrained=False).cuda()
        model.load_state_dict(torch.load('models/kitti.pt'))
    else:
        raise Exception("Must enter a valid model name")
    return model

def calculate_objective(sigma, icdf_pabar):
    """Calculates the certified area objective.
    Args:
        sigma (torch.tensor): Sigma vector.
        icdf_pabar (torch.tensor/np.array/float): Inverse Gaussian CDF of paBar.
    Returns:
        (torch.tensor) Certified area objective, single element tensor.
    """
    sigma = torch.abs(sigma)  # For log calculation. Negative or positive makes no difference in our formulation.
    eps = 0.000000001 # To prevent log from returning infinity.
    if isinstance(icdf_pabar, float):
        icdf_pabar = torch.tensor(icdf_pabar)
    elif not torch.is_tensor(icdf_pabar):
        icdf_pabar = torch.tensor(icdf_pabar.item())
    objective = torch.sum(torch.log(sigma+eps)) + torch.numel(sigma) * torch.log(icdf_pabar+eps)
    return objective

def train(args, smoothed_classifier, device, train_loader, optimizer, epoch, writer):
    """Optimizes sigma for the certified area objective, writes results to tensorboard.
    Args:
        args (argparse.ArgumentParser): Arguments containing N_train and batch_smooth.
        smoothed_classifier (smoothing.Smooth): Randomized smoother.
        device (torch.device): Device to load the data onto.
        train_loader (torch.utils.data.DataLoader): Train dataset loader.
        optimizer (torch.optim.Optimizer): Optimizer for smoother's sigma vector.
        epoch (int): Epoch of optimization process.
        writer (torch.utils.tensorboard.SummaryWriter): Writer for tensorboard data.
    """
    avg_objective = torch.tensor([0.0]).cuda()
    avg_accuracy = 0
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad()
        objective = torch.tensor([0.0]).cuda()
        accuracy = 0
        for i in range(data.shape[0]):
            prediction, icdf_pabar = smoothed_classifier.certify_training(data[i], args.N_train, args.batch_smooth, target[i])
            if prediction == target[i]:  # Add 0 to all if it predicts wrong.
                accuracy += 1
                objective += calculate_objective(smoothed_classifier.sigma, icdf_pabar)
        avg_objective += objective
        avg_accuracy += accuracy
        if accuracy != 0:
            objective /= accuracy  # Want to average objectives that are actually certified
            accuracy /= data.shape[0]
            loss = -objective
            loss.backward()
            optimizer.step()
        if batch_idx % args.log_interval == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tObjective: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset),
                100. * batch_idx / len(train_loader), objective.item()))
            print('Accuracy: {:.5f} \t sigma mean: {:.5f} \t sigma stddev: {:.5f}'.format(
                accuracy,
                torch.abs(smoothed_classifier.sigma).mean().item(),
                torch.abs(smoothed_classifier.sigma).std().item()))
    # Write avg objective and accuracy to tensorboard
    avg_objective /= avg_accuracy  # Divide by number of correctly classified points
    avg_accuracy /= len(train_loader.dataset)
    writer.add_scalar('objective/train', avg_objective, epoch-1)
    writer.add_scalar('accuracy/train', avg_accuracy, epoch-1)

def test(args, smoothed_classifier, device, test_loader, epoch, writer, comment):
    """Tests smoothed classifer for certified area objective, writes results to tensorboard.
    Args:
        args (argparse.ArgumentParser): Arguments containing N0, N, alpha, and batch_smooth.
        smoothed_classifier (smoothing.Smooth): Randomized smoother.
        device (torch.device): Device to load the data onto.
        test_loader (torch.utils.data.DataLoader): Test dataset loader.
        epoch (int): Epoch of optimization process.
        writer (torch.utils.tensorboard.SummaryWriter): Writer for tensorboard data.
        comment (str): String to append to use for saved sigma filenames.
    """
    objective = 0
    accuracy = 0
    with torch.no_grad():
        for data, target in test_loader:
            data, target = data.to(device), target.to(device)
            for i in range(data.shape[0]):
                prediction, icdf_pabar = smoothed_classifier.certify(data[i], args.N0, args.N, args.alpha, args.batch_smooth)
                if prediction == target[i]:  # Add 0 to all if it predicts wrong.
                    accuracy += 1
                    objective += calculate_objective(smoothed_classifier.sigma, icdf_pabar)
        objective /= accuracy  # Want to average objectives that are actually certified
        accuracy /= len(test_loader.dataset)
        print('\nAverage Test objective: {:.4f}'.format(objective))
        print('Percent correct: {:.4f}'.format(accuracy))
        print('Sigma avg: {:.4f}\n'.format(torch.abs(smoothed_classifier.sigma).mean()))
        writer.add_scalar('objective/test', objective, epoch-1)
        writer.add_scalar('accuracy/test', accuracy, epoch-1)
        writer.add_scalar('sigma/mean', torch.abs(smoothed_classifier.sigma).mean(), epoch-1)
        writer.add_scalar('sigma/stddev', torch.abs(smoothed_classifier.sigma).std(), epoch-1)
        sigma_img = torch.abs(smoothed_classifier.sigma)  # For image. Negative or positive makes no difference in our formulation.
        sigma_img = sigma_img - sigma_img.min()
        sigma_img = sigma_img / sigma_img.max()
        writer.add_image('sigma_linear_normalized', sigma_img, epoch-1)
        if args.save_sigma:
            torch.save(smoothed_classifier.sigma, 'models/sigmas/sigma' + comment + '_EPOCH_' + str(epoch) + '.pt')

def main():
    parser = argparse.ArgumentParser(description='Optimize certified area')
    parser.add_argument('--model', type=str,
                        help='filepath to saved model parameters')
    parser.add_argument('--lr', type=float, default=0.001,
                        help='learning rate')
    parser.add_argument('--gamma', type=float, default=0.8,
                        help='learning rate step gamma')
    parser.add_argument('--batch_size', type=int, default=2,
                        help='input batch size for training')
    parser.add_argument('--test_batch_size', type=int, default=2,
                        help='input batch size for testing')
    parser.add_argument("--sigma", type=float, default=0.01,
                        help="constant elements in sigma vector are initialized to")
    parser.add_argument("--sigma_add", type=float, default=0.01,
                        help="amount to add to sigma per sub-epoch if doing sigma modulation")
    parser.add_argument('--epochs', type=int, default=200,
                        help='number of epochs to train')
    parser.add_argument('--sub_epochs', type=int, default=10,
                        help='number of epochs to optimize for per initialization if doing sigma modulation')
    parser.add_argument('--comment_add', type=str, default="",
                        help='string to add to the end of name used for tensorboard and sigma filesaves')
    parser.add_argument('--sigma_mod', action='store_true', default=False,
                        help='modulate sigma, re-initialize after sub-epochs to train multiple times')
    parser.add_argument('--save_sigma', action='store_true', default=True,
                        help='save the sigma vector')
    parser.add_argument("--batch_smooth", type=int, default=32,
                        help="batch size for smoothed classifer when sampling random noise")
    parser.add_argument("--N0", type=int, default=32,
                        help='number of samples used in when estimating smoothed classifer prediction')
    parser.add_argument("--N", type=int, default=256,
                        help="number of samples used when estimating paBar")
    parser.add_argument("--N_train", type=int, default=32,
                        help="number of samples to use in training when the smoothed classifer samples noise")
    parser.add_argument("--alpha", type=float, default=0.001,
                        help="probability that paBar is not a true lower bound on pA")
    parser.add_argument('--no_cuda', action='store_true', default=False,
                        help='disables CUDA training')
    parser.add_argument('--seed', type=int, default=1,
                        help='random seed')
    parser.add_argument('--log-interval', type=int, default=10,
                        help='how many batches to wait before logging training status')
    args = parser.parse_args()

    comment = '_MODEL_' + args.model + '_LR_' + str(args.lr) + '_GAMMA_' + str(args.gamma)
    if args.sigma_mod:
        comment = comment + '_SIGMA_MOD'
    comment = comment + args.comment_add

    torch.manual_seed(args.seed)
    use_cuda = not args.no_cuda and torch.cuda.is_available()
    device = torch.device("cuda" if use_cuda else "cpu")
    train_loader, test_loader = load_dataset(get_dataset_name(args.model), args.batch_size, args.test_batch_size, use_cuda)
    # for batch_idx, (data, target) in enumerate(train_loader):
    #     if batch_idx < 10:
    #         print(batch_idx, data.size(), target)
    model = load_model(args.model, device)
    model.eval()
    writer = SummaryWriter(comment=comment)
    if args.sigma_mod:
        sigma = args.sigma
        for epoch in range(1, args.epochs + 1):
            smoother = Smooth(model, sigma=sigma,
                              num_classes=get_num_classes(get_dataset_name(args.model)),
                              data_shape=get_input_dim(get_dataset_name(args.model)))
            optimizer = optim.Adam([smoother.sigma], lr=args.lr)
            scheduler = StepLR(optimizer, step_size=1, gamma=args.gamma)
            for sub_epoch in range(1, args.sub_epochs + 1):
                effective_epoch = (epoch - 1) * args.sub_epochs + sub_epoch
                writer.add_scalar('sigma_mod/sigma_init', sigma, effective_epoch-1)
                train(args, smoother, device, train_loader, optimizer, effective_epoch, writer)
                test(args, smoother, device, test_loader, effective_epoch, writer, comment)
                scheduler.step()
            sigma += args.sigma_add
    else:
        smoother = Smooth(model, sigma=args.sigma,
                          num_classes=get_num_classes(get_dataset_name(args.model)),
                          data_shape=get_input_dim(get_dataset_name(args.model)))
        optimizer = optim.Adam([smoother.sigma], lr=args.lr)
        scheduler = StepLR(optimizer, step_size=1, gamma=args.gamma)
        for epoch in range(1, args.epochs + 1):
            train(args, smoother, device, train_loader, optimizer, epoch, writer)
            test(args, smoother, device, test_loader, epoch, writer, comment)
            scheduler.step()
    writer.close()

if __name__ == '__main__':
    main()


import RPi.GPIO as GPIO
from flask import Flask, render_template, Response, request
from time import sleep
import serial
from MotorModule import Motor
from LaneDetectionModule import getLaneCurve
import WebcamModule
import cv2
import multiprocessing

initi = 0
userValue = 0
kart = 0
i = 0
app = Flask(__name__)

def main1():
    motor = Motor(13,19,16,20)
    while True:
        img = WebcamModule.getImg()
        curveVal = getLaneCurve(img,1)
        sleep(0.01)
        sen = 5 # SENSITIVITY
        maxVAl= 0.35 # MAX SPEED
        if curveVal>maxVAl:curveVal = maxVAl
        if curveVal<-maxVAl: curveVal =-maxVAl
        print('curvel')
        print(curveVal)
        if curveVal>0:
            if curveVal<0.05: curveVal=0
        else:
            if curveVal>-0.08: curveVal=0
        motor.move(2,curveVal*sen,0.1)
        print('motor commend sent')
        cv2.waitKey(1)

process = multiprocessing.Process(target=main1, args=())

@app.route("/", methods=["GET", "POST"])
def home():
    global initi
    global userValue
    global motor
    global kart
    print('/')
    global i
#     motor.stop(0,0,0)
    TES_pin = 26
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(TES_pin, GPIO.OUT)
    GPIO.output(TES_pin, GPIO.LOW)
    print("Pump Off")
    initi = 0

    if kart == 1:
        print("trying to stop thread")
        process.terminate()
        sleep(2)
       # process.close()
        i = 0
        motor = Motor(13,19,16,20)
        motor.stop()
        kart = kart -1;

    return render_template("index.html")  # nothing happen

    # To Power on the motor, pump and etc
@app.route('/on', methods=["GET", "POST"])

def on():
    global initi
    global userValue
    global curveVal
    global i
    global kart
    sen = 5 # SENSITIVITY

    if i == 0:
        process.start()
        kart = 1
        i = i + 1 ;

    if  initi == 0:
        RelayControl = 26
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(RelayControl, GPIO.OUT)
        GPIO.output(RelayControl, GPIO.HIGH)
        initi = 1
        print('on1')
        sleep(2)
        return render_template('on.html')

    elif request.method == "POST":
        print('Post Request')
        userValue = request.form["val"]  # get the value of val from html file and store as str
        print(userValue)
        SMotor_Control(userValue)
        return render_template('on.html')

    elif request.method == "GET":
        print("Get")
        Data = WaterLevelRead()
        return render_template('on.html',data=Data)

def SMotor_Control(degree):
    print("Spray Motor Control")
    val1 = SetAngle(degree)
    servoM1_pin = 6  # PWM pin
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(servoM1_pin, GPIO.OUT)
    m1 = GPIO.PWM(servoM1_pin, 50)
    m1.start(0)
    m1.ChangeDutyCycle(12)
    sleep(4)
    m1.ChangeDutyCycle(val1)
    sleep(2)
    #GPIO.cleanup()

def SetAngle(angle):
    angle1 = float(angle)
    print(angle1)
    angle1 += 90
    print(angle1)
    duty = 12 - (angle1 / 180) * 10
    result = int(duty)
    print(duty)
    print(result)
    return result

def WaterLevelRead():
    ser = serial.Serial('/dev/ttyACM0', 9600, timeout=1)
    ser.flush()
    sleep(1)
    Line = ser.readline().decode('utf-8').rstrip()
    print(Line)
    ser.close()
    return Line

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=False)


try:

    import zmq
    import time
    import sys

except Exception as e:

    print(e)

class forwarder(object):
    '''
    Forwarder object acts as a stable point between critical objects
    If any of the critical objects fail, this aviods an entire system shut-down
    '''

    def __init__(self,socket_number):

        self.context = zmq.Context(1)
        self.frontend_socket_number = socket_number
        self.backend_socket_number = socket_number+1

        print('Forwarder is ready')

        # Socket facing clients
        frontend = self.context.socket(zmq.SUB)
        frontend.bind("tcp://127.0.0.1:{}".format(self.frontend_socket_number))

        frontend.setsockopt_string(zmq.SUBSCRIBE, "")

        # Socket facing services
        backend = self.context.socket(zmq.PUB)
        backend.bind("tcp://127.0.0.1:{}".format(self.backend_socket_number))

        zmq.device(zmq.FORWARDER, frontend, backend)

        time.sleep(5) # Since binding takes time, sleep for a few seconds before running

if __name__ == "__main__":

    try:

        socket_number = int(sys.argv[1])

        f1 = forwarder(socket_number)

    except:

        print( 'Error in forwarder object' )

'''
About ZMQ:
https://www.randonomicon.com/zmq/2018/09/19/zmq-bind-vs-connect.html

Use BIND for stable tings & Use CONNECT for volatile things
Use BIND when listening & Use CONNECT when broadcasting
Use BIND for incoming & Use CONNECT for outgoing
Use BIND for long-lived process & Use CONNECT for short-lived process

'''


from PyQt5.QtWidgets import QListWidget
from PyQt5.QtCore import Qt

class ListBoxWidget(QListWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setAcceptDrops(True)
        self.itemsList = set()

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        else:
            event.ignore()

    def dragMoveEvent(self, event):
        if event.mimeData().hasUrls():
           event.setDropAction(Qt.CopyAction)
           event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        if event.mimeData().hasUrls():
            event.setDropAction(Qt.CopyAction)
            event.accept()

            for url in event.mimeData().urls():
                if url.isLocalFile():
                    localFile = str(url.toLocalFile())

                    if localFile.endswith((".png", ".jpg", ".jpeg")):
                       self.itemsList.add(localFile)
                else:
                    continue

            self.clear()
            self.addItems(self.itemsList)
        else:
            event.ignore()


import unittest
from functools import partial
import numpy as np
import bayes
import tensorflow as tf
import tensorflow_probability as tfp

tfd = tfp.distributions
tfb = tfp.bijectors

class BayesTestCase(unittest.TestCase):
    def test_batch(self):

        n=4
        x = np.random.normal(loc=10, scale=2, size=(n,351,1)).astype(np.float32)
        model = bayes.poisson_mixture_regression(x, 2)

        s = model.sample(n)

        @tf.function(jit_compile=True)
        def f(x):
            return model.log_prob(x)

        f(s)
        return 0
    def test_no_batch(self):

        n=4
        x = np.random.normal(loc=10, scale=2, size=(351,1)).astype(np.float32)
        model = bayes.poisson_mixture_regression(x, 2)

        s = model.sample()

        @tf.function(jit_compile=True)
        def f(x):
            return model.log_prob(x)

        f(s)
        return 0

class TupleModelTestCase(unittest.TestCase):

    def test_prior(self):
        prior = bayes.PoissonMixtureRegression.prior(2, tf.float64)

        n = 4
        sample_model = bayes.PoissonMixtureRegression(*map(partial(tfd.Distribution.sample,sample_shape=n), prior))
        x = np.random.normal(loc=10, scale=2, size=(n,351, 1))
        sample_model(x)
        ...
    def test_z(self):
        prior = bayes.PoissonMixtureRegression.prior(2, tf.float64)

        n = 4
        sample_model = bayes.PoissonMixtureRegression(*map(partial(tfd.Distribution.sample,sample_shape=n), prior))
        x = np.random.normal(loc=10, scale=2, size=(n,351, 1))
        sample_model.Z(x,tf.round(x))

    def test_jdc(self):
        n = 4
        x = np.random.normal(loc=10, scale=2, size=(n, 351, 1))
        Root = tfd.JointDistributionCoroutine.Root
        def makejdc():
            @tfd.JointDistributionCoroutine
            def model():
                params=[]
                for p in bayes.PoissonMixtureRegression.prior(2,tf.float64):
                    param = yield Root(p)
                    params.append(param)
                yield bayes.PoissonMixtureRegression(*params)(x)
            return model

        model = makejdc()
        model.log_prob(model.sample())
        ...

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


"""
Tests covering Pytelliot rpc connection  utils.
"""
import pytest
import requests
from brownie import chain

from telliot_core.model.endpoints import EndpointList
from telliot_core.model.endpoints import RPCEndpoint

network = "mainnet"
provider = "pokt"

def test_rpc_endpoint():
    """RPCEndpoint connects to the blockchain"""
    url = "http://127.0.0.1:8545"  # local Ganache node
    endpt = RPCEndpoint(network=network, provider=provider, url=url)
    endpt.connect()
    chain.mine(10)
    assert endpt.web3.eth.block_number > 1

    print(endpt.get_state())

def test_very_bad_rpc_url():
    """an invalid url will raise an exception in RPCEndpoint"""
    url = "this is not a valid rpc url"
    endpt = RPCEndpoint(network=network, provider=provider, url=url)
    with pytest.raises(ValueError):
        _ = endpt.connect()

@pytest.mark.skip()
def test_incomplete_rpc_url():
    """an incomplete url will raise an exception in RPCEndpoint"""
    url = "https://eth-rinkeby.gateway.pokt.network/v1/lb/"
    endpt = RPCEndpoint(network=network, provider=provider, url=url)
    # expect bad url error from requests library
    with pytest.raises(requests.exceptions.HTTPError):
        _ = endpt.connect()

@pytest.mark.skip("Only Pulsechain available in endpoint list")
def test_endpoint_list():
    sl = EndpointList()
    # print(json.dumps(sl.get_state(), indent=2))
    ep4 = sl.find(chain_id=4)[0]
    assert ep4.network == "rinkeby"

    ep3 = sl.find(chain_id=3)[0]
    assert ep3.network == "ropsten"


import datetime
import sys
import struct
import pyqtgraph as pg
from PyQt5.QtCore import Qt, QTimer, QThread, pyqtSignal
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import (
    QMainWindow, QApplication, QWidget, QPushButton, QGridLayout, QComboBox,
    QLineEdit, QMessageBox, QTextEdit, QLabel, QCheckBox
)
import serial
import serial.tools.list_ports as port_find

# 帧头
frame_b_1 = b'\xfa'
frame_b_2 = b'\xac'

# 帧尾
frame_e_1 = b'\xcc'
frame_e_2 = b'\x89'

def get_serial_com():
    portlist = list(port_find.comports())
    return [port[0] for port in portlist]

class SerialThread(QThread):
    data_received = pyqtSignal(bytes)

    def __init__(self, port, baud_rate):
        super().__init__()
        self.new_data = None
        self.port = port
        self.baud_rate = baud_rate
        self.running = True

    def run(self):
        with serial.Serial(
                port=self.port, baudrate=self.baud_rate,
                parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=None
        ) as ser:
            while self.running:
                self.new_data = ser.read(10)
                self.data_received.emit(self.new_data)

    def stop(self):
        self.running = False

class SerialDebugger(QMainWindow):
    def __init__(self):
        super().__init__()
        self.data_frame = None
        self.poltch = None
        self.bound_rate = None
        self.plot_widget = None
        self.ser = None
        self.serialbox = None
        self.data_buffer = b''
        self.init_ui()
        self.plot_data = [[], [], [], []]
        self.serial_thread = None

    def open_serial(self):
        port = self.serialbox.currentText()
        bound_str = self.bound_rate.text()
        try:
            bound = int(bound_str)
            self.serial_thread = SerialThread(port, bound)
            self.serial_thread.data_received.connect(self.process_received_data)
            self.serial_thread.start()
            QMessageBox.information(None, 'Success', '串口已打开')
        except ValueError:
            QMessageBox.critical(None, 'Error', '波特率为整数')

    def process_received_data(self, new_data):
        self.data_buffer += new_data
        self.process_data_buffer()

        current_time = datetime.datetime.now().strftime('%H:%M:%S.%f')[:-3]
        data_str = f'[{current_time}] \
            {" ".join(format(byte, "02x").upper() for byte in new_data)}
'

        if self.rx_show.isChecked():
            self.text_edit.insertHtml(data_str)
            self.scroll_to_bottom()

    def closeEvent(self, event):
        if self.serial_thread and self.serial_thread.isRunning():
            self.serial_thread.stop()
            self.serial_thread.wait()

        super().closeEvent(event)

    def init_ui(self):
        central_widget = QWidget(self)
        grid = QGridLayout()
        central_widget.setLayout(grid)
        self.setCentralWidget(central_widget)
        self.setWindowTitle("Serial Debugger")
        self.setWindowIcon(QIcon('main.png'))
        self.setGeometry(200, 100, 1200, 720)
        grid.setSpacing(10)

        self.serialbox = QComboBox()
        self.serialbox.addItems(get_serial_com())

        button = QPushButton("打开串口")
        button.clicked.connect(self.open_serial)

        self.bound_rate = QLineEdit()
        self.bound_rate.setPlaceholderText("波特率")

        for i in range(15):
            grid.setColumnStretch(i, 1)

        for i in range(10):
            grid.setRowStretch(i, 1)

        self.plot_widget = pg.PlotWidget()
        self.plot_widget.showGrid(x=True, y=True)
        self.plot_widget.setBackground('w')

        self.poltch = QComboBox()
        self.poltch.addItems(["0", "1", "2", "3", "4"])

        chlabel = QLabel()
        chtxt = f'选择数据通道数'
        chlabel.setText(chtxt)
        chlabel.setAlignment(Qt.AlignBottom)

        self.rx_show = QCheckBox('RX ON')
        self.tx_show = QCheckBox('TX ON')

        self.text_edit = QTextEdit()
        self.text_edit.setReadOnly(True)

        self.tx_edit = QLineEdit()

        button_tx = QPushButton("发送")
        button_tx.clicked.connect(self.serial_send)

        self.sendtypebox = QComboBox()
        self.sendtypebox.addItems(["ABC", "HEX"])

        grid.addWidget(self.sendtypebox, *[9, 13], 1, 1)
        grid.addWidget(button_tx, *[9, 14], 1, 1)
        grid.addWidget(self.text_edit, *[7, 1], 2, 14)
        grid.addWidget(self.tx_edit, *[9, 1], 1, 12)
        grid.addWidget(self.plot_widget, *[0, 1], 7, 14)
        grid.addWidget(self.serialbox, *[0, 0])
        grid.addWidget(self.bound_rate, *[1, 0])

        grid.addWidget(button, *[2, 0])
        grid.addWidget(self.poltch, *[4, 0])
        grid.addWidget(chlabel, *[3, 0])
        grid.addWidget(self.rx_show, *[7, 0])
        grid.addWidget(self.tx_show, *[9, 0])

        self.ch1 = self.plot_widget.getPlotItem()
        self.ch2 = self.plot_widget.getPlotItem()
        self.ch3 = self.plot_widget.getPlotItem()
        self.ch4 = self.plot_widget.getPlotItem()

        self.plot_data = [[], [], [], []]
        self.plot_curve1 = self.ch1.plot(self.plot_data[0])
        self.plot_curve1.setPen(pg.mkPen(color='red', width=2, style=pg.QtCore.Qt.SolidLine))
        self.plot_curve2 = self.ch2.plot(self.plot_data[1])
        self.plot_curve2.setPen(pg.mkPen(color='blue', width=2, style=pg.QtCore.Qt.SolidLine))
        self.plot_curve3 = self.ch3.plot(self.plot_data[2])
        self.plot_curve3.setPen(pg.mkPen(color='green', width=2, style=pg.QtCore.Qt.SolidLine))
        self.plot_curve4 = self.ch4.plot(self.plot_data[3])
        self.plot_curve4.setPen(pg.mkPen(color='black', width=2, style=pg.QtCore.Qt.SolidLine))

        self.show()
        self.timer = self.startTimer(10)
        self.plot_timer = QTimer(self)
        self.plot_timer.timeout.connect(self.plot_update)
        self.plot_timer.start(100)

    def scroll_to_bottom(self):
        scrollbar = self.text_edit.verticalScrollBar()
        scrollbar.setValue(scrollbar.maximum())

    def process_data_buffer(self):
        start_index_1 = self.data_buffer.find(frame_b_1)
        start_index_2 = self.data_buffer.find(frame_b_2)
        end_index_1 = self.data_buffer.find(frame_e_1)
        end_index_2 = self.data_buffer.find(frame_e_2)

        if start_index_2 - start_index_1 == 1 and end_index_2 - end_index_1 == 1:
            self.data_frame = self.data_buffer[start_index_2 + 1:end_index_1]
            self.data_buffer = self.data_buffer[end_index_2 + 1:]
            print(self.data_frame)
        else:
            self.data_buffer = self.data_buffer[end_index_2 + 1:]
        # if len(self.data_buffer) > 1000:
        #     self.data_buffer = b''

    def serial_send(self):
        if self.ser != None:
            if self.ser.isOpen():
                txtype = self.sendtypebox.currentText()
                txcontent = self.tx_edit.text()
                if txtype == "HEX":
                    content = bytes.fromhex(txcontent)
                    self.ser.write(content)
                    current_time = datetime.datetime.now().strftime('%H:%M:%S.%f')[:-3]
                    data_str = f'[{current_time}] \
                                    {" ".join(format(byte, "02x").upper() for byte in content)}
'
                    if self.tx_show.isChecked():
                        self.text_edit.insertHtml(data_str)
                    print(content)
                if txtype == "ABC":
                    content = bytes(txcontent, "UTF-8")
                    self.ser.write(content)
                    current_time = datetime.datetime.now().strftime('%H:%M:%S.%f')[:-3]
                    data_str = f'[{current_time}] \
                                    {" ".join(format(byte, "02x").upper() for byte in content)}
'
                    if self.tx_show.isChecked():
                        self.text_edit.insertHtml(data_str)
                    print(content)
        else:
            QMessageBox.information(None, "ATTITION", '先打开串口哦')

    def plot_update(self):
        ch = self.poltch.currentIndex()
        if ch != 0 and self.data_frame != None:
            if len(self.data_frame) != 0:
                data = struct.unpack("h" * ch, self.data_frame[:ch * 2])
                data_len = len(data)
                for i in range(data_len):
                    self.plot_data[i].insert(0, data[i])

                self.plot_curve1.setData(self.plot_data[0])
                self.plot_curve2.setData(self.plot_data[1])
                self.plot_curve3.setData(self.plot_data[2])
                self.plot_curve4.setData(self.plot_data[3])

if __name__ == "__main__":
    app = QApplication(sys.argv)
    sd = SerialDebugger()
    sys.exit(app.exec_())


# -*- coding: utf-8 -*-
"""
https://leetcode.com/problems/cousins-in-binary-tree/solution/

#1 BFS, record the parent and depth
#2 DFS, record the parent and depth
"""
import collections
class Solution:
    def isCousins_bfs(self, root: 'TreeNode', x: 'int', y: 'int') -> 'bool':
        parents, depths = {}, {}
        queue = collections.deque((root, 0))
        while queue:
            node, d = queue.popleft()
            if node.left:
                queue.append((node.left, d + 1))
                if node.left.val in (x, y):
                    parents[node.left.val] = node.val
                    depths[node.left.val] = d + 1
            if node.right:
                queue.append((node.right, d + 1))
                if node.right.val in (x, y):
                    parents[node.right.val] = node.val
                    depths[node.right.val] = d + 1
            if len(parents) == 2:
                break
        if len(parents) != 2:
            return False
        if parents[x] != parents[y] and depths[x] == depths[y]:
            return True
        return False

    def isCousins_dfs(self, root: 'TreeNode', x: 'int', y: 'int') -> 'bool':
        parent, depth = {}, {}
        def dfs(node, par = None):
            if node:
                depth[node.val] = 1 + depth[par.val] if par else 0
                parent[node.val] = par
                dfs(node.left, node)
                dfs(node.right, node)
        dfs(root)
        return depth[x] == depth[y] and parent[x] != parent[y]


from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
import tensorflow as tf
from sklearn.preprocessing import OneHotEncoder, MinMaxScaler
from sklearn.metrics import accuracy_score
import numpy as np

datasets = load_wine()
print(datasets.DESCR)
print(datasets.feature_names)

x_data = datasets.data
y_data = datasets.target
y_data = y_data.reshape(-1, 1)
print(x_data.shape, y_data.shape)  # (178, 13) (178, 1)

one_hot_Encoder = OneHotEncoder()
one_hot_Encoder.fit(y_data)
y_data = one_hot_Encoder.transform(y_data).toarray()

print(x_data.shape, y_data.shape)  # (178, 13) (178, 3)

x_train, x_test, y_train, y_test = train_test_split(x_data, y_data, train_size=0.8, random_state=9, shuffle=True)

x = tf.placeholder(tf.float32, shape=[None, 13])
y = tf.placeholder(tf.float32, shape=[None, 3])

w = tf.Variable(tf.random_normal([13, 3]), dtype=tf.float32) # x X w = N, 3 (y)의 값이 되어야 한다
b = tf.Variable(tf.random_normal([1, 3]), dtype=tf.float32)

hypothesis = tf.nn.softmax(tf.matmul(x, w) + b)

loss = tf.reduce_mean(-tf.reduce_sum(y * tf.log(hypothesis), axis=1)) # categorical crossentropy

optimizer = tf.train.GradientDescentOptimizer(learning_rate=5e-1).minimize(loss)

sess = tf.compat.v1.Session()
sess.run(tf.global_variables_initializer())

for epochs in range(1001):
    cost_val, hy_val, _ = sess.run([loss, hypothesis, optimizer],
                    feed_dict={x:x_data, y:y_data})
    if epochs % 10 == 0:
        print(epochs, 'cost: ', cost_val, "predict: ", hy_val)

pred = sess.run(hypothesis, feed_dict={x:x_test}) # x_test에 대한 기울기 다시 도출
print('전:', pred[:5])
pred = np.argmax(pred, axis=1)
print('후:', pred[:5])
print('전 1:', y_test[:5])
y_test = np.argmax(y_test, axis=1)
print('후 1:', y_test[:5])
print('acc: ', accuracy_score(y_test, pred))

# acc:  0.4722222222222222


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
- author: Lkeme
- contact: Useri@live.cn
- file: app
- time: 2019/10/4 7:28
- desc:
"""
import requests
import time
import re

try:
    from urllib import urlencode
except:
    from urllib.parse import urlencode
from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

def printer(info, *args):
    at_now = int(time.time())
    time_arr = time.localtime(at_now)
    format_time = time.strftime("%Y-%m-%d %H:%M:%S", time_arr)
    # flag = "," if len(args) else " "
    content = f'[{format_time}] {info} {" ".join(f"{str(arg)}" for arg in args)}'
    print(content)

def format_time():
    return f"[{str(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))}]"

def match_csrf(cookie):
    temp = re.search(r"bili_jct=(.{32})", cookie)
    csrf = str(temp.group(1))
    return csrf

# 心跳E
def heart_beat_e(room_id=23058):
    url = 'https://live-trace.bilibili.com/xlive/data-interface/v1/x25Kn/E'
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Origin': 'https://live.bilibili.com',
        'Referer': f'https://live.bilibili.com/{room_id}',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36',
        'Cookie': cookie,
    }
    payload = {
        'id': [1, 34, 0, 23058],
        'device': '["c4ca4238a0b923820dcc509a6f75849b","55e2620e-a2b9-4086-bd9a-bc399ba13480"]',
        'ts': int(time.time()) * 1000,
        'is_patch': 0,
        'heart_beat': [],
        'ua': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36',
        'csrf_token': match_csrf(cookie),
        'csrf': match_csrf(cookie),
        'visit_id': ''
    }
    data = urlencode(payload)
    # {"code":0,"message":"0","ttl":1,"data":{"timestamp":1595342828,"heartbeat_interval":300,"secret_key":"seacasdgyijfhofiuxoannn","secret_rule":[2,5,1,4],"patch_status":2}}
    response = session.post(url, headers=headers, data=data,
                            verify=False).json()
    printer("E心跳", response)
    payload['ets'] = response['data']['timestamp']
    payload['secret_key'] = response['data']['secret_key']
    payload['heartbeat_interval'] = response['data']['heartbeat_interval']
    return payload

# 心跳X
def heart_beat_x(index, payload, room_id=23058):
    url = 'https://live-trace.bilibili.com/xlive/data-interface/v1/x25Kn/X'
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Origin': 'https://live.bilibili.com',
        'Referer': f'https://live.bilibili.com/{room_id}',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36',
        'Cookie': cookie,
    }
    s_data = {
        "t": {
            'id': [1, 34, index, 23058],
            "device": payload['device'],  # LIVE_BUVID
            "ets": payload['ets'],
            "benchmark": payload['secret_key'],
            "time": payload['heartbeat_interval'],
            "ts": int(time.time()) * 1000,
            "ua": payload['ua']
        },
        "r": [2, 5, 1, 4]
    }
    t = s_data['t']
    payload = {
        's': generate_s(s_data),
        'id': t['id'],
        'device': t['device'],
        'ets': t['ets'],
        'benchmark': t['benchmark'],
        'time': t['time'],
        'ts': t['ts'],
        "ua": t['ua'],
        'csrf_token': match_csrf(cookie),
        'csrf': match_csrf(cookie),
        'visit_id': '',
    }
    # printer(payload)
    payload = urlencode(payload)
    # {"code":0,"message":"0","ttl":1,"data":{"heartbeat_interval":300,"timestamp":1595346846,"secret_rule":[2,5,1,4],"secret_key":"seacasdgyijfhofiuxoannn"}}
    response = session.post(url, headers=headers, data=payload,
                            verify=False).json()
    printer("X心跳", response)
    return response

# 加密s
def generate_s(data):
    url = 'http://127.0.0.1:3000/enc'
    response = requests.post(url, json=data).json()
    printer("S加密", response['s'])
    return response['s']

# 加密s
def generate_s_test():
    url = 'http://127.0.0.1:3000/enc'
    data = {
        "t": {
            "id": [1, 34, 0, 23058],
            "device": [
                "c4ca4238a0b923820dcc509a6f75849b",
                "55e2620e-a2b9-4086-bd9a-bc399ba13480"
            ],
            "ets": 1570562610,
            "benchmark": "seacasdgyijfhofiuxoannn",
            "time": 120,
            "ts": 1570562730734
        },
        "r": [2, 5, 1, 4]
    }
    response = requests.post(url, json=data).json()
    printer("S加密", response)
    return response['s']

# X心跳 {'code': 1012002, 'message': 'bad timestamp request,timestamp:1584604393,watchtime:300,userstatus:1584604393,roomInterval:300,serverTime:1584604393,ispatch:0', 'ttl': 1, 'data': {'heartbeat_interval': 300, 'timestamp': 1584604393, 'secret_rule': [2, 5, 1, 4], 'secret_key': 'seacasdgyijfhofiuxoannn'}}
# 41.1b7a7f2689ea751d75d4.js:574 {"id":"","device":"[\"c4ca4238a0b923820dcc509a6f75849b\",\"55e2620e-a2b9-4086-bd9a-bc399ba13480\"]","ets":1570562610,"benchmark":"seacasdgyijfhofiuxoannn","time":120,"ts":1570562730734}
# 41.1b7a7f2689ea751d75d4.js:575 打印r
# 41.1b7a7f2689ea751d75d4.js:576
# 41.1b7a7f2689ea751d75d4.js:577 (4) [2, 5, 1, 4]
# 41.1b7a7f2689ea751d75d4.js:587 T类型 string
# 41.1b7a7f2689ea751d75d4.js:588 R类型 object
# 41.1b7a7f2689ea751d75d4.js:608 打印加密后
# 41.1b7a7f2689ea751d75d4.js:609 cdc04cffba0b1f9f7bfa145b27fc5a4430c95d83d526002371ea363f42c608792798170e3f23dd3eda69480553699ad1b002a8ba7fc60070ae77153930a86e5e

if __name__ == '__main__':
    cookie = ""
    session = requests.Session()
    data = heart_beat_e(room_id=23058)
    for index in [1, 2, 3, 4, 5, 6, 7]:
        printer(f"Interval {data['heartbeat_interval']} 后开始第 {index} 次")
        time.sleep(data['heartbeat_interval'])
        response = heart_beat_x(index, data, room_id=23058)
        data['ets'] = response['data']['timestamp']
        data['secret_key'] = response['data']['secret_key']
        data['heartbeat_interval'] = response['data']['heartbeat_interval']


# -*- coding: utf-8 -*-
"""
Created on Sat Nov 17 17:26:37 2018

@author: Acarbay

Functions that aid in building and analyzing ML models.
"""
import pandas as pd
import numpy as np
import math
import matplotlib.pyplot as plt
import itertools

def performance_measures(cm):
    """ Computes accuracy, precision, specificity and recall statistics for given
    classification results. The function is primarily built to be used within
    classify_from_prob function, yet it can be used elsewhere with the correct inputs.
        Parameters:
        cm: Series of classification results with indices:
            - True Up, False Down, False Up, True Down
    """
    perf = pd.Series()
    # Accuracy: % of correct classifications
    perf['accuracy'] = (cm['True Up']+cm['True Down'])/cm.sum()
    # Precision: True Up/Predicted Up
    perf['precision'] = cm['True Up']/(cm['True Up']+cm['False Up'])
    # Recall/sensitivity(True Positive Rate): True Positive/Actual Positive
    perf['recall'] = cm['True Up']/(cm['True Up']+cm['False Down'])
    # Specificity(True Negative Rate): True Negative/Actual Negative
    perf['specificity'] = cm['True Down']/(cm['True Down']+cm['False Up'])
    # False Positive Rate: 1-Specificity
    perf['false positive rate'] = 1-perf['specificity']
    # False Negative Rate: 1-Recall
    perf['false negative rate'] = 1-perf['recall']
    return perf

def classify_from_prob(prob, pDown, pUp, Y_test, prob_tuning = False):
    """ This function takes the probabilities computed from a model, the probability levels
    for classification and returns the classification results, a confusion matrix and
    performance measures for classification accuracy. If prob_tuning is set to True,
    only return accuracy and the number of total calls made.
    """
    # probs = pd.DataFrame({'Down': prob[:,0].flatten(), 'Up': prob[:,1].flatten()})
    # pred = probs['Down'].map(lambda x: 0 if x > pUp else(1 if x < pDown else -1))
    pred = prob.map(lambda x: 1 if x > pUp else(0 if x < pDown else -1))
    # Identify indices of up/down classes
    ind_up = pred[pred == 1].index.values
    ind_down = pred[pred == 0].index.values
    cm = pd.Series()
    cm['True Up'] = 0
    cm['True Down'] = 0
    for i in range(len(ind_up)):
        if Y_test[ind_up[i]] == pred[ind_up[i]]:
            cm['True Up'] += 1
    for i in range(len(ind_down)):
        if Y_test[ind_down[i]] == pred[ind_down[i]]:
            cm['True Down'] += 1
    total_correct = cm['True Up'] + cm['True Down']
    percentage_correct = (total_correct/(len(ind_up)+len(ind_down)))*100
    print('Accuracy (%):' + str(round(percentage_correct,2)))
    cm['False Up'] = (len(ind_up))-cm['True Up']
    cm['False Down'] = (len(ind_down))-cm['True Down']
    cm = cm.reindex(index = ['True Up', 'False Down', 'False Up', 'True Down'])
    if prob_tuning == False:
        perf = performance_measures(cm)
        return pred, cm, perf
    else:
        total_calls = len(pred)+1-pd.value_counts(pred)[-1] # total number of calls
        return percentage_correct, total_calls, cm

def mass_classify_from_prob(prob, pDown, pUp, targets, levels = math.nan,
                            result_per_level = True, join_cm = False):
    """ This function takes the probabilities computed from a model and two lists
    denoting the classification levels for buy/sell cases and computes the
    predictions at each combination of probabilities and accuracy statistics for each
    case. If join_cm is set to True, forms a confusion matrix for each probability
    pair, if not, returns two seperate dataframes one for the accuracy of each
    pUp and one for the accuracy of pDown. If levels is set to varying test set sizes,
    the function instead returns a list of the same outputs, each regarding one test
    size. If result per_level is set to False, the overall results displaying
    each level will be returned instead."""

    targets.reset_index(drop = True, inplace = True)
    if levels is not math.nan:
        down_ind = []
        true_neg = []
        false_neg = []
        for p in pDown:
            down = prob.map(lambda x: 0 if x < p else -1)
            ind = down[down == 0].index.values
            down_ind.append(ind)
            true = []
            false = []
            for level in levels:
                if len(ind) > 0:
                    if ind[0] < level:
                        true.append((targets[:level][ind] == down[:level][ind]).sum())
                        false.append(len(targets[:level][ind].dropna()) - true[-1])
            true_neg.append([0]*(len(levels)-len(true))+true)
            false_neg.append([0]*(len(levels)-len(false))+false)

        up_ind = []
        true_pos = []
        false_pos = []
        for p in pUp:
            up = prob.map(lambda x: 1 if x > p else -1)
            ind = up[up == 1].index.values
            up_ind.append(ind)
            true = []
            false = []
            for level in levels:
                if len(ind) > 0:
                    if ind[0] < level:
                        true.append((targets[:level][ind] == up[:level][ind]).sum())
                        false.append(len(targets[:level][ind].dropna()) - true[-1])
            true_pos.append([0]*(len(levels)-len(true))+true)
            false_pos.append([0]*(len(levels)-len(false))+false)

        true_neg = pd.DataFrame(data = np.array(true_neg), columns = levels, index = pDown)
        false_neg = pd.DataFrame(data = np.array(false_neg), columns = levels, index = pDown)
        true_pos = pd.DataFrame(data = np.array(true_pos), columns = levels, index = pUp)
        false_pos = pd.DataFrame(data = np.array(false_pos), columns = levels, index = pUp)

        accuracy_neg = (true_neg/(true_neg+false_neg))*100
        accuracy_pos = (true_pos/(true_pos+false_pos))*100

        no_of_calls_up = true_pos+false_pos
        no_of_calls_down = true_neg+false_neg

        perc_of_calls_up = 100*(true_pos+false_pos)/levels
        perc_of_calls_down = 100*(true_neg+false_neg)/levels

        if result_per_level:
        # Right now each accuracy statistic is in a dataframe of its own. Instead, we'd
        # like to merge these statistic for each test set.
            up = []
            down = []
            for i in range(len(levels)):
                neg = pd.concat([true_neg[levels[i]], false_neg[levels[i]],
                                 accuracy_neg[levels[i]], no_of_calls_down[levels[i]],
                                 perc_of_calls_down[levels[i]]], axis = 1)
                neg.columns = ['True Down', 'False Down', 'Accuracy(%)', '# of calls', '% of calls']
                pos = pd.concat([true_pos[levels[i]], false_pos[levels[i]],
                                 accuracy_pos[levels[i]], no_of_calls_up[levels[i]],
                                 perc_of_calls_up[levels[i]]], axis = 1)
                pos.columns = ['True Down', 'False Down', 'Accuracy(%)', '# of calls', '% of calls']
                up.append(pos)
                down.append(neg)
        else:
            up, down = {}, {}
            up["True"] = true_pos
            up["False"] =  false_pos
            up["Accuracy(%)"] = accuracy_pos
            up["# of calls"] = no_of_calls_up
            up["% of calls"] = perc_of_calls_up
            down["True"] = true_neg
            down["False"] =  false_neg
            down["Accuracy(%)"] = accuracy_neg
            down["# of calls"] = no_of_calls_down
            down["% of calls"] = perc_of_calls_down

        # Join the predictions for pUp and pDown into pairs
        classifications = pd.DataFrame()
        for i, pD in enumerate(pDown):
            for j, pU in enumerate(pUp):
                temp = np.full((len(targets),),-1)
                temp[list(down_ind[i])] = 0
                temp[list(up_ind[j])] = 1
                classifications[str(round(pD,5))+':'+str(round(pU,5))] = temp
        cls = []
        for level in levels:
            cls.append(classifications[:level])

        return cls, up, down
    else:
        # Classify each case according to the given probabilities and calculate
        # the number of true positives&negatives
        down_ind = []
        true_neg = pd.Series(name = 'True Down')
        false_neg = pd.Series(name = 'False Down')
        for p in pDown:
            down = prob.map(lambda x: 0 if x < p else -1)
            ind = down[down == 0].index.values
            true_neg[str(round(p,5))] = (targets[ind] == down[ind]).sum()
            false_neg[str(round(p,5))] = (len(ind)) - true_neg[str(round(p,5))]
            down_ind.append(ind)

        up_ind = []
        true_pos = pd.Series(name = 'True Up')
        false_pos = pd.Series(name = 'False Up')
        for p in pUp:
            up = prob.map(lambda x: 1 if x > p else -1)
            ind = up[up == 1].index.values
            true_pos[str(round(p,5))] = (targets[ind] == up[ind]).sum()
            false_pos[str(round(p,5))] = (len(ind)) - true_pos[str(round(p,5))]
            up_ind.append(ind)

        # Join the predictions for pUp and pDown into pairs
        classifications = pd.DataFrame()
        for i, pD in enumerate(pDown):
            for j, pU in enumerate(pUp):
                temp = np.full((len(targets),),-1)
                temp[list(down_ind[i])] = 0
                temp[list(up_ind[j])] = 1
                classifications[str(round(pD,5))+':'+str(round(pU,5))] = temp

        # Produce confusion matrix for each pair
        if join_cm:
            true_up = pd.Series(name = 'True Up')
            false_down = pd.Series(name = 'False Down')
            false_up = pd.Series(name = 'False Up')
            true_down = pd.Series(name = 'True Down')
            for i, pD in enumerate(pDown):
                for j, pU in enumerate(pUp):
                    true_up[str(round(pD,5))+':'+str(round(pU,5))] =  true_pos[str(round(pU,5))]
                    false_down[str(round(pD,5))+':'+str(round(pU,5))] =  false_neg[str(round(pD,5))]
                    false_up[str(round(pD,5))+':'+str(round(pU,5))] =  false_pos[str(round(pU,5))]
                    true_down[str(round(pD,5))+':'+str(round(pU,5))] =  true_neg[str(round(pD,5))]
            cm = pd.concat([true_up,false_down,false_up,true_down], axis = 1)
            return classifications, cm
        else:
            cm_up = pd.concat([true_pos, false_pos], axis = 1)
            cm_up['Accuracy(%)'] = (true_pos/(true_pos+false_pos))*100
            cm_up['# of calls'] = true_pos+false_pos
            cm_up['% of calls'] = 100*(true_pos+false_pos)/len(targets)
            cm_down = pd.concat([true_neg, false_neg], axis = 1)
            cm_down['Accuracy(%)'] = (true_neg/(true_neg+false_neg))*100
            cm_down['# of calls'] = true_neg+false_neg
            cm_down['% of calls'] = 100*(true_neg+false_neg)/len(targets)
            return classifications, cm_up, cm_down

def plot_confusion_matrix(cm, classes,
                          normalize=False,
                          title='Confusion matrix',
                          cmap=plt.cm.Blues):
    """
    This function prints and plots the confusion matrix.
    Normalization can be applied by setting `normalize=True`.
    Taken from the sci-kit learn website:
        http://scikit-learn.org/stable/auto_examples/model_selection/
        plot_confusion_matrix.html#sphx-glr-auto-examples-model-selection-plot-confusion-matrix-py
    """
    if normalize:
        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
        #print("Normalized confusion matrix")
#    else:
#        print('Confusion matrix, without normalization')
#
#    print(cm)

    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    plt.yticks(tick_marks, classes)

    fmt = '.2f' if normalize else 'd'
    thresh = (cm.max() + cm.min())/ 2.
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, format(cm[i, j], fmt),
                 horizontalalignment="center",
                 color="white" if cm[i, j] > thresh else "black")

    plt.ylabel('True label')
    plt.xlabel('Predicted label')
    plt.tight_layout()

def plot_results(accuracy, normalize = False):
    # Plot the accuracy results for all models
    plt.figure(figsize = (12,36))
    # Compute subplot size - we want 3 plots in each row
    row_no = math.ceil(len(accuracy.columns)/3)
    for i in range(len(accuracy.columns)):
        plt.subplot(row_no,3,i+1)
        plot_confusion_matrix(accuracy[accuracy.columns[i]].values.reshape([2,2]),
                              classes = ['up','down'],
                              normalize=normalize,
                              title=accuracy.columns[i],
                              cmap=plt.cm.Blues)


# -*- coding: utf-8 -*-
"""
Created on Thu Feb 14 22:44:36 2019

@author: sathvik
"""

import cv2
import numpy as np
img=cv2.imread('C:\\Users\\sathvik\\Desktop\\opencv\\butterfly.jpeg',1)

img=cv2.GaussianBlur(img,(5,5),0)
cv2.imshow("image",img)
cv2.waitKey(0)

cv2.imwrite("GaussianBlur.jpeg",img)
cv2.destroyAllWindows()


import requests
from time import sleep

bot_token = "BOT_TOKEN"
channel_id = "@channel_name"

def telegram_bot_send_text(bot_message):
    """Отправляем сообщение в канал через телеграм бота"""
    send_text = 'https://api.telegram.org/bot' + bot_token + '/sendMessage?chat_id=' + channel_id + '&parse_mode=Markdown&text=' + bot_message
    response = requests.get(send_text).json()
    sleep(0.1)
    return response

if __name__ == "__main__":
    telegram_bot_send_text("IMPORT TELEGRAM")


import os

from flask import Flask

from flask import request

import requests, json

app = Flask(__name__)

@app.route('/')
def hello():
    default_t = 10
    degree = request.args.get('apparent_t')
    if degree is not None and len(degree) != 0:
        try:
            default_t = float(degree)
        except:
            print("degree is not float, ignore")
    createErrorResponse = request.args.get('createErrorResponse')
    url = "http://www.bom.gov.au/fwo/IDN60801/IDN60801.95765.json"
    if (createErrorResponse == "True"):
        url += ".error"
    user_agent = {'User-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36'}
    response_obj = requests.get(url, headers = user_agent)
    if response_obj.status_code != 200:
        rsp = {
                'error': "Error Connecting to BOM. Reason: " + response_obj.reason
            }
        rsp_code = 503
    else:
        response_text = response_obj.text
        response = json.loads(response_text)
        station_list = []
        item = {}
        for station in response['observations']['data']:
            if station['apparent_t'] > default_t:
                item = {
                        'name': station['name'],
                        'apparent_t': station['apparent_t'],
                        'lat': station['lat'],
                        'lon': station['lon']
                    }
                station_list.append(item)
                station_list.sort(key=lambda x: x.get('apparent_t'))
        print(station_list)
        rsp = {
                'response': station_list
            }
        rsp_code = 200
    return json.dumps(rsp), rsp_code

if __name__ == '__main__':
    app.run(host='0.0.0.0')


from github import Github
import datetime
import csv
from collections import OrderedDict
from shutil import copy2
import os
from tqdm import tqdm
import argparse
from aux_functions import display_StatTheGit

# Command-line input setup
parser = argparse.ArgumentParser(
    description="StatTheGit - Maintain GitHub repository stats for more than 14 days"
)
parser.add_argument(
    "--git_token_file",
    type=str,
    default="access_token.txt",
    help="GitHub token to your profile",
)
parser.add_argument(
    "--username", type=str, default="hag007", help="GitHub Username",
)
parser.add_argument(
    "--namespace", type=str, default="Shamir-Lab", help="GitHub Namespace",
)
parser.add_argument(
    "--repo_names",
    type=str,
    default='all', # ['EMP', 'DOMINO', 'SCAPP', 'MONET', 'MSP_UHS', 'PRODIGY', 'EMP-benchmark',  'Logrank-Inaccuracies', 'Multi-Omics-Cancer-Benchmark','PlasClass', 'Recycler', 'NEMO','CT-FOCS', 'DOCKS','Karyotype-reconstruction','SPRINT', 'Sorting-Cancer-Karyotypes', 'FOCS', 'ADEPTUS-2.0','GENEPARK', 'Faucet', 'BARCODE']
    nargs="+",
    help="Name of repositories seperated by space. Leave it empty and all the repositories will be serviced",
)

if __name__ == "__main__":
    # Parse the command line
    display_StatTheGit()
    args = parser.parse_args()
    g = Github(open(args.git_token_file).read().strip())
    repo_names = []
    # Check the repositories
    if "all" not in args.repo_names:
        # repo_names.append(args.repo_names)
        repo_names = args.repo_names
        print(repo_names)
    else:
        for repo in g.get_user().get_repos():
            repo_full_name = repo._full_name.value
            if args.namespace == repo_full_name.split("/")[0]:
                repo_name = repo_full_name.split("/")[1]
                repo_names.append(repo_name)

    for repo_n in tqdm(repo_names):
        # Process each repository
        repo_str = args.namespace + "/" + repo_n
        print("Processing: ", repo_n)
        repo = g.get_repo(repo_str)

        # Get repository clones statistics
        clone_stat = repo.get_clones_traffic()
        clone_stat = clone_stat["clones"]

        # Get repository views statistics
        traffic_stat = repo.get_views_traffic()
        print(traffic_stat)
        traffic_stat = traffic_stat["views"]

        # Get repository commits statistics
        commit_stat = repo.get_commits()
        commits=[a.raw_data['commit']['author']['date'].split('T')[0].split(' ')[0] for a in list(commit_stat)]
        earliest_commit_date=commits[0]

        # Get URL
        repo_url = repo.html_url

        # The stats fetched from GitHub packaged has date missing where the clones/views are zero.
        # The following lines appends missing dates and orders them.

        if len(clone_stat) > 0 or True:
            print(clone_stat)
            print(traffic_stat)
            # Find the earliest date between the views and clones
            if len(traffic_stat) > 0:
                earliest_exposure_date=traffic_stat[0].timestamp.date()
                if len(clone_stat) > 0 and traffic_stat[0].timestamp.date() > clone_stat[0].timestamp.date():
                    earliest_exposure_date = clone_stat[0].timestamp.date()

            else:
                earliest_exposure_date=datetime.datetime.strptime("1970-01-01", '%Y-%m-%d').date()
            date_array = []
            clone_array = {}
            traffic_array = {}

            # Generate array of dates under consideration
            for d in range(14):
                latest_date = str(earliest_exposure_date + datetime.timedelta(days=d))
                # Assign zeros to clone and views statistics
                clone_array[latest_date] = 0
                traffic_array[latest_date] = 0

            # Populate the clone statistics for the available date.
            # For unavailable dates, the stat is already initialized to zero
            for c in clone_stat:
                clone_array[str(c.timestamp.date())] = c.uniques

            for v in traffic_stat:
                traffic_array[str(v.timestamp.date())] = v.uniques

            # Create the folder of username if it doesn't exists
            path_to_folder = "repo_stats/" + args.username
            if not os.path.exists(path_to_folder):
                os.makedirs(path_to_folder)

            exposure_csv_str = os.path.join("repo_stats", repo_str.split("/")[0], "exposure", repo_str.split("/")[1] + ".txt")
            exposure_csv_str_temp = os.path.join("repo_stats", repo_str.split("/")[0], "exposure", repo_str.split("/")[1] + "_temp.txt")
            commits_csv_str = os.path.join("repo_stats", repo_str.split("/")[0], "commits", repo_str.split("/")[1] + ".txt")
            commits_csv_str_temp = os.path.join("repo_stats", repo_str.split("/")[0], "commits", repo_str.split("/")[1] + "_temp.txt")
            url_csv_str = os.path.join("repo_stats", repo_str.split("/")[0], "urls", repo_str.split("/")[1] + ".txt")

            # Save the stat file as another temp file.
            if os.path.exists(exposure_csv_str):
                s = copy2(exposure_csv_str, exposure_csv_str_temp)
            if os.path.exists(commits_csv_str):
                s = copy2(commits_csv_str, commits_csv_str_temp)

            # Create CSV file.
            try:
                os.makedirs(os.path.dirname(exposure_csv_str))
            except:
                pass
            try:
                os.makedirs(os.path.dirname(commits_csv_str))
            except:
                pass
            try:
                os.makedirs(os.path.dirname(url_csv_str))
            except:
                pass

            exposure_csv_file = open(exposure_csv_str, "w")
            exposure_writer = csv.writer(exposure_csv_file)
            commits_csv_file = open(commits_csv_str, "w")
            commits_writer = csv.writer(commits_csv_file)

            # Define header of the CSV file
            exposure_writer.writerow(["Date", "Clones", "Traffic"])
            commits_writer.writerow(["Commits"])

            clone_array = OrderedDict(sorted(clone_array.items(), key=lambda t: t[0]))
            traffic_array = OrderedDict(sorted(traffic_array.items(), key=lambda t: t[0]))

            if os.path.exists(exposure_csv_str_temp):
                # copyfile(csv_str, csv_str_temp)
                cc = 1
                with open(exposure_csv_str_temp) as exposure_csv_file:
                    csv_reader = csv.reader(exposure_csv_file, delimiter=",")
                    line_count = 0
                    for row in csv_reader:
                        if line_count > 0:
                            datetime_obj = datetime.datetime.strptime(
                                row[0], "%Y-%m-%d"
                            ).date()
                            compare_date = datetime.datetime.strptime(
                                str(earliest_exposure_date), "%Y-%m-%d"
                            ).date()

                            if datetime_obj < compare_date or compare_date < datetime.datetime.strptime("1970-01-30", "%Y-%m-%d").date():
                                exposure_writer.writerow([row[0], row[1], row[2]])
                            else:
                                break
                        line_count += 1

            if os.path.exists(commits_csv_str_temp):
                # copyfile(csv_str, csv_str_temp)
                cc = 1
                with open(commits_csv_str_temp) as commits_csv_file:
                    csv_reader = csv.reader(commits_csv_file, delimiter=",")
                    line_count = 0
                    for row in csv_reader:
                        if line_count > 0:
                            datetime_obj = datetime.datetime.strptime(
                                row[0], "%Y-%m-%d"
                            ).date()
                            compare_date = datetime.datetime.strptime(
                                str(earliest_commit_date), "%Y-%m-%d"
                            ).date()

                            if datetime_obj < compare_date or compare_date < datetime.datetime.strptime("1970-01-30", "%Y-%m-%d").date():
                                commits_writer.writerow([row[0]])
                            else:
                                break
                        line_count += 1

            compare_date = datetime.datetime.strptime(str(earliest_exposure_date), "%Y-%m-%d").date()
            first_date= datetime.datetime.strptime("1970-01-30", "%Y-%m-%d").date()
            if compare_date>first_date or not os.path.exists(exposure_csv_str_temp):
                for (key_clone, value_clone), (key_traffic, value_traffic) in zip(
                    clone_array.items(), traffic_array.items()
                ):
                    exposure_writer.writerow([key_clone, value_clone, value_traffic])

                exposure_csv_file.close()

            for commit in commits:
                commits_writer.writerow([commit])

            commits_csv_file.close()

            exposure_csv_file = open(exposure_csv_str_temp, "w")
            exposure_writer = csv.writer(exposure_csv_file)
            exposure_writer.writerow(["Date", "Clones", "Traffic"])
            with open(exposure_csv_str) as exposure_csv_file:
                csv_reader = csv.reader(exposure_csv_file, delimiter=",")
                for row in csv_reader:
                    exposure_writer.writerow([row[0], row[1], row[2]])
            exposure_csv_file.close()

            commits_csv_file = open(commits_csv_str_temp, "w")
            commits_writer = csv.writer(commits_csv_file)
            commits_writer.writerow(["Commits"])
            with open(commits_csv_str) as commits_csv_file:
                csv_reader = csv.reader(commits_csv_file, delimiter=",")
                for row in csv_reader:
                    commits_writer.writerow([row[0]])
            commits_csv_file.close()

            url_csv_file = open(url_csv_str, "w")
            url_writer = csv.writer(url_csv_file)
            with open(url_csv_str) as url_csv_file:
                    url_writer.writerow(["URL"])
                    url_writer.writerow([repo_url])
            url_csv_file.close()

            # Remove temp file.
            os.remove(exposure_csv_str_temp)
            os.remove(commits_csv_str_temp)


from http.client import ACCEPTED
from django.shortcuts import render
from django.http import HttpResponse, JsonResponse
from rest_framework.parsers import JSONParser
from rest_framework.serializers import Serializer
from .models import UserModel, Meep
from .serializers import FollowerSerializer, UserSerializer, MeepSerializer, MeepFeedSerializer
from rest_framework.response import Response
from rest_framework.decorators import api_view, permission_classes
from rest_framework.authtoken.models import Token
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework import status
import json

from meepit import serializers

# Create your views here.
@api_view(['POST',])
@permission_classes((AllowAny,))
def SignUp(request):
    if request.method == 'POST':
        serializer = UserSerializer(data = request.data)
        data = {}
        if serializer.is_valid():
            user = serializer.save()
            data['response'] = "User registration successful"
            data['email'] = user.email
            data['uname'] = user.uname
            token = Token.objects.get(user=user).key
            data['token'] = token
            return JsonResponse(data, status=status.HTTP_200_OK)
        else:
            return JsonResponse(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@api_view(['POST'])
@permission_classes((IsAuthenticated,))
def CreateMeep(request):

    if request.method == 'POST':
        user = request.user
        serializer = MeepSerializer(data = request.data,context={'userid': user.id})
        data = {}
        if serializer.is_valid():
            meep = serializer.save()
            data['response'] = "Meep successfully created"
            data['meeptext'] = meep.meeptext
            data['user'] = str(user)
            return JsonResponse(data, status=status.HTTP_200_OK)
        else:
            return JsonResponse(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@api_view(['POST'])
@permission_classes((IsAuthenticated,))
def FollowPerson(request,uname):

    if request.method == 'POST':
        user = request.user
        serializer = FollowerSerializer(data = request.data,context={'userid':user.id,'person':uname})
        data = {}
        if serializer.is_valid():
            follower = serializer.save()
            data['response'] = "Follow successful"
            data['Follower'] = str(follower.follower)
            data['Followed Person'] = str(follower.person)
            return JsonResponse(data, status=status.HTTP_200_OK)
        else:
            return JsonResponse(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@api_view(['GET'])
@permission_classes((IsAuthenticated,))
def LoadMeeps(request):
    if request.method == 'GET':
        user = request.user
        meeps = MeepFeedSerializer(data=request.data,context={'userid':user.id})
        meepit = meeps.save()
        l = []
        if meeps.is_valid():
            for i in meepit:
                l.append(str(i.userid)+": "+str(i.meeptext))
            return JsonResponse(l,safe=False, status=status.HTTP_200_OK)
        else:
            return JsonResponse(meeps.errors, status=status.HTTP_400_BAD_REQUEST)


"""
Utils specific to T5 network.
"""

# torch
import torch

# numpy
import numpy as np

# numpy
from transformers.generation_stopping_criteria import (
    MaxLengthCriteria,
    StoppingCriteriaList,
)

# TRT-HuggingFace
from NNDF.general_utils import measure_python_inference_code
from NNDF.torch_utils import use_cuda

@use_cuda
def decoder_inference(
    t5_decoder, input_ids, encoder_last_hidden_state, timing_profile, use_cuda=True
):
    decoder_stmt = lambda: t5_decoder(
        input_ids=input_ids, encoder_hidden_states=encoder_last_hidden_state
    )
    decoder_e2e_median_time = measure_python_inference_code(
        decoder_stmt, number=timing_profile.number, iterations=timing_profile.iterations
    )

    return (decoder_stmt(), decoder_e2e_median_time)

@use_cuda
def encoder_inference(t5_encoder, input_ids, timing_profile, use_cuda=True):
    encoder_stmt = lambda: t5_encoder(input_ids=input_ids)
    encoder_e2e_median_time = measure_python_inference_code(
        encoder_stmt, number=timing_profile.number, iterations=timing_profile.iterations
    )

    return (encoder_stmt(), encoder_e2e_median_time)

# Code specifically for Pythonic inference measurement used across all T5 related scripts
@use_cuda
def full_inference_greedy(
    t5_encoder,
    t5_decoder,
    input_ids,
    tokenizer,
    timing_profile,
    max_length,
    use_cuda=True,
):
    stopping_criteria = StoppingCriteriaList([MaxLengthCriteria(max_length)])
    decoder_input_ids = torch.full(
        (1, 1), tokenizer.convert_tokens_to_ids(tokenizer.pad_token), dtype=torch.int32
    )

    if use_cuda:
        decoder_input_ids = decoder_input_ids.to("cuda")

    def _e2e():
        encoder_last_hidden_state = t5_encoder(input_ids=input_ids)

        return t5_decoder.greedy_search(
            input_ids=decoder_input_ids,
            encoder_hidden_states=encoder_last_hidden_state,
            stopping_criteria=stopping_criteria,
        )

    full_e2e_median_time = measure_python_inference_code(
        _e2e,
        number=timing_profile.number,
        iterations=timing_profile.iterations,
    )

    return (_e2e(), full_e2e_median_time)