#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Developed by Shangchen Zhou <shangchenzhou@gmail.com>

import os
import sys
import torch
import torch.nn as nn
import torch.nn.init as init
import random
import numpy as np
from datetime import datetime as dt
from config import cfg
import torch.nn.functional as F

import cv2

def mkdir(path):
    if not os.path.isdir(path):
        mkdir(os.path.split(path)[0])
    else:
        return
    os.mkdir(path)

def var_or_cuda(x):
    if torch.cuda.is_available():
        x = x.cuda(non_blocking=True)
    return x

def initialize_weights(net_l, scale=1):
    if not isinstance(net_l, list):
        net_l = [net_l]
    for net in net_l:
        for n, m in net.named_modules():
            if isinstance(m, nn.Conv2d) and not '_mean' in n:
                init.kaiming_normal_(m.weight, a=0, mode='fan_in')
                m.weight.data *= scale  # for residual block
                if m.bias is not None:
                    m.bias.data.zero_()
            elif isinstance(m, nn.Linear):
                init.kaiming_normal_(m.weight, a=0, mode='fan_in')
                m.weight.data *= scale
                if m.bias is not None:
                    m.bias.data.zero_()
            elif isinstance(m, nn.BatchNorm2d):
                init.constant_(m.weight, 1)
                init.constant_(m.bias.data, 0.0)

def set_random_seed(seed, deterministic=False):
    """Set random seed just for debug.
    Args:
        seed (int): Seed to be used.
        deterministic (bool): Whether to set the deterministic option for
            CUDNN backend, i.e., set `torch.backends.cudnn.deterministic`
            to True and `torch.backends.cudnn.benchmark` to False.
            Default: False.
    """
    random.seed(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)
    torch.cuda.manual_seed_all(seed)
    if deterministic:
        torch.backends.cudnn.deterministic = True
        torch.backends.cudnn.benchmark = False

def save_checkpoint(file_path, file_name, epoch_idx, net, solver, best_PSNR, best_epoch):
    if not os.path.exists(file_path):
        mkdir(file_path)
    file_path = os.path.join(file_path, file_name)
    print('[INFO] %s Saving checkpoint to %s ...' % (dt.now(), file_path))
    checkpoint = {
        'epoch_idx': epoch_idx,
        'best_PSNR': best_PSNR,
        'best_epoch': best_epoch,
        'net_state_dict': net.state_dict(),
        'solver_state_dict': solver.state_dict()
    }
    torch.save(checkpoint, file_path)

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

def get_weight_parameters(model):
    return [param for name, param in model.named_parameters() if ('weight' in name)]

def get_bias_parameters(model):
    return [param for name, param in model.named_parameters() if ('bias' in name)]

class AverageMeter(object):
    """Computes and stores the average and current value"""
    def __init__(self):
        self.reset()

    def reset(self):
        self.val = 0
        self.avg = 0
        self.sum = 0
        self.count = 0

    def update(self, val, n=1):
        self.val = val
        self.sum += val * n
        self.count += n
        self.avg = self.sum / self.count

    def __repr__(self):
        return '{:.5f} ({:.5f})'.format(self.val, self.avg)

##################################
# Image convert functions
##################################
def crop_like(input, target):
    if input.size()[2:] == target.size()[2:]:
        return input
    else:
        return input[:, :, :target.size(2), :target.size(3)].contiguous()

def crop_border(img_list, crop_border):
    """Crop borders of images
    Args:
        img_list (list [Numpy]): HWC
        crop_border (int): crop border for each end of height and weight
    Returns:
        (list [Numpy]): cropped image (list)
    """
    if crop_border == 0: return img_list

    if isinstance(img_list, list):
        return [v[crop_border:-crop_border, crop_border:-crop_border] for v in img_list]
    else:
        return v[crop_border:-crop_border, crop_border:-crop_border]

def tensor2img(tensor, out_type=np.uint8, min_max=(0, 255)):
    '''
    Converts a torch Tensor into an image Numpy array
    Input: 4D(B,(3/1),H,W), 3D(C,H,W), or 2D(H,W), any range, RGB channel order
    Output: 3D(H,W,C) or 2D(H,W), [0,255], np.uint8 (default)
    '''
    assert tensor.dim() == 3

    tensor = tensor.squeeze().float().cpu().clamp_(*min_max)  # clamp
    img_np = tensor.numpy()
    img_np = np.transpose(img_np, (1, 2, 0))[:,:,[2,1,0]]  # HWC, to BGR for cv2 imwrite

    if out_type == np.uint8:
        img_np = img_np.round()
        # Important. Unlike matlab, numpy.unit8() WILL NOT round by default.
    return img_np.astype(out_type)

def img2tensor(img, min_max=(0, 255)):
    '''
    Converts a numpy.ndarray (H x W x C) to a torch.FloatTensor of shape (C x H x W).
    '''
    img = img.astype('float32')
    img = np.transpose(img, (2, 0, 1))
    img = np.ascontiguousarray(img)
    img = torch.from_numpy(img)
    return img.clamp(*min_max)

def rgb2ycbcr(img, only_y=True):
    '''same as matlab rgb2ycbcr
    only_y: only return Y channel
    Input:
        uint8, [0, 255]
        float, [0, 1]
    For matplotlib.image
    '''
    in_img_type = img.dtype
    img.astype(np.float32)
    if in_img_type != np.uint8:
        img *= 255.
    # convert
    if only_y:
        rlt = np.dot(img, [65.481, 128.553, 24.966]) / 255.0 + 16.0
    else:
        rlt = np.matmul(img, [[65.481, -37.797, 112.0], [128.553, -74.203, -93.786],
                              [24.966, 112.0, -18.214]]) / 255.0 + [16, 128, 128]
    if in_img_type == np.uint8:
        rlt = rlt.round()
    else:
        rlt /= 255.
    return rlt.astype(in_img_type)

def bgr2ycbcr(img, only_y=True):
    '''same as matlab rgb2ycbcr
    only_y: only return Y channel
    Input:
        uint8, [0, 255]
        float, [0, 1]
    For opencv
    '''
    in_img_type = img.dtype
    img.astype(np.float32)
    if in_img_type != np.uint8:
        img *= 255.
    # convert
    if only_y:
        rlt = np.dot(img, [24.966, 128.553, 65.481]) / 255.0 + 16.0
    else:
        rlt = np.matmul(img, [[24.966, 112.0, -18.214], [128.553, -74.203, -93.786],
                              [65.481, -37.797, 112.0]]) / 255.0 + [16, 128, 128]
    if in_img_type == np.uint8:
        rlt = rlt.round()
    else:
        rlt /= 255.
    return rlt.astype(in_img_type)

##################################
# adaptive_instance_normalization
##################################

def adaptive_instance_normalization(center_feat, knn_feat, eps=1e-5):
    # center_feat = center_feat.contiguous()
    # knn_feat = knn_feat.contiguous()
    b,m,c,p = center_feat.size()
    _,_,_,sp,k = knn_feat.size()

    center_var = center_feat.var(dim=3) + eps
    center_std = center_var.sqrt().view(b, m, c, 1, 1)
    center_mean = center_feat.mean(dim=3).view(b, m, c, 1, 1)

    knn_var = knn_feat.var(dim=3) + eps
    knn_std = knn_var.sqrt().view(b, m, c, 1, k)
    knn_mean = knn_feat.mean(dim=3).view(b, m, c, 1, k)

    size = knn_feat.size()
    normalized_feat = (knn_feat - knn_mean.expand(size)) / knn_std.expand(size)

    return normalized_feat * center_std.expand(size) + center_mean.expand(size)

##################################
# Efficient and effective test
##################################
class Chop(nn.Module):
    def __init__(self, model):
        super(Chop, self).__init__()
        self.model = model
        self.scale = cfg.CONST.SCALE
        if cfg.CONST.SCALE == 4:
            self.scale_s = 2
        else:
            self.scale_s = cfg.CONST.SCALE

    def forward(self, x_son, x, shave=12, min_size=40000):
        n_GPUs = min(cfg.CONST.NUM_GPU, 4)
        b, c, h_s, w_s = x_son.size()
        _, _, h, w = x.size()
        h_0, w_0 = h%self.scale_s, w%self.scale_s

        h_half_s, w_half_s = h_s//2, w_s//2
        h_half, w_half = h_half_s*self.scale_s, w_half_s*self.scale_s

        shave_s = shave//self.scale_s

        h_size_s, w_size_s = h_half_s + shave_s, w_half_s + shave_s
        h_size, w_size = h_size_s*self.scale_s, w_size_s*self.scale_s

        lr_list_s = [
            x_son[:, :, 0:h_size_s, 0:w_size_s],
            x_son[:, :, 0:h_size_s, (w_s - w_size_s):w_s],
            x_son[:, :, (h_s - h_size_s):h_s, 0:w_size_s],
            x_son[:, :, (h_s - h_size_s):h_s, (w_s - w_size_s):w_s]]

        lr_list = [
            x[:, :, 0:h_size+h_0, 0:w_size+w_0],
            x[:, :, 0:h_size+h_0, (w - w_size-w_0):w],
            x[:, :, (h - h_size-h_0):h, 0:w_size+w_0],
            x[:, :, (h - h_size-h_0):h, (w - w_size-w_0):w]]

        if w_size * h_size < min_size:
            sr_list = []
            for i in range(0, 4, n_GPUs):
                lr_s_batch = torch.cat(lr_list_s[i:(i + n_GPUs)], dim=0)
                lr_batch = torch.cat(lr_list[i:(i + n_GPUs)], dim=0)
                sr_batch = self.model(lr_s_batch, lr_batch)
                sr_list.extend(sr_batch.chunk(n_GPUs, dim=0))
        else:
            sr_list = [
                self.forward(patch_s, patch, shave=shave, min_size=min_size) \
                for (patch_s, patch) in zip(lr_list_s, lr_list)
            ]

        h, w = self.scale * h, self.scale * w

        h_half, w_half = self.scale * h_half, self.scale * w_half
        h_size, w_size = self.scale * h_size, self.scale * w_size
        shave *= self.scale
        h_0, w_0 = h_0*self.scale, w_0*self.scale
        output = x.new(b, c, h, w)
        output[:, :, 0:h_half, 0:w_half] \
            = sr_list[0][:, :, 0:h_half, 0:w_half]
        output[:, :, 0:h_half, w_half:w] \
            = sr_list[1][:, :, 0:h_half, (w_size - w + w_half+w_0):w_size+w_0]
        output[:, :, h_half:h, 0:w_half] \
            = sr_list[2][:, :, (h_size - h + h_half+h_0):h_size+h_0, 0:w_half]
        output[:, :, h_half:h, w_half:w] \
            = sr_list[3][:, :, (h_size - h + h_half+h_0):h_size+h_0, (w_size - w + w_half+w_0):w_size+w_0]

        return output

def forward_x8(x_son, x, forward_function):
    def _transform(v, op):

        v2np = v.data.cpu().numpy()
        if op == 'v':
            tfnp = v2np[:, :, :, ::-1].copy()
        elif op == 'h':
            tfnp = v2np[:, :, ::-1, :].copy()
        elif op == 't':
            tfnp = v2np.transpose((0, 1, 3, 2)).copy()

        ret = torch.Tensor(tfnp).cuda()

        return ret

    lr_son_list = [x_son]
    lr_list = [x]
    for tf in 'v', 'h', 't':
        lr_son_list.extend([_transform(t, tf) for t in lr_son_list])
        lr_list.extend([_transform(t, tf) for t in lr_list])

    sr_list = [forward_function(lr_son, lr) for (lr_son, lr) in zip(lr_son_list, lr_list)]
    for i in range(len(sr_list)):
        if i > 3:
            sr_list[i] = _transform(sr_list[i], 't')
        if i % 4 > 1:
            sr_list[i] = _transform(sr_list[i], 'h')
        if (i % 4) % 2 == 1:
            sr_list[i] = _transform(sr_list[i], 'v')

    output_cat = torch.cat(sr_list, dim=0)
    output = output_cat.mean(dim=0, keepdim=True)

    return output


import numpy as np
import scipy.io
from nn import *
import matplotlib.pyplot as plt
import pickle
import string
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import ImageGrid

train_data = scipy.io.loadmat('../data/nist36_train.mat')
valid_data = scipy.io.loadmat('../data/nist36_valid.mat')

train_x, train_y = train_data['train_data'], train_data['train_labels']
valid_x, valid_y = valid_data['valid_data'], valid_data['valid_labels']

max_iters = 150
# pick a batch size, learning rate
batch_size = 64
learning_rate = 0.001#Also trained with 0.01, 0.001 and 0.0001
hidden_size = 64

batches = get_random_batches(train_x, train_y, batch_size)
batch_num = len(batches)

params = {}

# initialize layers here
initialize_weights(train_x.shape[1], hidden_size, params, 'layer1')
initialize_weights(hidden_size, train_y.shape[1], params, 'output')

# with default settings, you should get loss < 150 and accuracy > 80%
train_loss, train_accuracy = [], []
valid_loss, valid_accuracy = [], []
for itr in range(max_iters):
    total_loss = 0
    total_acc = 0
    for xb, yb in batches:
        # training loop can be exactly the same as q2!

        # plt.figure()
        # plt.imshow(np.reshape(xb,(64,32,32))[0,:,:])
        # plt.colorbar()
        # plt.show()

        yb = yb.astype(int)
        # forward
        h1 = forward(xb, params, 'layer1')
        probs = forward(h1, params, 'output', softmax)

        # loss
        # be sure to add loss and accuracy to epoch totals
        loss, acc = compute_loss_and_acc(yb, probs)
        total_loss += loss
        total_acc += acc

        # backward
        delta2 = backwards(probs - yb, params, 'output', linear_deriv)
        backwards(delta2, params, 'layer1', sigmoid_deriv)

        # apply gradient
        params['Wlayer1'] -= learning_rate * params['grad_Wlayer1']
        params['blayer1'] -= learning_rate * params['grad_blayer1']
        params['Woutput'] -= learning_rate * params['grad_Woutput']
        params['boutput'] -= learning_rate * params['grad_boutput']

    total_acc /= batch_num

    train_loss.append(total_loss)
    train_accuracy.append(total_acc)

    if itr % 2 == 0:
        print("itr: {:02d} \t loss: {:.2f} \t acc : {:.2f}".format(itr, total_loss, total_acc))

    # run on validation set per iteration
    valid_y = valid_y.astype(int)
    probs = forward(forward(valid_x, params, 'layer1'), params, 'output', softmax)
    loss, acc = compute_loss_and_acc(valid_y, probs)
    valid_loss.append(loss)
    valid_accuracy.append(acc)

plt.figure('accuracy')
plt.plot(range(max_iters), train_accuracy, color='r')
plt.plot(range(max_iters), valid_accuracy, color='g')
plt.legend(['train', 'validation'])
plt.show()

plt.figure('loss')
plt.plot(range(max_iters), train_loss, color='r')
plt.plot(range(max_iters), valid_loss, color='g')
plt.legend(['train', 'validation'])
plt.show()

# run on validation set and report accuracy! should be above 75%
h1 = forward(valid_x, params, 'layer1')
probs = forward(h1, params, 'output', softmax)
valid_loss, valid_acc = compute_loss_and_acc(valid_y, probs)

print('Validation accuracy: ', valid_acc)

test_data = scipy.io.loadmat('../data/nist36_test.mat')
test_x, test_y = test_data['test_data'], test_data['test_labels']
# run on test set
h1 = forward(test_x, params, 'layer1')
probs = forward(h1, params, 'output', softmax)
test_loss, test_acc = compute_loss_and_acc(test_y, probs)
print('Test accuracy: ', test_acc)

saved_params = {k:v for k,v in params.items() if '_' not in k}
with open('q3_weights.pickle', 'wb') as handle:
    pickle.dump(saved_params, handle, protocol=pickle.HIGHEST_PROTOCOL)

with open('q3_weights.pickle', 'rb') as handle:
    data = pickle.load(handle)
    params['Wlayer1'] = data['Wlayer1']
    params['blayer1'] = data['blayer1']
    params['Woutput'] = data['Woutput']
    params['boutput'] = data['boutput']

# Q3.1.3

empty_params = {}
initialize_weights(train_x.shape[1], hidden_size, empty_params, 'layer1')
initialize_weights(hidden_size, train_y.shape[1], empty_params, 'output')

fig = plt.figure()
grid = ImageGrid(fig, 111, nrows_ncols=(8, 8))
for i in range(hidden_size):
    grid[i].imshow(np.reshape(empty_params['Wlayer1'][:, i], (32, 32)))  # The AxesGrid object work as a list of axes.
    plt.axis('off')
plt.show()

fig = plt.figure()
grid = ImageGrid(fig, 111, nrows_ncols=(8, 8))
for i in range(hidden_size):
    grid[i].imshow(np.reshape(params['Wlayer1'][:, i], (32, 32)))  # The AxesGrid object work as a list of axes.
    plt.axis('off')
plt.show()

# Q3.1.4

def get_confusion_matrix(probs, y):
    confusion_matrix = np.zeros((y.shape[1], y.shape[1]))

    y = y.astype(int)
    pred_y = (probs == np.expand_dims(np.max(probs, axis=1), axis=1))
    with_same_prob = np.where(np.sum(pred_y, axis=1) > 1)[0]
    for i in range(with_same_prob.shape[0]):
        pred_y[i, np.where(pred_y[i, :] == np.max(pred_y[i, :]))[0][0] + 1:] = False

    yl = [np.where(y[i, :] == 1)[0][0] for i in range(y.shape[0])]
    pred_yl = [np.where(pred_y[i, :] == 1)[0][0] for i in range(pred_y.shape[0])]

    for a, p in zip(yl, pred_yl):
        confusion_matrix[a][p] += 1

    return confusion_matrix

# confusion matrix for training data
train_data = scipy.io.loadmat('../data/nist36_train.mat')
train_x, train_y = train_data['train_data'], train_data['train_labels']
train_probs = forward(forward(train_x, params, 'layer1'), params, 'output', softmax)

confusion_matrix = get_confusion_matrix(train_probs, train_y)

plt.imshow(confusion_matrix, interpolation='nearest')
plt.grid(True)
plt.xticks(np.arange(36), string.ascii_uppercase[:26] + ''.join([str(_) for _ in range(10)]))
plt.yticks(np.arange(36), string.ascii_uppercase[:26] + ''.join([str(_) for _ in range(10)]))
plt.show()

# confusion matrix for validation data
valid_data = scipy.io.loadmat('../data/nist36_valid.mat')
valid_x, valid_y = valid_data['valid_data'], valid_data['valid_labels']
valid_probs = forward(forward(valid_x, params, 'layer1'), params, 'output', softmax)

confusion_matrix = get_confusion_matrix(valid_probs, valid_y)

plt.imshow(confusion_matrix, interpolation='nearest')
plt.grid(True)
plt.xticks(np.arange(36), string.ascii_uppercase[:26] + ''.join([str(_) for _ in range(10)]))
plt.yticks(np.arange(36), string.ascii_uppercase[:26] + ''.join([str(_) for _ in range(10)]))
plt.show()

# confusion matrix for test data
test_data = scipy.io.loadmat('../data/nist36_test.mat')
test_x, test_y = test_data['test_data'], test_data['test_labels']
test_probs = forward(forward(test_x, params, 'layer1'), params, 'output', softmax)

confusion_matrix = get_confusion_matrix(test_probs, test_y)

plt.imshow(confusion_matrix, interpolation='nearest')
plt.grid(True)
plt.xticks(np.arange(36), string.ascii_uppercase[:26] + ''.join([str(_) for _ in range(10)]))
plt.yticks(np.arange(36), string.ascii_uppercase[:26] + ''.join([str(_) for _ in range(10)]))
plt.show()


from typing import List

from celery import shared_task

from exareme2 import DATA_TABLE_PRIMARY_KEY
from exareme2.exceptions import DataModelUnavailable
from exareme2.exceptions import DatasetUnavailable
from exareme2.node import config as node_config
from exareme2.node.monetdb_interface import views
from exareme2.node.monetdb_interface.common_actions import create_table_name
from exareme2.node.monetdb_interface.common_actions import get_data_models
from exareme2.node.monetdb_interface.common_actions import (
    get_dataset_code_per_dataset_label,
)
from exareme2.node.node_logger import initialise_logger
from exareme2.node_tasks_DTOs import TableInfo
from exareme2.node_tasks_DTOs import TableType

MINIMUM_ROW_COUNT = node_config.privacy.minimum_row_count

@shared_task
@initialise_logger
def get_views(request_id: str, context_id: str) -> List[str]:
    """
    Parameters
    ----------
    request_id : str
        The identifier for the logging
    context_id : str
        The id of the experiment

    Returns
    ------
    List[str]
        A list of view names
    """
    return views.get_view_names(context_id)

@shared_task
@initialise_logger
def create_data_model_views(
    request_id: str,
    context_id: str,
    command_id: str,
    data_model: str,
    datasets: List[str],
    columns_per_view: List[List[str]],
    filters: dict = None,
    dropna: bool = True,
    check_min_rows: bool = True,
) -> List[str]:
    """
    Create a view on a provided data model with specific columns, filters and datasets to the DB.

    Parameters
    ----------
    request_id : str
        The identifier for the logging
    context_id : str
        The id of the experiment
    command_id : str
        The id of the command that the view
    data_model : str
        The data_model data table on which the view will be created
    datasets : List[str]
        The datasets that will be used in the view.
    columns_per_view : List[List[str]]
        One view will be created for each list of columns.
    filters : dict
        A Jquery filters object
    dropna : bool
        A flag that determines if the not null constraints about the columns should be included in the filters
    check_min_rows : bool
        A flag that determines if the min_rows_threshold should be checked.

    Returns
    ------
    List[str(TableInfo)]
        A list of TableInfo objects in a jsonified format
    """
    _validate_data_model_and_datasets_exist(data_model, datasets)
    if datasets:
        filters = _get_filters_with_datasets_constraints(
            filters=filters, datasets=datasets
        )

    # In each view, it's not null constraints should include the columns of ALL views
    if dropna:
        all_columns = [column for columns in columns_per_view for column in columns]
        filters = _get_filters_with_columns_not_null_constraints(
            filters=filters, columns=all_columns
        )

    return [
        create_data_model_view(
            context_id=context_id,
            command_id=command_id,
            result_id=str(count),
            data_model=data_model,
            columns=view_columns,
            filters=filters,
            check_min_rows=check_min_rows,
        ).json()
        for count, view_columns in enumerate(columns_per_view)
    ]

def create_data_model_view(
    context_id: str,
    command_id: str,
    result_id: str,
    data_model: str,
    columns: List[str],
    filters: dict = None,
    check_min_rows: bool = True,
) -> TableInfo:
    view_name = create_table_name(
        table_type=TableType.VIEW,
        node_id=node_config.identifier,
        context_id=context_id,
        command_id=command_id,
        result_id=result_id,
    )
    columns.insert(0, DATA_TABLE_PRIMARY_KEY)

    return views.create_view(
        view_name=view_name,
        table_name=f'"{data_model}"."primary_data"',
        columns=columns,
        filters=filters,
        minimum_row_count=MINIMUM_ROW_COUNT,
        check_min_rows=check_min_rows,
    )

def _get_filters_with_datasets_constraints(filters, datasets):
    """
    This function will return the given filters which will also include the dataset's constraints.
    """
    rules = [
        {
            "id": "dataset",
            "field": "dataset",
            "type": "string",
            "input": "text",
            "operator": "in",
            "value": datasets,
        }
    ]

    if filters:
        rules.append(filters)

    return {
        "condition": "AND",
        "rules": rules,
        "valid": True,
    }

def _get_filters_with_columns_not_null_constraints(filters, columns):
    """
    This function will return the given filters which will also include the columns' not null constraints.
    """
    rules = [
        {
            "condition": "AND",
            "rules": [
                {
                    "id": variable,
                    "type": "string",
                    "operator": "is_not_null",
                    "value": None,
                }
                for variable in columns
            ],
        }
    ]

    if filters:
        rules.append(filters)

    return {
        "condition": "AND",
        "rules": rules,
        "valid": True,
    }

def _validate_data_model_and_datasets_exist(data_model: str, datasets: List[str]):
    if data_model not in get_data_models():
        raise DataModelUnavailable(node_config.identifier, data_model)

    available_datasets = get_dataset_code_per_dataset_label(data_model)
    for dataset in datasets:
        if dataset not in available_datasets:
            raise DatasetUnavailable(node_config.identifier, dataset)

@shared_task
@initialise_logger
def create_view(
    request_id: str,
    context_id: str,
    command_id: str,
    table_name: str,
    columns: List[str],
    filters: dict,
) -> str:
    """
    Creates a view of a table with specific columns and filters to the DB.

    Parameters
    ----------
    request_id : str
        The identifier for the logging
    context_id : str
        The id of the experiment
    command_id : str
        The id of the command that the view
    table_name : str
        The name of the table
    columns : List[str]
        A list of column names
    filters : dict
        A Jquery filters in a dict

    Returns
    ------
    str(TableInfo)
        A TableInfo object in a jsonified format
    """
    view_name = create_table_name(
        TableType.VIEW,
        node_config.identifier,
        context_id,
        command_id,
    )
    return views.create_view(
        view_name=view_name,
        table_name=table_name,
        columns=columns,
        filters=filters,
        minimum_row_count=MINIMUM_ROW_COUNT,
    ).json()


# -*- coding: utf-8 -*-
"""
Created on Sat Nov  3 14:44:38 2018

@author: Administrator
"""
def ten_year_calc(num,start_date):
    yearLen = timedelta(days=365)
    for x in range(num):
        print(start_date + yearLen*x)

from datetime import date
from datetime import timedelta
import pandas as pd

d = date(2007, 11, 5)
print(d.isoformat())
ten_year_calc(10, d)

s= '4545,6565'.split(',')
print(s[0])

arr = []
arr.append(1)
arr.append(2)
print(arr)

d = {'col1': [1, 2], 'col2': [3, 4]}
df = pd.DataFrame()


# -*- coding: utf-8 -*-
"""
Created on Thu Dec 04 17:16:27 2014

@author: lwasser
"""

#import libraries that Python needs to read shapefiles
import h5py
import numpy as np
import shapefile

#enter the directory that you wish to explore
#fileDirectory = (r'/Volumes/My Passport/D17_Data_2014_Distro/02_SJER/SJER_Spectrometer_Data/2013061320/Reflectance/')
#fileDirectory = (r'X:/All_data_distro/D17/SJER/2013/SJER_Spectrometer_Data/2013061320/Reflectance')
#fileDirectory = (r'F:/D17_Data_2014_Distro/02_SJER/SJER_Spectrometer_Data/2013061320/Reflectance/')
#windows version
fileDirectory = (r'F:/D17_Data_2014_Distro/02_SJER/SJER_Spectrometer_Data/2013061320/Reflectance/')

#get a list of all files in the directory
from os import listdir
from os.path import isfile, join
onlyfiles = [ f for f in listdir(fileDirectory) if isfile(join(fileDirectory,f)) ]

#Generate a list of the names of H5 files in the specified directory
onlyH5files=[]
for f in onlyfiles:
  if f.endswith(".h5"):
    onlyH5files.append(f)

#filePattern=join(fileDirectory, '*.h5')

#a better way to import a list of files
#import glob
#onlyH5files = glob.glob(filePattern)

#should be able to populate this ahead of time with Nan
#oop through all of the files in the directory, extract flightline bounds and resolution
#calculate extent in UTM
finalLookup=[]
#for f in onlyH5files:
    #iterate through all H5 files in the directory
for f in xrange(len(onlyH5files)):
    #open the file name to the directory path so the code knows where to find
    #the hdf5 file to open.
    filePath=join(fileDirectory,onlyH5files[f])
    #open hdf5 file
    file = h5py.File(filePath, 'r')   # 'r' means that hdf5 file is open in read-only mode

    #Select the reflectance dataset within the H5 file and associated needed attributes.
    reflectance=file['/Reflectance']
    CRS=file['/coordinate system string']
    mapInfo=['/map info']

    #Split map info string to extract raster corner location
    mapInfo=str(file['map info'][:]).split(',')
    eastingUL=float(mapInfo[3])
    northingUL=float(mapInfo[4])
    xsize=float(mapInfo[5])
    ysize=float(mapInfo[6])
    zone=int(mapInfo[7])

    #grab the shape of the reflectance matrix (the raster size)
    #Use this to define raster x,y,z extent (matrix dimensions)
    nb,nY,nX=reflectance.shape

    #find the extents of the hdf5 file
    yTop=northingUL
    yBot=northingUL-nY*ysize
    xLeft=eastingUL
    xRight=eastingUL+nX*xsize

    #find file centroid
    yCent=yBot+(nY/2)
    xCent=xLeft+(nX/2)

    #be sure to close the file
    file.close()

    #write out elements into a list
    fileExtents=[onlyH5files[f],yTop,yBot,xLeft,xRight,mapInfo,xCent,yCent]
    finalLookup.append(fileExtents)

#%reset clears all variables
print("All Files Inventoried - finalLookup Table Created!")

###########################################################################
# PART TWO -- Find flightlines for each plot
###########################################################################

#first get the plot coordinate

#plotBoundariesPath=(r'F:\ESA_WorkshopData\WorkingDirectory\Field_SHP_Use\SJERPlotCentroids_Buff_Square.shp')
#for mac
#plotBoundariesPath=(r'/Volumes/My Passport/ESA_WorkshopData/WorkingDirectory/Field_SHP_Use/SJERPlotCentroids_Buff_Square.shp')
plotBoundariesPath=(r'C:/Users/lwasser/Documents/GitHub/adventures-with-python/data/sjerPlots/SJERPlotCentroids_Buff_Square.shp')

sf = shapefile.Reader(plotBoundariesPath)
shapes = sf.shapes()

#read all of the fields in the shapefile
plotMetadata=sf.fields
records = sf.records()
#Create dictionary object that will store final data
#to access attribute data records[0][2:3]
plotIdDict={}

#loop through all plots, determine which fligthlines they fall wtihin the boundary of
#add the flightlines that fall wtihin the boundary of each plot to the dictionary
for j in xrange(len(shapes)):
    #get the coordinates of the plot boundary
    #bbox saves 4 corners as follows [left X, Lower Y, right X, Upper Y ]
    plotVertices=shapes[j].bbox
    #grab plot centroid coords
    plotCentroidX=float(records[j][3])
    plotCentroidY=float(records[j][2])

    #finalLookup order 1:Ytop 2:ybottom 3:xLeft  4:xRIGHT
    #loop through all flightlines - figure out which ones contain the plot boundary
    #if they create the boundary, then store that in the disctionary
    #plotID
    isInTemp=[]
    for i in xrange(len(finalLookup)):
        if ((plotVertices[0] > finalLookup[i][3]) and (plotVertices[2] < finalLookup[i][4])) and ((plotVertices[1] > finalLookup[i][2]) and (plotVertices[3] < finalLookup[i][1])):
            isInTemp.append([i,finalLookup[i][0],finalLookup[i][1],finalLookup[i][2],finalLookup[i][3],finalLookup[i][4]])
        plotIdDict[records[j][0]]=[isInTemp]

########################################################################
#plot things
########################################################################

import matplotlib
import matplotlib.pyplot as plt

onePlot=plotIdDict['SJER1068'][0]

#create the figure
fig = plt.figure()
ax = fig.add_subplot(111)

for i in xrange(len(onePlot)):
    print(i)
    xWidth=(onePlot[i][5]-onePlot[i][4])
    yHeight=(onePlot[i][2]-onePlot[i][3])
    locals()["rect"+str(i)] = matplotlib.patches.Rectangle((onePlot[i][4],onePlot[i][3]), xWidth, yHeight, fill=None, edgecolor='red')
    ax.add_patch(locals()["rect"+str(i)])
    #ax.add_patch(matplotlib.patches.Rectangle((onePlot[i][4],onePlot[i][2]), xWidth, yHeight, edgecolor='violet'))

###################
#dummy test code...
recCen=[[100,400],[140,450],[150,500]]
plotcent=[170,620]
dis=[]
for q in xrange(3):
	dis.append([abs(plotcent[0]-recCen[q][0]),abs(plotcent[1]-recCen[q][1])])

#############################
#use this code to sort out the smallest values...
dis=[[20, 1], [30, 5], [20, 120]]
min(dis, key=lambda item: (item[0], item[1]))

dis.index(min(dis, key=lambda item: (item[0], item[1])))
#############################

#add plot boundary
#bbox saves 4 corners as follows [left X, Lower Y, right X, Upper Y ]
plotVertices=shapes[0].bbox
plotBoundary = matplotlib.patches.Rectangle((plotVertices[0],plotVertices[1]), 40, 40, edgecolor='blue', facecolor='white')
ax.add_patch(plotBoundary)

plt.xlim([250000, 265000])
plt.ylim([4104000, 4115000])
plt.show()

fig = plt.figure()
ax = fig.add_subplot(111)
rect1 = matplotlib.patches.Rectangle((0,0), 200, 800, fill=None, edgecolor='red')
rect2 = matplotlib.patches.Rectangle((100,150), 180, 750, fill=None, edgecolor='green')
rect3 = matplotlib.patches.Rectangle((50,100), 200, 800, fill=None, edgecolor='violet')
plot = matplotlib.patches.Rectangle((150,600), 40, 40, color='blue')

#circle1 = matplotlib.patches.Circle((-200,-250), radius=90, color='#EB70AA')
ax.add_patch(rect1)
ax.add_patch(rect2)
ax.add_patch(rect3)
ax.add_patch(plot)

#ax.add_patch(circle1)
plt.xlim([-100, 1000])
plt.ylim([-100, 1000])
plt.show()


import board
import busio
#### For the ada fruit libraries use sudo pip3 install adafruit-circuitpython-ads1x15
import adafruit_ads1x15.ads1115 as ADS
from adafruit_ads1x15.analog_in import AnalogIn
from time import sleep
import subprocess
import syslog
from datetime import datetime
import os

#################################################################################################
# Cron command to run this script every minute                                                  #
# */1 * * * * /usr/bin/python3 /scripts/ads1115/get_bat.py >/dev/null 2>&1                      #
#                                                                                #
# The code for interfacing with the ADS1115 came from the Adafruit example                      #
# located at: https://learn.adafruit.com/adafruit-4-channel-adc-breakouts/python-circuitpython  #
#################################################################################################

def get_battery():
    # Get the voltage of the battery by useing the ADS1115
    i2c = busio.I2C(board.SCL, board.SDA)
    ads = ADS.ADS1115(i2c)
    avg_bat = 0

    # Take three samples and average them
    for i in range(4):
        chan = AnalogIn(ads, ADS.P0)
        # Measuring with multimeter 2.043 was the correct multiplier for my splitter
        # this value should be updated for each build
        current_voltage = chan.voltage * 2.005
        avg_bat = avg_bat + current_voltage
    avg_bat = avg_bat/4

    # Return the average of the three battery samples
    return(avg_bat)

def os_announce(message):
    # Use wall and xmessage to announce any message passed to the function
    # to all logged in users.
    command = "/usr/bin/wall"
    try:
        subprocess.call([command, message])
    except Exception as e:
        print(e)
    # os.environ["DISPLAY"] = ':0.0'
    # os.environ["XAUTHORITY"] = '/home/pi/.Xauthority'
    # command = "xmessage"
    # try:
    #     subprocess.call([command, message])
    # except Exception as e:
    #     print(e)

def shutdown_system(message):
    # command = "shutdown"
    # arg1 = "-h"
    # arg2 = "-t 120"
    # subprocess.call([command, arg1, arg2, message])
    os.system('systemctl poweroff')

if __name__ == "__main__":
    current_bat = get_battery()
    current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    if current_bat <= 6.4:
        # If the battery voltage is critical send a shutdown command and then
        # use wall to send a message to all users finally log the voltage and
        # warning to syslog
        message = 'Voltage is Critial.  System will is shutting down. Current Voltage = ' + \
            str(current_bat)
        syslog.syslog("[Critical] Battery Voltage is: %s" % current_bat)
        os_announce(message)
        shutdown_system(message)
    elif current_bat < 7.0 and current_bat > 6.6:
        # If the battery voltage is low use wall to send a message to all users
        # then log the voltage and warning to syslog
        message = 'BATTERY IS LOW! Current Voltage = ' + str(current_bat)
        syslog.syslog("[Error] Battery Voltage is: %s" % current_bat)
        os_announce(message)
    else:
        # If the battery isn't critical log the voltage every 5 minutes
        minute = int(datetime.now().strftime('%M')) % 5
        if minute == 0:
            syslog.syslog("Battery Voltage is: %s" % current_bat)


import pandas as pd
from sklearn.datasets import load_iris

def load_and_save_iris_data():
    # 加载 IRIS 数据集
    iris = load_iris()

    # 创建 DataFrame 并设置列名
    iris_data = pd.DataFrame(iris.data, columns=['sepal_length', 'sepal_width', 'petal_length', 'petal_width'])
    iris_data['target'] = iris.target

    # 添加索引作为列名
    iris_data.columns.name = 'index'

    # 保存为csv文件
    iris_data.to_csv('../dataset/iris_modified.csv', index=False)

def load_and_save_cancer_data():
    data = pd.read_csv('../dataset/wdbc.csv')

    column_names = ['ID number','Diagnosis',
                    'Mean Radius', 'Mean Texture', 'Mean Perimeter','Mean Area', 'Mean Smoothness',
                    'Mean Compactness','Mean Concavity','Mean Concave points', 'Mean Symmetry', 'Mean Fractal dimension',
                    'Radius SE', 'Texture SE', 'Perimeter SE','Area SE', 'Smoothness SE',
                    'Compactness SE','Concavity SE','Concave points SE', 'Symmetry SE', 'Fractal dimension SE',
                    'Worst Radius', 'Worst Texture', 'Worst Perimeter','Worst Area', 'Worst Smoothness',
                    'Worst Compactness','Worst Concavity','Worst Concave points', 'Worst Symmetry', 'Worst Fractal dimension']

    data.columns = column_names
    data.columns.name = 'index'

    data.to_csv('../dataset/cancer_modified.csv', index=False)

def main():
    load_and_save_iris_data()
    load_and_save_cancer_data()

if __name__ == '__main__':
    main()


import os
import argparse

class Parser():
    """
    获取命令行参数
    """
    def __init__(self, description):
        self.parser = argparse.ArgumentParser(description=description)
        self.args = None
        self._parse()

    def _parse(self):
        """
        设置文件路径
        """
        self.parser.add_argument(
            '--path', type=str, default=None,
            help='md文件的路径')
        self.args = self.parser.parse_args()

def add_anchor_tags(filepath):
    with open(filepath, 'r', encoding='utf-8') as file:
        content = file.readlines()

    anchor = []
    updated_content = []
    F = 1
    S = 1
    T = 1
    for line in content:
        if '#####' in line.split(' '):
            anchor.append(f"        - [{line.split('#####')[-1].strip()}](#{str(F-1)+'_'+str(S-1)+'_'+str(T)})  \n")
            updated_content.append(f"\n")
            T += 1
        elif '####' in line.split(' '):
            anchor.append(f"    - [{line.split('####')[-1].strip()}](#{str(F-1)+'_'+str(S)})  \n")
            updated_content.append(f"\n")
            S += 1
            T = 1
        elif '###' in line.split(' '):
            anchor.append(f"- [{line.split('###')[-1].strip()}](#{str(F)})  \n")
            updated_content.append(f"\n")
            F += 1
            S = 1
            T = 1
        updated_content.append(line)
    anchor[-1] += '\n'
    updated_content = anchor + updated_content    #最终处理好的md文件内容

    dirpath, filename = filepath[:-filepath[::-1].index('\\')], filepath.split('\\')[-1]
    filename2 = filename.split('.')[0] + 'Updated.md'
    with open(os.path.join(dirpath,filename2), 'w', encoding='utf-8') as file:
        file.writelines(updated_content)
    print(f'已经保存到 {os.path.join(dirpath,filename2)}')

# 调用示例
if __name__ == '__main__':
    filename = Parser(None).args.path
    add_anchor_tags(filename)
# python .\add_anchor.py --path .\docs\about_Python\其他.md


"""RoomGeneratorFunction

Returns a unique ID for a chat room.

When doing this, it also:
 * Creates an SNS topic for posting messages to the room.
 * Sets the SNS topic's policy to allow subscription, publishing, and cleanup.
 * Sets up a CloudWatch log group for success / failure delivery notifications.
 * Sets the SNS topic to log success and failure content.
 * Creates a CloudWatch metric filter for the SNS message dwell time.

"""

from __future__ import print_function

import os
import json
import uuid
import time
import boto3
import zbase32
from apigateway_helpers.exception import APIGatewayException
from apigateway_helpers.headers import get_response_headers

room_duration_seconds = 7200 # 7200 seconds == Two hours

sns_client = boto3.client("sns")
sts_client = boto3.client("sts")
logs_client = boto3.client("logs")
sfn_client = boto3.client("stepfunctions")

def lambda_handler(event, context):
    print("Event: {}".format(json.dumps(event)))

    if "warming" in event and "{}".format(event["warming"]).lower() == "true":
        return {
            "message": "Warmed!"
        }

    room_log_event_processor_function_arn = os.environ["ROOM_LOG_EVENT_PROCESSOR_FUNCTION_ARN"]

    new_room_id = generate_new_room_id()

    new_topic_name = generate_room_sns_topic_name(new_room_id)

    sns_response = sns_client.create_topic(
        Name = new_topic_name
    )

    topic_arn = sns_response["TopicArn"]

    topic_attributes_to_set = [
        ("Policy", get_default_topic_policy(topic_arn)),
        ("SQSFailureFeedbackRoleArn", os.environ["SNS_FAILURE_FEEDBACK_ROLE"]),
        ("SQSSuccessFeedbackRoleArn", os.environ["SNS_SUCCESS_FEEDBACK_ROLE"])
    ]

    for each_topic_attribute_tuple in topic_attributes_to_set:
        sns_client.set_topic_attributes(
            TopicArn = topic_arn,
            AttributeName = each_topic_attribute_tuple[0],
            AttributeValue = each_topic_attribute_tuple[1]
        )

    sns_client.subscribe(
        TopicArn = topic_arn,
        Protocol = "lambda",
        Endpoint = room_log_event_processor_function_arn
    )

    message_object = {
        "identity-id": "SYSTEM",
        "author-name": "System Message",
        "message": "The room is now open.",
        "type": "ROOM_OPEN",
        "timestamp": int(time.time())
    }

    sns_client.publish(
        TopicArn = topic_arn,
        Message = json.dumps(message_object)
    )

    sns_log_group_name = get_sns_cloudwatch_log_group_name(event, new_room_id)

    logs_client.create_log_group(
        logGroupName = sns_log_group_name
    )

    logs_client.put_metric_filter(
        logGroupName = sns_log_group_name,
        filterName = "SNSRoomTopicDwellTime",
        filterPattern = "{ $.delivery.dwellTimeMs > 0 }",
        metricTransformations = [
            {
                "metricName": "DwellTimeMs",
                "metricNamespace": "WebChat-{}".format(event["requestContext"]["apiId"]),
                "metricValue": "$.delivery.dwellTimeMs"
            }
        ]
    )

    created_timestamp_seconds = int(time.time())

    room_config_object = {
        "created": created_timestamp_seconds,
        "duration": room_duration_seconds,
        "sns-topic-arn": topic_arn,
        "sns-log-group": sns_log_group_name
    }

    room_lifecycle_state_machine_arn = os.environ["ROOM_LIFECYCLE_STATE_MACHINE_ARN"]

    response = sfn_client.start_execution(
        stateMachineArn = room_lifecycle_state_machine_arn,
        name = new_room_id,
        input = json.dumps({
            "id": new_room_id,
            "config": room_config_object
        })
    )

    print("Room lifecycle state machine execution ARN: {}".format(response["executionArn"]))

    return {
        "id": new_room_id
    }

def generate_room_sns_topic_name(room_id):
    return "{}-{}".format(
        os.environ["PROJECT_GLOBAL_PREFIX"],
        room_id
    )

def generate_new_room_id():
    return zbase32.encode(uuid.uuid4().bytes).decode('utf-8') #zbase32.b2a(uuid.uuid4().bytes)

account_id = None
def get_own_account_id():
    global account_id

    if account_id is None:
        account_id = sts_client.get_caller_identity()["Account"]

    return account_id

def get_sns_cloudwatch_log_group_name(event, room_id):
    return "sns/{region}/{account_id}/{app_prefix}-{room_id}".format(
        region = os.environ["AWS_DEFAULT_REGION"],
        account_id = get_own_account_id(),
        app_prefix = os.environ["PROJECT_GLOBAL_PREFIX"],
        room_id = room_id
    )

def get_default_topic_policy(sns_topic_arn):
    return json.dumps({
        "Version": "2008-10-17",
        "Statement": [
            {
                "Sid": "AllowSubscriptionFromRoomSessionGenerator",
                "Effect": "Allow",
                "Principal": {
                    "AWS": os.environ["SUBSCRIBE_ROOM_TOPIC_ROLE"]
                },
                "Action": [
                    "sns:Subscribe",
                    "sns:Publish"
                ],
                "Resource": sns_topic_arn
            },
            {
                "Sid": "AllowPublishingByRoomMessagePoster",
                "Effect": "Allow",
                "Principal": {
                    "AWS": os.environ["PUBLISH_ROOM_TOPIC_ROLE"]
                },
                "Action": "sns:Publish",
                "Resource": sns_topic_arn
            },
            {
                "Sid": "AllowPublishingAndSubscribingBySelf",
                "Effect": "Allow",
                "Principal": {
                    "AWS": os.environ["OWN_FUNCTION_ROLE"]
                },
                "Action": [
                    "sns:Publish",
                    "sns:Subscribe"
                ],
                "Resource": sns_topic_arn
            },
            {
                "Sid": "AllowRoomLifecycleManagement",
                "Effect": "Allow",
                "Principal": {
                    "AWS": os.environ["ROOM_LIFECYCLE_FUNCTION_ROLE"]
                },
                "Action": "sns:SetTopicAttributes",
                "Resource": sns_topic_arn
            },
            {
                "Sid": "AllowCleanup",
                "Effect": "Allow",
                "Principal": {
                    "AWS": os.environ["DELETE_ROOM_TOPIC_ROLE"]
                },
                "Action": "sns:DeleteTopic",
                "Resource": sns_topic_arn
            }
        ]
    })

def proxy_lambda_handler(event, context):

    response_headers = get_response_headers(event, context)

    try:
        return_dict = lambda_handler(event, context)
    except APIGatewayException as e:
        return {
            "statusCode": e.http_status_code,
            "headers": response_headers,
            "body": json.dumps({
                "message": e.http_status_message
            })
        }

    return {
        "statusCode": 200,
        "headers": response_headers,
        "body": json.dumps(return_dict)
    }


# This file contains some utilities for pre-processing the images:
#  - background image:
#    = re-scaling
#  - source image:
#    = mask generating
#    = re-scaling

import cv2
import numpy as np

def rescale(in_fname: str, out_fname: str, new_size: tuple, domain_axis: int) -> None:
    ''' A utility function for rescaling the image, encapsulated from `cv2.resize`.
        @param in_fname: <str>, the input filename
        @param out_fname: <str>, the input filename
        @param new_size: <tuple(height, width)>, the new size (pixels) of the image
        @param domain_axis: For free rescaling, set to -1. For equal-ratio rescaling, set to 0/1.  \
            For example, if you want new_size depends on axis=0, set it to 0.  \
            Then axis1 will be automatically adjusted by axis0.
    '''
    assert( len(new_size) == 2 )
    img = cv2.imread(in_fname)
    if domain_axis == -1:
        out_img = cv2.resize(img, new_size)
    elif domain_axis == 0:
        fy = new_size[0] / img.shape[0]
        out_img = cv2.resize(img, None, fx=fy, fy=fy)
    elif domain_axis == 1:
        fx = new_size[1] / img.shape[1]
        out_img = cv2.resize(img, None, fx=fx, fy=fx)
    cv2.imwrite(out_fname, out_img)

def generate_mask(in_fname: str) -> None:
    ''' A utility function to generate a mask of a given image. '''

    def callback(event, x, y, flags, param):
        ''' Callback function of the window. '''
        if event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON:
            cv2.circle(mask, (x, y), 8, (255, 255, 255), -1)
            cv2.circle(img, (x, y), 8, (255, 255, 255), -1)
            # print(x, y)
            cv2.imshow('mask gen', img)
        # elif event == cv2.EVENT_LBUTTONUP:
        #     cv2.destroyWindow('mask gen')
        #     cv2.namedWindow('mask gen')
        #     cv2.setMouseCallback('mask gen',callback)

    img = cv2.imread(in_fname)
    h, w, _ = img.shape
    mask = np.zeros((h, w, 3), dtype=np.uint8)

    cv2.namedWindow('mask gen')
    cv2.setMouseCallback('mask gen',callback)
    cv2.imshow('mask gen', img)

    while(True):
        if cv2.waitKey(20)&0xFF==ord('s'):
            cv2.destroyAllWindows()
            cv2.imwrite(in_fname.split('.')[0] + '_mask.jpg', mask)
            break
        elif cv2.waitKey(20)&0xFF==ord('q'):
            cv2.destroyAllWindows()
            break

# USE samples:
# rescale('imgs/1_original_src1.jpg', 'imgs/1_src1.jpg', (100, 400), 1)
# generate_mask('imgs/1_src1.jpg')


import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

# 문제1
# simple3 파일을 읽어
# hx = wx + b
# w, b 값을 구하고 x가 5인 경우의 값을 예측하시오.

f = np.loadtxt("simple3.txt", dtype=np.int32, skiprows=1, delimiter=",")
print(f)

x = f[:, 0]
y = f[:, 1]

print(x)
print(y)

X = tf.placeholder(dtype=tf.float32)
Y = tf.constant(y, dtype=tf.float32)

# xaiver or he 알고리즘으로 적절한 초기값을 지정할 수 있다.
W = tf.Variable(1, dtype=tf.float32)
b = tf.Variable(1, dtype=tf.float32)

hx = W * X + b

cost = tf.reduce_mean(tf.square(hx - y))

optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1)
train = optimizer.minimize(cost)

sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)

for i in range(100):
    _train, _cost = sess.run([train, cost], feed_dict={X: x})
    print(i, _cost)
    plt.plot(i, _cost, "ro")

print("W : ", sess.run(W))
print("b : ", sess.run(b))

print("X가 5인경우 값 : ", sess.run(hx, feed_dict={X: 5}))

# 문제2
# 위의 결과로 그래프를 그리시오.
# x축, y축 (hx)
plt.show()

plt.plot(x, sess.run(hx, feed_dict={X: x}))
plt.show()

# 문제3
# y = (5x +2 ) ^ 2를 미분하시오
# 코딩이 아닌 도출과정을 적으시오.

# 풀이 ==> 2 * (5x + 2) * 5 (편미분)


import xbmc
import xbmcgui
import xbmcaddon
import json

##############################################################
#                                                            #
#                                                            #
#			from script.module.drmhelper                     #
#				ausieaddons                                  #
# 					by glennguy                              #
#                                                            #
##############################################################

def get_addon(wtyk="inputstream.rtmp"):
    """
    Check if inputstream is installed, attempt to install if not.
    Enable inpustream addon.
    """
    addon = None

    try:
        enabled_json = ('{"jsonrpc":"2.0","id":1,"method":'
                        '"Addons.GetAddonDetails","params":'
                        '{"addonid":"%s", '
                        '"properties": ["enabled"]}}'%wtyk)
        result = json.loads(xbmc.executeJSONRPC(enabled_json))
    except RuntimeError:
        return False

    if 'error' in result:  # not installed
        try:  # see if there's an installed repo that has it
            xbmc.executebuiltin('InstallAddon(%s)'%wtyk, True)
            addon = xbmcaddon.Addon('%s'%wtyk)
            return addon
        except RuntimeError:
            xbmcgui.Dialog().ok('%s not installed'%wtyk,
                                '%s not installed. This '
                                'addon now comes supplied with newer builds '
                                'of Kodi 18 for Windows/Mac/LibreELEC/OSMC, '%wtyk)
        return False

    else:  # installed but not enabled. let's enable it.
        if result['result']['addon'].get('enabled') is False:
            json_string = ('{"jsonrpc":"2.0","id":1,"method":'
                           '"Addons.SetAddonEnabled","params":'
                           '{"addonid":"%s",'
                           '"enabled":true}}'%wtyk)
            try:
                xbmc.executeJSONRPC(json_string)
            except RuntimeError:
                xbmcgui.Dialog().ok('Unable to enable %s'%wtyk,
                                    'Unable to enable %s, '
                                    'please try to enable manually '
                                    'and try again'%wtyk)
                return False
        addon = xbmcaddon.Addon('%s'%wtyk)

    return addon

def disable_addon(wtyk="inputstream.rtmp"):
	addon=None
	json_string = ('{"jsonrpc":"2.0","id":1,"method":'
				'"Addons.SetAddonEnabled","params":'
				'{"addonid":"%s",'
				'"enabled":false}}'%wtyk)
	try:
		xbmc.executeJSONRPC(json_string)
		#xbmcgui.Dialog().ok('Disabled','%s is disabled'%wtyk)
	except RuntimeError:
		xbmcgui.Dialog().ok('Unable to disable %s'%wtyk,
							'Unable to disable %s, '
							'please try to disable manually '
							'and try again'%wtyk)
		return False

	return addon


import PySimpleGUI as sg
from tkinter import *
from tkinter import simpledialog
from tkinter import messagebox
from PIL import ImageTk, Image,ImageFilter
import os
import math
import cv2
from os import listdir
from os.path import isfile, join
import numpy as np
from itertools import cycle
import json

def writeToJSONFile(path, fileName, data):
    filePathNameWExt =  path + '/' + fileName + '.json'
    with open(filePathNameWExt, 'w') as fp:
        json.dump(data, fp)

class GUI:
    def move(self,event):
        if event.char == "a":
            self.canvas.move(self.img_id, -10, 0)
        elif event.char == "d":
            self.canvas.move(self.img_id, 10, 0)
        elif event.char == "w":
            self.canvas.move(self.img_id, 0, -10)
        elif event.char == "s":
            self.canvas.move(self.img_id, 0, 10)

    def resetZoom(self):
        self.canvas_image = ImageTk.PhotoImage(self.curIt)
        self.moveIM = self.canvas.create_image(self.w/2, self.h/2-100, image=self.canvas_image, anchor="center")
        self.zoomed = False
        self.scale = 1
    def zoomOut(self):
        self.scale *= float(2)/3
        self.redraw(self.x, self.y)
    def zoomIn(self):
        self.scale *= 1.5
        self.redraw(self.x, self.y)

    def redraw(self, x=0, y=0):
        if self.img_id:
            self.canvas.delete(self.img_id)
        self.zX = x
        self.zY = y
        print(self.curIt.size)
        self.iw, self.ih = self.curIt.size
        size = int(self.iw * self.scale), int(self.ih * self.scale)
        self.initial_im = self.canvas_image
        self.canvas_image = ImageTk.PhotoImage(self.curIt.resize(size),Image.ANTIALIAS)
        print(size)
        self.canvas.delete(ALL)
        self.img_id = self.canvas.create_image(self.w/2, self.h/2-100, image=self.canvas_image, anchor = "center")
        self.zoomed = True
        self.canvas.old_coords = None

    def leftClick(self,event):
        self.x,self.y = event.x, event.y
        if self.canvas.old_coords:

            self.x1, self.y1 = self.canvas.old_coords
            self.canvas.create_line(self.x, self.y, self.x1, self.y1, width = 2)
            self.canvas.old_coords = None
            if self.x == self.x1:
                if self.y1 < self.y:
                    degree = 90
                else:
                    degree = 270
            elif self.y == self.y1:
                if self.x1 < self.x:
                    degree = 0
                else:
                    degree = 0
            else:
                slope = -(self.y1-self.y)/(self.x1-self.x)
                degree = math.degrees(math.atan(slope))
                degree = round(degree)
                if self.y < self.y1:
                    if degree < 0:
                        degree = 180 + degree
                else:
                    if degree < 0:
                        degree = 360 + degree
                    else:
                        degree = 180 + degree
            if degree == 360:
                degree = 0

            self.angle = str(degree)
            self.label.config(text=self.angle)
            print(degree)

        else:
            self.canvas.old_coords = self.x, self.y
            #self.button2Click()

    def buttonClick(self):

        if (self.angle == None):
            answer  = messagebox.askyesnocancel("Skip the Image","Any angle has not chosen yet, do you want to skip the image?")
            if answer == True:
                self.curName=next(self.iteratorName)
                if self.data[self.curName] == False:
                    self.canvas.delete(ALL)
                    self.curIt = next(self.iterator)
                    self.canvas_image = ImageTk.PhotoImage(self.curIt)
                    self.moveIM = self.canvas.create_image(self.w/2, self.h/2-100, image=self.canvas_image, anchor="center")
                    self.zoomed = False
                    self.scale = 1
                    self.angle = None
                else:
                    messagebox.showinfo("Quit","No Image Left")
                    self.window.destroy()
        else:
            self.f.write(self.curName +","+ self.angle + "\n")
            self.angle = None
            self.label.config(text=self.angle)
            self.data[self.curName] = True
            writeToJSONFile(self.direc,'file-name',self.data)
            self.curName=next(self.iteratorName)

            if self.data[self.curName] == False:
                self.canvas.delete(ALL)
                self.curIt = next(self.iterator)
                self.canvas_image = ImageTk.PhotoImage(self.curIt)
                self.moveIM = self.canvas.create_image(self.w/2, self.h/2-100, image=self.canvas_image, anchor="center")
                self.zoomed = False
                self.scale = 1

            else:
                 messagebox.showinfo("Quit","No Image Left")
                 self.window.destroy()

    def __init__(self):

        self.window = Tk()
        self.window.withdraw()
        self.direc = simpledialog.askstring("Directory","Please enter the directory",initialvalue="C:/Users/cagri/OneDrive/Desktop/Yedek/py/all/set")

        self.window.title("Angle Calculator")
        self.w, self.h = self.window.winfo_screenwidth(), self.window.winfo_screenheight()
        self.window.geometry("%dx%d+0+0" % (self.w, self.h-70))

        self.window.configure(background='grey')
        self.initial_im = None
        self.zX = None
        self.zY = None
        self.zoomed = False
        self.iw = None
        self.ih = None
        self.scale = 1
        self.img_id = None
        self.img = None
        self.x = None
        self.y = None
        self.x1 = None
        self.y1 = None
        self.images = []
        self._drag_data1 = {"x": 0, "y": 0, "item1": None}
        try:
            r = open(self.direc + "/" + 'Name-Angle.txt',mode='r')
            alltxt = r.read()
            r.close()
        except:
            alltxt = ""
        self.f = open(self.direc + "/" +'Name-Angle.txt', 'w')
        self.f.write(alltxt)
        dirs = os.listdir( self.direc )

        try:
            filePathNameWExt =  self.direc + '/' + 'file-name' + '.json'
            with open(filePathNameWExt, "r") as read_file:
                self.data = json.load(read_file)
        except:
            print("Not Found")
            self.data = {}

        print(self.data)
        # resize image
        names = []
        for file in dirs:
            #st = file.find(".jpg" ) is not -1) or (file.find(".JPG" ) is not -1) or (file.find(".bmp" ) is not -1) or (file.find(".BMP" ) is not -1)
            #st = (file.find(".bmp" ) is not -1) or (file.find(".BMP" ) is not -1)# or (file.find(".j" ) is not -1) or (file.find(".BMP" ) is not -1)
            if (file.find(".bmp" ) is not -1) or (file.find(".BMP" ) is not -1):
                file = file.replace(".bmp","")
                file = file.replace(".BMP","")

                if (file in self.data):
                    if (self.data[file] == False):
                        im = cv2.cvtColor(cv2.imread(self.direc+"/"+file+".bmp"), cv2.COLOR_BGR2RGB)
                        im = Image.fromarray(im)
                        names.append(file)
                        self.images.append(im)
                else:
                    im = cv2.imread(self.direc+"/"+file+".bmp")
                    im = Image.fromarray(im)
                    names.append(file)
                    self.images.append(im)
                    self.data[file] = False
            elif (file.find(".jpg" ) is not -1) or (file.find(".JPG" ) is not -1):
                file = file.replace(".jpg","")
                file = file.replace(".JPG","")
                print(self.direc+"/"+file+".jpg")
                if (file in self.data):
                    if (self.data[file] == False):
                        im = cv2.cvtColor(cv2.imread(self.direc+"/"+file+".jpg"), cv2.COLOR_BGR2RGB)
                        im = Image.fromarray(im)
                        names.append(file)
                        self.images.append(im)
                else:
                    #im = cv2.imread("1.jpg")
                    im = cv2.imread(self.direc+"/"+file+".jpg")
                    print(type(im))
                    im = Image.fromarray(im)
                    names.append(file)
                    self.images.append(im)
                    self.data[file] = False
        self.iterator = cycle(self.images)
        self.iteratorName = cycle(names)

        try:
            self.curName = next(self.iteratorName)
        except:
            messagebox.showinfo("Quit","No JPG Image Found")
            self.window.quit()
        self.curIt = next(self.iterator)
        self.img = ImageTk.PhotoImage(self.curIt)
        self.canvas_image = self.img
        writeToJSONFile(self.direc,'file-name',self.data)
        Button(text="Next Image",command=self.buttonClick).pack(side = "bottom", fill = "both", expand = "no")
        Button(text="Zoom In",command=self.zoomIn).pack(side = "bottom", fill = "both", expand = "no")
        Button(text="Zoom Out",command=self.zoomOut).pack(side = "bottom", fill = "both", expand = "no")
        Button(text="Reset Zoom",command=self.resetZoom).pack(side = "bottom", fill = "both", expand = "no")
        self.angle = None
        self.label = Label(text = self.angle)
        self.label.pack(side = "bottom", fill = "both", expand = "no")

        self.canvas = Canvas(width=self.w, height=self.h)
        self.canvas.pack(expand=YES, fill=BOTH)
        self.canvas.old_coords = None
        self.canvas_image = self.img
        self.moveIM = self.canvas.create_image(self.w/2, self.h/2-100, image=self.img, anchor="center")
        self.canvas.bind("<Button-1>",self.leftClick)
        self.window.bind("<Key>", self.move)
        self.move_flag = False
        self.mouse_xpos = self.w/2
        self.mouse_ypos = self.h/2-100
        self.window.deiconify()
        self.window.mainloop()
def main():
    GUI()
if __name__ == "__main__":
     main()


from django.contrib.auth.decorators import login_required
from django.db.models import F
from django.http import HttpResponseRedirect, JsonResponse

from django.template.loader import render_to_string
from django.views.generic import UpdateView
from baskets.models import Basket
from mainapp.mixin import UserDipatchMixin, BaseClassContextMixin
from mainapp.models import Product

class BasketAddCreateView(UpdateView, UserDipatchMixin, BaseClassContextMixin):
    model = Basket
    template_name = 'mainapp/products.html'
    title = 'GeekShop | Добавление товара в корзину!'

    def post(self, request, *args, **kwargs):
        if request.is_ajax:
            user_select = request.user
            product = Product.objects.get(id=self.kwargs['id'])
            baskets = Basket.objects.filter(user=user_select,
                                            product=product).select_related()
            if not baskets.exists():
                Basket.objects.create(user=user_select, product=product,
                                      quantity=1)
            else:
                basket = baskets.first()
                basket.quantity = F('quantity') + 1
                basket.save()
            return JsonResponse(
                {'result': 1, 'object': f'{self.kwargs["id"]}',
                 'data': render_to_string(
                     'mainapp/includes/card.html',
                     {'product': product, 'request': request,
                      'user': request.user})})

@login_required
def basket_edit(request, id_basket, quantity):
    if request.is_ajax():
        basket = Basket.objects.get(id=id_basket)
        basket.quantity = quantity
        basket.save()

        baskets = Basket.objects.filter(user=request.user).select_related()
        context = {'baskets': baskets}
        result = render_to_string('baskets/basket.html', context)
        return JsonResponse({'result': result})

@login_required
def basket_remove(request, basket_id):
    Basket.objects.get(id=basket_id).delete()
    return HttpResponseRedirect(request.META.get('HTTP_REFERER'))


from vnc_api.vnc_api import *

from cfgm_common import importutils

from neutron.api.v2 import attributes
from neutron.plugins.common import constants

from config_db import *

class LoadbalancerAgent(object):
    def __init__(self, svc_mon, vnc_lib, config_section):
        # Loadbalancer
        self._vnc_lib = vnc_lib
        self._svc_mon = svc_mon
        self._pool_driver = {}
        self._loadbalancer_driver = {}
        self._default_provider = self._load_driver(config_section)
    # end __init__

    def _load_driver(self, config_section):
        # TODO Load the driver fom config option
        self._loadbalancer_driver["opencontrail"] = importutils.import_object(
            "svc_monitor.services.loadbalancer.drivers.ha_proxy.driver.OpencontrailLoadbalancerDriver", self._svc_mon, self._vnc_lib, config_section)
        self._loadbalancer_driver["f5"] = importutils.import_object(
            "svc_monitor.services.loadbalancer.drivers.f5.f5_driver.OpencontrailF5LoadbalancerDriver", self._svc_mon, self._vnc_lib, config_section)
        return "opencontrail"
    # end _load_driver

    def _get_driver_for_provider(self, provider_name):
        return self._loadbalancer_driver[provider_name]
    # end _get_driver_for_provider

    def _get_driver_for_pool(self, pool_id, provider=None):
        if not pool_id:
            return self.drivers[self._default_provider]
        if pool_id in self._pool_driver:
            return self._pool_driver[pool_id]
        if not provider:
            pool = LoadbalancerPoolSM.get(pool_id)
            provider = pool.provider
        driver = self._get_driver_for_provider(provider)
        self._pool_driver[pool_id] = driver
        return driver
    # end _get_driver_for_pool

    # Loadbalancer
    def loadbalancer_pool_add(self, pool):
        p = self.loadbalancer_pool_get_reqdict(pool)
        driver = self._get_driver_for_pool(p['id'], p['provider'])
        try:
            if not pool.last_sent:
                driver.create_pool(p)
            #elif p != pool.last_sent:
            else:
                driver.update_pool(pool.last_sent, p)
        except Exception as ex:
            pass
        return p
    # end loadbalancer_pool_add

    def loadbalancer_member_add(self, member):
        m = self.loadbalancer_member_get_reqdict(member)
        driver = self._get_driver_for_pool(m['pool_id'])
        try:
            if not member.last_sent:
                driver.create_member(m)
            elif m != member.last_sent:
                driver.update_member(member.last_sent, m)
        except Exception as ex:
            pass
        return m
    # end loadbalancer_member_add

    def virtual_ip_add(self, vip):
        v = self.virtual_ip_get_reqdict(vip)
        driver = self._get_driver_for_pool(v['pool_id'])
        try:
            if not vip.last_sent:
                driver.create_vip(v)
            elif v != vip.last_sent:
                driver.update_vip(vip.last_sent, v)
        except Exception as ex:
            pass
        return v
    # end  virtual_ip_add

    def delete_virtual_ip(self, obj):
        v = obj.last_sent
        driver = self._get_driver_for_pool(v['pool_id'])
        try:
            driver.delete_vip(v)
        except Exception as ex:
            pass
    # end delete_virtual_ip

    def delete_loadbalancer_member(self, obj):
        m = obj.last_sent
        driver = self._get_driver_for_pool(m['pool_id'])
        try:
            driver.delete_member(m)
        except Exception as ex:
            pass
    # end delete_loadbalancer_member

    def delete_loadbalancer_pool(self, obj):
        p = obj.last_sent
        driver = self._get_driver_for_pool(p['id'])
        try:
            driver.delete_pool(p)
        except Exception as ex:
            pass
    # end delete_loadbalancer_pool

    def update_hm(self, obj):
        hm = self.hm_get_reqdict(obj)
        current_pools = hm['pools'] or []
        old_pools = []
        if obj.last_sent:
            old_pools = hm['pools'] or []

        set_current_pools = set()
        set_old_pools = set()
        for i in current_pools:
            set_current_pools.add(i['pool_id'])
        for i in old_pools:
            set_old_pools.add(i['pool_id'])
        update_pools = set_current_pools & set_old_pools
        delete_pools = set_old_pools - set_current_pools
        add_pools = set_current_pools - set_old_pools
        try:
            for pool in add_pools:
                driver = self._get_driver_for_pool(pool)
                driver.create_pool_health_monitor(hm, pool)
            for pool in delete_pools:
                driver = self._get_driver_for_pool(pool)
                driver.delete_pool_health_monitor(hm, pool)
            for pool in update_pools:
                driver = self._get_driver_for_pool(pool)
                driver.update_health_monitor(obj.last_sent,
                                         hm, pool)
        except Exception as ex:
            pass
    # end update_hm

    def _get_vip_pool_id(self, vip):
        pool_refs = vip.loadbalancer_pool
        if pool_refs is None:
            return None
        return pool_refs
    # end _get_vip_pool_id

    def _get_interface_params(self, vip, props):
        port_id = vip.virtual_machine_interface
        if port_id is None:
            return None

        if not props['address'] or props['address'] == attributes.ATTR_NOT_SPECIFIED:
            vmi = VirtualMachineInterfaceSM.get(port_id)
            ip_refs = vmi.instance_ip
            if ip_refs:
                iip = InstanceIpSM.get(ip_refs)
                props['address'] = iip.address

        return port_id
    # end _get_interface_params

    def virtual_ip_get_reqdict(self, vip):
        props = vip.params
        port_id = self._get_interface_params(vip, props)

        res = {'id': vip.uuid,
               'tenant_id': vip.parent_uuid.replace('-', ''),
               'name': vip.display_name,
               'description': self._get_object_description(vip),
               'subnet_id': props['subnet_id'],
               'address': props['address'],
               'port_id': port_id,
               'protocol_port': props['protocol_port'],
               'protocol': props['protocol'],
               'pool_id': self._get_vip_pool_id(vip),
               'session_persistence': None,
               'connection_limit': props['connection_limit'],
               'admin_state_up': props['admin_state'],
               'status': self._get_object_status(vip)}

        if props['persistence_type']:
            sp = {'type': props['persistence_type']}
            if props['persistence_type'] == 'APP_COOKIE':
                sp['cookie_name'] = props['persistence_cookie_name']
            res['session_persistence'] = sp

        return res;
    # end virtual_ip_get_reqdict

    _loadbalancer_health_type_mapping = {
        'admin_state': 'admin_state_up',
        'monitor_type': 'type',
        'delay': 'delay',
        'timeout': 'timeout',
        'max_retries': 'max_retries',
        'http_method': 'http_method',
        'url_path': 'url_path',
        'expected_codes': 'expected_codes'
    }

    def hm_get_reqdict(self, health_monitor):
        res = {'id': health_monitor.uuid,
               'tenant_id': health_monitor.parent_uuid.replace('-', ''),
               'status': self._get_object_status(health_monitor)}

        props = health_monitor.params
        for key, mapping in self._loadbalancer_health_type_mapping.iteritems():
            value = props[key]
            if value is not None:
                res[mapping] = value

        pool_ids = []
        pool_back_refs = health_monitor.loadbalancer_pools
        for pool_back_ref in pool_back_refs or []:
            pool_id = {}
            pool_id['pool_id'] = pool_back_ref
            pool_ids.append(pool_id)
        res['pools'] = pool_ids

        return res
    # end hm_get_reqdict

    _loadbalancer_member_type_mapping = {
        'admin_state': 'admin_state_up',
        'status': 'status',
        'protocol_port': 'protocol_port',
        'weight': 'weight',
        'address': 'address',
    }

    def loadbalancer_member_get_reqdict(self, member):
        res = {'id': member.uuid,
               'pool_id': member.loadbalancer_pool,
               'status': self._get_object_status(member)}

        pool = LoadbalancerPoolSM.get(member.loadbalancer_pool)
        res['tenant_id'] = pool.parent_uuid.replace('-', '')

        props = member.params
        for key, mapping in self._loadbalancer_member_type_mapping.iteritems():
            value = props[key]
            if value is not None:
                res[mapping] = value

        return res
    # end loadbalancer_member_get_reqdict

    _loadbalancer_pool_type_mapping = {
        'admin_state': 'admin_state_up',
        'protocol': 'protocol',
        'loadbalancer_method': 'lb_method',
        'subnet_id': 'subnet_id'
    }

    def _get_object_description(self, obj):
        id_perms = obj.id_perms
        if id_perms is None:
            return None
        return id_perms['description']
    # end _get_object_description

    def _get_object_status(self, obj):
        id_perms = obj.id_perms
        if id_perms and id_perms['enable']:
            return constants.ACTIVE
        return constants.PENDING_DELETE
    # end _get_object_status

    def loadbalancer_pool_get_reqdict(self, pool):
        res = {
            'id': pool.uuid,
            'tenant_id': pool.parent_uuid.replace('-', ''),
            'name': pool.display_name,
            'description': self._get_object_description(pool),
            'status': self._get_object_status(pool),
        }

        props = pool.params
        for key, mapping in self._loadbalancer_pool_type_mapping.iteritems():
            value = props[key]
            if value is not None:
                res[mapping] = value

        # provider
        res['provider'] = pool.provider

        # vip_id
        res['vip_id'] = None
        vip_refs = pool.virtual_ip
        if vip_refs is not None:
            res['vip_id'] = vip_refs

        # members
        res['members'] = list(pool.members)

        # health_monitors
        res['health_monitors'] = list(pool.loadbalancer_healthmonitors)

        # TODO: health_monitor_status
        res['health_monitors_status'] = []
        return res
    # end loadbalancer_pool_get_reqdict


from flask import render_template, copy_current_request_context
from flask import appcontext_tearing_down
from app import app, socketio
from . import photobox

@app.route('/')
@app.route('/index')
def index():
    photobox.start()
    return render_template('index.html')

@app.route('/button')
def capture_button():
    photobox.start()
    return render_template('index.html', show_button=True)

@socketio.on('capture', namespace='/test')
def capture_image():
    photobox.capture_photo()

@socketio.on('connect', namespace='/test')
def test_connect():
    started = photobox.start()
    if not started:
        photobox.send_initial_photo_count()


# -*- coding: utf-8 -*-
from sympy import isprime, prime, factorial

def euclid(a, b):
    """ Euclidean Algorithm."""
    a, b = b, a%b
    return a if not b else euclid(a, b)

def lcm(a, b):
    """ Least common multiple."""
    return (a * b) / (euclid(a, b))

def inverse(a, b, both = False):
    """ Multiplicative inverse of 'a' in mod 'b'.
        both = True gives the coefficients 'A' and 'B' of
        the equation A*x + B*y = gcd(x,y)"""
    x = [1, 0]
    y = [0, 1]
    q = a / b
    a, b = b, a % a
    while r[1]:
        x[0], x[1] = x[1], x[0] - q * x[1]
        y[0], y[1] = y[1], y[0] - q * y[1]
        q = a / b
        a, b = b, a % a
    if both:
        return (x[-1], y[-1])
    else:
        return x[-1] % b if a == 1 else None

def primefact(number):
    """ Prime factorization of 'number'.
        Returns a list of 2-tuples in which the first
        element is the prime factor and the second is the
        number of times that prime appears.  For example,
        [(2,1), (5,3)] corresponds to  2^1 * 5^3 = 250
        ( 2**1 * 5**3 in Python syntax )."""

    if isprime(number) or number == 1:
        return [(number, 1)]
    else:
        factors = []
        counts = []
        for primenum in (prime(n) for n in xrange(1, number)):
            if number == 1:
                break
            if not number % primenum:
                factors.append(primenum)
                counts.append(1)
                number = number // primenum
                while not (number % primenum):
                    counts[-1] += 1
                    number = number // primenum
        return zip(factors, counts)

def encrypt_general(message, encrypter, modulo = 26):
    return

def encrypt(message, a, b):
    """ Encrypts a message with formula y = a * x + b.
        Input may be either a string message or a list of indices 0-25."""
    alpha = [chr(char) for char in range(ord('a'), ord('z'))]
    if isinstance(message, str):
        offset = 65 if ord(message[0]) <=90 else 97
        encrypted = [(a * (ord(char) - offset) + b) % 26 for char in message]
    else:
        encrypted = [(a * char + b) % 26 for char in message]
    return "".join([chr(char + 65) for char in encrypted]), encrypted

def decrypt(message, a, b):
    """ Decrypts a message encrypted with formula y = a * x + b.
        Input may be either a string message or a list of indices 0-25."""

    if isinstance(message, str):
        offset = 65 if ord(message[0]) <=90 else 97
        message = [(ord(char) - offset) % 26 for char in message]
    a = inverse(a, 26)
    b = 26 - b
    decrypted = [(a * (char + b)) % 26 for char in message]
    return "".join([chr(char+65) for char in decrypted]), decrypted

def cartesian(*sets):
    """ Returns the cartesian product of the argument sets.  This can get very big."""
    def product(s1, s2):
        return set([(el1, el2) for el1 in s1 for el2 in s2])
    def merge(s1, s2):
        return set(tuple(list(el1) + [el2]) for el1 in s1 for el2 in s2)
    master = product(sets[0], sets[1])
    for s in sets[2:]:
        master = merge(master, s)
    return master

def powerset(s):
    """ Returns the powerset of a set.  Subsets will be instances of
        the 'frozenset' type.

        May also call as 'pset(s)'.

        This is the optimal option as it is far faster than the others
        for larger sets and correctly computes powersets of powersets.
        (ie: it handles sets containing sets correctly.)

        NOTE:  This will hog up your RAM if you use it to compute
               the power set of the power set of a set larger than 4 elements.
               I used all 32 gigs of ram trying pset(pset({1,2,3,4,5})).
               Thats 4294967296 elements, and each element eats up a lot of
               memory!

        This implementation is recursive."""
    def iterate(s, newSet = None):
        if newSet is None:
            newSet = set()
            s = {item for item in s}
        thisItem = frozenset([s.pop()])
        newSet.add(thisItem)
        for item in set(newSet):
            newSet.add(frozenset.union(thisItem, item))
        if s:
            return iterate(s, newSet)
        else:
            newSet.add(frozenset())
            return newSet

    return iterate(s)
pset = powerset

def subsets(s, cardinality):
    """ Returns a set of subsets with the specified cardinality.
        The subsets will be selected from input set 's'.

        Implemented poorly at the moment, but it works."""
    return {item for item in pset(s) if (len(item) == cardinality )}

def totient(num):
    """ Returns the totient of num."""
    if isprime(num):
        return num - 1
    else:
        return sum((1 for n in xrange(1, num) if euclid(num, n) == 1))

def powerset_old(s):
    """ Returns the powerset of a set.  Subsets will be instances of
        the 'frozenset' type. Broken for sets containing sets. ¯\_(ツ)_/¯"""
    sets = set([frozenset([item]) for item in s])
    lengthstart = 0
    while len(sets) != lengthstart:
        lengthstart = len(sets)
        sets = set.union(sets, set([frozenset.union(s1, s2)
                                    for s1 in sets for s2 in sets]))
    return set([frozenset(subset) for subset in sets] + [frozenset()])

def powerset_alt(s):
    """ Much slower way of getting the powerset."""
    tuples = cartesian(*[s for _ in range(len(s))])
    return set([frozenset(item) for item in tuples] + [frozenset()])

def breakRSA(e, n, message = None):
    """ Breaks a 'nice' RSA encryption with public key '(e, n)'."""
    (p, _), (q, _)  = primefact(n)
    tot = (p - 1) * (q - 1)
    d = inverse(e, tot, both = False)
    if message:
        return [num ** d % n for num in message]
    else:
        return d

def permute(n, r):
    """ Permutations of 'r' subitems in a set of 'n' items.
        May also call as 'permutations(n, r)'"""
    return factorial(n)/factorial(n - r)
permutations = permute

def choose(n, r):
    """ Combinations of 'r' subitems in a set of 'n' items.
        May also call as 'combinations(n, r)'"""
    return permute(n, r) / factorial(r)
combinations = choose

def recursive_choose(n, r):
    """ Recursive implementation of choose.  For fun."""
    if n == r:
        return 1
    elif r == 1 or n - r == 1:
        return n
    else:
        return choose_recursive(n-1, r) + choose_recursive(n-1, r - 1)

def binom(num, xcoeff = 1, ycoeff = 1):
    """ Coefficients of the resultant expansion of (xcoeff * x + ycoeff * y)^(num)."""
    return [choose(num, n) * xcoeff ** (num - n) * ycoeff**n for n in range(num+1)]

def pascal(row, index = None, allRows = False):
    """ Returns the requested row of pascals triangle.
        index:      Returns only the item at position 'index' within the row.
        allRows:    Call with 'allRows = True' to show every row up to and including
                    the requested row.  Priority given to 'index' over 'allRows'. """

    if index is not None:
        return choose(row, index)
    elif allRows:
        return [choose(row, n) for n in range(row+1)]
    else:
        return binom(row)

def pigeon(bins, pigeons):
    """ Pigeon hole principle with 'n' boxes needing
        'pigeons' items to fill them.  Gives the 'smallest maximum'
        that a bin/box must hold no matter how the 'pigeons' are arranged."""
    return pigeons // bins + bool(pigeons % bins)

def ballbins(balls, bins, withholding= False, minimum = 0):
    """ Returns the number of possible ways to arrange a given number of 'balls'
        into a given number of 'bins'.

        withholding: set this to true if some number of balls may be withheld
                     from the bins.
        minimum:     the minimum number of balls that must be contained within
                     each bin."""
    if withholding:
        if balls > bins:
            return sum([choose(bins + n - 1 - minimum * bins, balls - minimum * bins)
                        for n in range(balls+1)])
        else:
            return sum([choose(bins + n - 1, bins - 1)
                        for n in range(balls+1)])
    else:
        if balls > bins:
            return choose(bins + balls - 1 - minimum * bins, balls - minimum * bins)
        else:
            return choose(bins + balls - 1, bins - 1 )

def organize(seq):
    f = factorial(sum(seq))
    return f/(reduce(lambda x, y: x * y, [factorial(n) for n in seq]))

if __name__ == "__main__":
    pass


import datetime
from Classes.Interface import LetterResult
from Wordle.WordList import LIST_OF_ANSWERS

def getHongKongDate():
    return (datetime.datetime.utcnow() + datetime.timedelta(hours=8)).date()

def getCorrectGuessOfDay() -> str:
    today = getHongKongDate()
    index = getDateOffset(today)
    return getGuessFromOffset(index)

def getDateOffset(date: datetime.date) -> int:
    start_day = datetime.date(2021, 6, 19)
    return (date - start_day).days

def getGuessFromOffset(offset: int) -> str:
    return LIST_OF_ANSWERS[offset % len(LIST_OF_ANSWERS)]

class Validator:
    def __init__(self, word: str = None) -> None:
        if(word == None):
            word = getCorrectGuessOfDay()

        self.answer = word.lower()

    def isValidAnswer(word: str | None) -> bool:
        return word == None or (len(word) == 5 and word.lower() in LIST_OF_ANSWERS)

    def validateGuess(self, guessStr: str) -> str:
        result = ['_'] * 5
        copyOfAnswer = [char for char in self.answer]
        guess = [char for char in guessStr]

        # First we check for correct word in correct position
        for i in range(5):
            if copyOfAnswer[i] == guess[i]:
                # If it is correct and in correct position, we change it to '*'
                result[i] = '1'
                copyOfAnswer[i] = '*'
                guess[i] = '*'

        # Next, we look for partials
        for i in range(5):
            if guess[i] == '*' or guess[i] not in copyOfAnswer:
                # We have already marked this as correct so do not recheck
                continue
            actualPosition = copyOfAnswer.index(guess[i])
            copyOfAnswer[actualPosition] = '*'
            result[i] = '0'

        return ''.join(result)

    def parseGuessResult(word: str, result: str) -> dict[str, LetterResult]:
        resultMap = {}
        for i in range(len(word)):
            letter = word[i]
            res = result[i]

            if letter in resultMap:
                existingResult : LetterResult = resultMap[letter]
                if res == "1":
                    if existingResult.status == "CORRECT":
                        existingResult.correctPositions.append(i)
                    elif existingResult.status == "PARTIAL" or existingResult.status == "MULTI_INSTANCE":
                        existingResult.status = "MULTI_INSTANCE"
                        existingResult.correctPositions.append(i)
                    else:
                        resultMap[letter] = LetterResult.newCorrectResult(i)
                        existingResult = resultMap[letter]
                        existingResult.incorrectPositions = [j for j in range(5)]
                        existingResult.incorrectPositions.remove(i)
                elif res == "0":
                    if existingResult.status == "CORRECT":
                        existingResult.status = "MULTI_INSTANCE"
                        existingResult.incorrectPositions.append(i)
                    elif existingResult.status == "PARTIAL" or existingResult.status == "MULTI_INSTANCE":
                        existingResult.incorrectPositions.append(i)
                    else:
                        print("Encountered issue where incorrect before partial")
                        raise Exception("INCORRECT BEFORE PARTIAL")
                else:
                    if existingResult.status == "CORRECT":
                        existingResult.incorrectPositions = list(
                                filter(lambda num: num not in existingResult.correctPositions, [j for j in range(5)])
                            )
                    elif existingResult.status == "PARTIAL" or existingResult.status == "MULTI_INSTANCE":
                        existingResult.incorrectPositions.append(i)
                continue

            if res == "1":
                resultMap[letter] = LetterResult.newCorrectResult(i)
            elif res == "0":
                resultMap[letter] = LetterResult.newPartialResult(i)
            else:
                resultMap[letter] = LetterResult.newIncorrectResult()
        return resultMap


import warnings
warnings.filterwarnings('ignore')
import gym
import sys
sys.path.insert(0, './scripts/')
from simulation.agents import RLAgent

params = {
    'policy_frequency':     0.25,
    'simulation_frequency': 15,
    'save_history':         False,
    'offscreen_rendering':  False,
    'state_as_array':       True,
    'amplitude':            10000
}
env = gym.make('highway-v0', **params)
env.reset()

#%%
agent = RLAgent(env)
agent.load_model('/Users/rossgreen/PycharmProjects/simulation/scripts/models/dqn_params.h5f')

#%%
print(env.get_state())

#%%
agent.dqn.forward(env.get_state())

#%%
agent.dqn.forward()

#agent.test(nb_episodes=1, visualize=True, load_weights=True)


# THIS SCRIPT WILL ALLOW HANDS-FREE CONTROL OF OUR VOLUME

# IMPORT MOUSE CONTROLS
from pynput.mouse import Button, Controller

# IMPORT SCREEN RESOLUTION SETTINGS
import tkinter

# IMPORT BASE DEPENDENCIES
import cv2 as cv2
import time
import numpy as np
import PoseTrackUpdated as PT

# cam settings
w, h = 640, 480

cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
cap.set(3, w)
cap.set(4, h)

ptime, ctime = 0, 0
detector = PT.pose_detector(detection_confidence=0.7, max_hands=1)

# INITIALIZE MOUSE INPUT
mouse = Controller()

# INITIALIZE SCREEN SPECIFICATIONS
root = tkinter.Tk()
root.withdraw()
WIDTH, HEIGHT = root.winfo_screenwidth(), root.winfo_screenheight()

# INITIALIZE BOUNDING BOX AREA
area_bb = 0

while cap.isOpened():
    ret, frame = cap.read()
    frame_flip = cv2.flip(frame, 1)
    img = detector.find_hands(frame_flip)
    lmark_li, bounding_box = detector.find_position(img)
    flag_set_vol = False
    if lmark_li:
        # print(lmark_li[5], lmark_li[8])

        # FILTER HAND CONTROL SO THAT WE CAN MAINTAIN CONSISTENCY IN VOLUME OUTPUT
        # find area of bounding box
        area_bb = (bounding_box[2] - bounding_box[0])*(bounding_box[3] - bounding_box[1])//100
        print('The bounding box area is:', area_bb)
        if area_bb < 900 and area_bb > 0:
            print('Valid Range')

            # TRACK CURSOR: GET COORDINATES OF LANDMARK OF CHOICE TO USE AS OUR CURSOR
            # here: we are trying the thumb as a cursor so that we can possibly use index and middle finger
            # as left and right click
            # OUR CURSOR POSITION THROUGH THE CAMERA
            cursor_x, cursor_y = lmark_li[4][1], lmark_li[4][2]
            print(cursor_x, cursor_y)

            # interpolate the cursor position according to the size of our webcam window into
            # the total resolution of our screen (this will require some testing)
            # OUR PROJECTED CURSOR POSITION ON THE ACTUAL DISPLAY
            cursor_position_x = np.interp(cursor_x, [60, 400], [0, WIDTH])
            cursor_position_y = np.interp(cursor_y, [130, 300], [0, HEIGHT])
            # print(cursor_position_x, cursor_position_y)

            # adjust coordinates of the cursor according to the interpolated cursor position
            # adjust variable to make movement of mouse smoother
            mouse_smoothness = 8
            cursor_position_x, cursor_position_y = mouse_smoothness*int(cursor_position_x/mouse_smoothness), mouse_smoothness*int(cursor_position_y/mouse_smoothness)

            mouse.position = (cursor_position_x, cursor_position_y)

            # print(mouse.position)
            # # track which fingers are up or down
            fingers = detector.fingers_up()
            print(fingers)
            # CLICK CURSOR: IMPLEMENT RIGHT CLICK AND LEFT CLICK
            if fingers[1] == 0 and fingers[0] != 0:
                # this is the index finger action for left click, release once finger goes back up
                mouse.press(Button.left)
                mouse.release(Button.left)
            if fingers[2] == 0 and fingers[1] != 0:
                # this is the middle finger action for right click, release once finger goes back up
                mouse.press(Button.right)
                mouse.release(Button.right)

            # IMPLEMENT SCROLLING if both right click and left click fingers are down
            if fingers[1] == 0 and fingers[2] == 0 and fingers[3] == 0 and fingers[4] == 0:
                mouse.scroll(0, -1)
            if fingers[1] == 0 and fingers[1] == 0 and fingers[3] == 0 and fingers[4] == 1:
                mouse.scroll(0, 1)
        else:
            print('Out of Range: please take your hand further away')

    ctime = time.time()
    fps = 1 / (ctime - ptime)
    ptime = ctime

    # img_final = cv2.flip(frame, 1)
    cv2.putText(img, f'FPS: {int(fps)}', (10, 70), cv2.FONT_HERSHEY_PLAIN,
                3, (255, 0, 255), 2)

    cv2.imshow('Frame', img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()


import pyautogui
from PIL import Image,ImageGrab
import time
def hit(key):
    pyautogui.keyDown(key)
    return
# def takescreenshot():
    # image=ImageGrab.grab()

    # return image
def iscollide(data):
    for i in range(350,430):
        for j in range(540,560):
            if data[i,j]<100:
                hit("down")
                time.sleep(0.2)
                hit("up")
                return
    for i in range(470,500):
        for j in range(620,680):
            if data[i ,j]<100:
                hit("up")
                return

    return False

if __name__ == '__main__':
    print("starting dino game")
    # takescreenshot()
    time.sleep(3)
    while True:
        imag=ImageGrab.grab().convert('L')
        data=imag.load()
        iscollide(data)

        # for i in range(350,430):
        #     for j in range(540,560):
        #         data[i ,j]=1
        # for i in range(470,500):
        #     for j in range(620,680):
        #      data[i,j]=1

        # imag.show()
        # break


# coding: utf-8

"""
    Farsava API

    Farsava API. Speech Recognition and Text to Speech by applying powerful deep neural network models.  # noqa: E501

    OpenAPI spec version: 1.0.5
    Contact: amir@amerandish.com
    Generated by: https://openapi-generator.tech
"""

import pprint
import re  # noqa: F401

import six

class RecognitionAudioURI(object):
    """NOTE: This class is auto generated by OpenAPI Generator.
    Ref: https://openapi-generator.tech

    Do not edit the class manually.
    """

    """
    Attributes:
      openapi_types (dict): The key is attribute name
                            and the value is attribute type.
      attribute_map (dict): The key is attribute name
                            and the value is json key in definition.
    """
    openapi_types = {
        'uri': 'str'
    }

    attribute_map = {
        'uri': 'uri'
    }

    def __init__(self, uri=None):  # noqa: E501
        """RecognitionAudioURI - a model defined in OpenAPI"""  # noqa: E501

        self._uri = None
        self.discriminator = None

        self.uri = uri

    @property
    def uri(self):
        """Gets the uri of this RecognitionAudioURI.  # noqa: E501

        URI that points to a file that contains audio data bytes as specified in RecognitionConfig. The file must not be compressed (for example, gzip).   # noqa: E501

        :return: The uri of this RecognitionAudioURI.  # noqa: E501
        :rtype: str
        """
        return self._uri

    @uri.setter
    def uri(self, uri):
        """Sets the uri of this RecognitionAudioURI.

        URI that points to a file that contains audio data bytes as specified in RecognitionConfig. The file must not be compressed (for example, gzip).   # noqa: E501

        :param uri: The uri of this RecognitionAudioURI.  # noqa: E501
        :type: str
        """
        if uri is None:
            raise ValueError("Invalid value for `uri`, must not be `None`")  # noqa: E501

        self._uri = uri

    def to_dict(self):
        """Returns the model properties as a dict"""
        result = {}

        for attr, _ in six.iteritems(self.openapi_types):
            value = getattr(self, attr)
            if isinstance(value, list):
                result[attr] = list(map(
                    lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
                    value
                ))
            elif hasattr(value, "to_dict"):
                result[attr] = value.to_dict()
            elif isinstance(value, dict):
                result[attr] = dict(map(
                    lambda item: (item[0], item[1].to_dict())
                    if hasattr(item[1], "to_dict") else item,
                    value.items()
                ))
            else:
                result[attr] = value

        return result

    def to_str(self):
        """Returns the string representation of the model"""
        return pprint.pformat(self.to_dict())

    def __repr__(self):
        """For `print` and `pprint`"""
        return self.to_str()

    def __eq__(self, other):
        """Returns true if both objects are equal"""
        if not isinstance(other, RecognitionAudioURI):
            return False

        return self.__dict__ == other.__dict__

    def __ne__(self, other):
        """Returns true if both objects are not equal"""
        return not self == other