# Importing liabraries and DataReader
import pandas as pd
import pandas_datareader.data as web
import matplotlib.pyplot as plt
import datetime
from datetime import date

def stockchart():
	# Setting time range
	start = date(2016,1,1)
	end = date.today()
	stock_price = web.DataReader("TWTR", "yahoo", start, end)
	# stock_price.tail(5)
	stock_price["MA"] = stock_price["Adj Close"].rolling(window=10).mean()
	# we create grids
	price_fig = plt.subplot2grid((6,1),(0,0), rowspan=5, colspan=1)
	volume_fig = plt.subplot2grid((6,1),(5,0), rowspan=1, colspan=1, sharex=price_fig)
	price_fig.plot(stock_price.index, stock_price['Adj Close'])
	price_fig.plot(stock_price.index, stock_price['MA'])
	volume_fig.bar(stock_price.index, stock_price['Volume'])

	plt.show()

stockchart()


"""
******************************************************************************
* Purpose:  Prime Factors of given number.
*
* @author:  Pushkar Ishware
* @version: 3.7
* @since:   21-12-2018
*
******************************************************************************
"""

from Utilities import utilities
from Utilities.utilities import util

u = util()

def PrimeFactor():
    try:
        Number = int(input("Enter Number to calculate Prime factors:"))

        u.PrimeFactors(Number)

    except ValueError:
        print("Enter INT type input")

if __name__ == "__main__":
    PrimeFactor()


# -*- coding: utf-8 -*-
import requests
import re
import os
from bs4 import BeautifulSoup
#from imgurpython import ImgurClient
from argparse import ArgumentParser

def movie():
    target_url = 'http://www.atmovies.com.tw/movie/next/0/'
    print('Start parsing movie ...')
    rs = requests.session()
    res = rs.get(target_url, verify=False)
    res.encoding = 'utf-8'
    soup = BeautifulSoup(res.text, 'html.parser')
    content = ""
    for index, data in enumerate(soup.select('ul.filmNextListAll a')):
        if index == 5:
            return content
        title = data.text.replace('\t', '').replace('\r', '')
        link = "http://www.atmovies.com.tw" + data['href']
        content += '{}\n{}\n'.format(title, link)
    return content


#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Created by Ross on 2020/3/11

import argparse
import os
import pickle

import pandas as pd
import torch
import tqdm
from torch.utils.data.dataloader import DataLoader
from transformers.optimization import AdamW
from sklearn.metrics import roc_auc_score

import metrics
from config import Config, BertConfig
from data_utils import OOSDataset
from logger import Logger
from metrics import plot_confusion_matrix
from model.bilstm import BertBiLSTM
from processor.oos_processor import OOSProcessor
from processor.smp_processor import SMPProcessor
from utils import check_manual_seed, save_model, load_model, output_cases, EarlyStopping
from utils.visualization import scatter_plot, my_plot_roc, plot_train_test
from utils.tool import ErrorRateAt95Recall, save_result, save_feature

freeze_data = dict()
SEED = 123
gross_result = {}

if torch.cuda.is_available():
    device = 'cuda:0'
    FloatTensor = torch.cuda.FloatTensor
    LongTensor = torch.cuda.LongTensor
else:
    device = 'cpu'
    FloatTensor = torch.FloatTensor
    LongTensor = torch.LongTensor

def check_args(args):
    """to check if the args is ok"""
    if not (args.do_train or args.do_eval or args.do_test):
        raise argparse.ArgumentError('You should pass at least one argument for --do_train or --do_eval or --do_test')
    if args.gradient_accumulation_steps < 1 or args.train_batch_size % args.gradient_accumulation_steps != 0:
        raise argparse.ArgumentError('Gradient_accumulation_steps should >=1 and train_batch_size%gradient_accumulation_steps == 0')

def main(args):
    logger.info('Checking...')
    SEED = args.seed
    check_manual_seed(SEED)
    check_args(args)
    gross_result['seed'] = args.seed

    logger.info('Loading config...')
    bert_config = BertConfig('config/bert.ini')
    bert_config = bert_config(args.bert_type)

    # for oos-eval dataset
    data_config = Config('config/data.ini')
    data_config = data_config(args.dataset)

    # Prepare data processor
    data_path = os.path.join(data_config['DataDir'], data_config[args.data_file])  # 把目录和文件名合成一个路径
    label_path = data_path.replace('.json', '.label')

    if args.dataset == 'oos-eval':
        processor = OOSProcessor(bert_config, maxlen=32)
    elif args.dataset == 'smp':
        processor = SMPProcessor(bert_config, maxlen=32)
    else:
        raise ValueError('The dataset {} is not supported.'.format(args.dataset))

    processor.load_label(label_path)  # Adding label_to_id and id_to_label ot processor.

    n_class = len(processor.id_to_label)
    config = vars(args)  # 返回参数字典
    config['model_save_path'] = os.path.join(args.output_dir, 'save', 'bert.pt')
    config['n_class'] = n_class

    logger.info('config:')
    logger.info(config)

    model = BertBiLSTM(bert_config, n_class)  # Bert encoder
    if args.fine_tune:
        model.unfreeze_bert_encoder()
    else:
        model.freeze_bert_encoder()
    model.to(device)

    global_step = 0

    def train(train_dataset, dev_dataset):
        train_dataloader = DataLoader(train_dataset, batch_size=args.train_batch_size // args.gradient_accumulation_steps, shuffle=True,
                                      num_workers=2)

        nonlocal global_step
        n_sample = len(train_dataloader)
        early_stopping = EarlyStopping(args.patience, logger=logger)
        # Loss function
        classified_loss = torch.nn.CrossEntropyLoss().to(device)

        # Optimizers
        optimizer = AdamW(model.parameters(), args.lr)

        train_loss = []
        if dev_dataset:
            valid_loss = []
            valid_ind_class_acc = []
        iteration = 0
        for i in range(args.n_epoch):

            model.train()

            total_loss = 0
            for sample in tqdm.tqdm(train_dataloader):
                sample = (i.to(device) for i in sample)
                token, mask, type_ids, y = sample
                batch = len(token)

                logits = model(token, mask, type_ids)
                loss = classified_loss(logits, y.long())
                total_loss += loss.item()
                loss = loss / args.gradient_accumulation_steps
                loss.backward()
                # bp and update parameters
                if (global_step + 1) % args.gradient_accumulation_steps == 0:
                    optimizer.step()
                    optimizer.zero_grad()
                    global_step += 1

            logger.info('[Epoch {}] Train: train_loss: {}'.format(i, total_loss / n_sample))
            logger.info('-' * 30)

            train_loss.append(total_loss / n_sample)
            iteration += 1

            if dev_dataset:
                logger.info('#################### eval result at step {} ####################'.format(global_step))
                eval_result = eval(dev_dataset)

                valid_loss.append(eval_result['loss'])
                valid_ind_class_acc.append(eval_result['ind_class_acc'])

                # 1 表示要保存模型
                # 0 表示不需要保存模型
                # -1 表示不需要模型，且超过了patience，需要early stop
                signal = early_stopping(eval_result['accuracy'])
                if signal == -1:
                    break
                elif signal == 0:
                    pass
                elif signal == 1:
                    save_model(model, path=config['model_save_path'], model_name='bert')

                logger.info(eval_result)

        from utils.visualization import draw_curve
        draw_curve(train_loss, iteration, 'train_loss', args.output_dir)
        if dev_dataset:
            draw_curve(valid_loss, iteration, 'valid_loss', args.output_dir)
            draw_curve(valid_ind_class_acc, iteration, 'valid_ind_class_accuracy', args.output_dir)

        if args.patience >= args.n_epoch:
            save_model(model, path=config['model_save_path'], model_name='bert')

        freeze_data['train_loss'] = train_loss
        freeze_data['valid_loss'] = valid_loss

    def eval(dataset):
        dev_dataloader = DataLoader(dataset, batch_size=args.predict_batch_size, shuffle=False, num_workers=2)
        n_sample = len(dev_dataloader)
        result = dict()
        model.eval()

        # Loss function
        classified_loss = torch.nn.CrossEntropyLoss().to(device)
        all_pred = []
        all_logit = []
        total_loss = 0
        for sample in tqdm.tqdm(dev_dataloader):
            sample = (i.to(device) for i in sample)
            token, mask, type_ids, y = sample
            batch = len(token)

            with torch.no_grad():
                logit = model(token, mask, type_ids)
                all_logit.append(logit)
                all_pred.append(torch.argmax(logit, 1))
                total_loss += classified_loss(logit, y.long())

        all_y = LongTensor(dataset.dataset[:, -1].astype(int)).cpu()  # [length, n_class]
        all_binary_y = (all_y != 0).long()  # [length, 1] label 0 is oos
        all_pred = torch.cat(all_pred, 0).cpu()
        all_logit = torch.cat(all_logit, 0).cpu()
        ind_class_acc = metrics.ind_class_accuracy(all_pred, all_y)
        report = metrics.classification_report(all_y, all_pred, output_dict=True)
        oos_ind_precision, oos_ind_recall, oos_ind_fscore, _ = metrics.binary_recall_fscore(all_pred,
                                                                                all_binary_y)
        result.update(report)
        y_score = all_logit.softmax(1)[:, 1].tolist()
        eer = metrics.cal_eer(all_binary_y, y_score)

        result['eer'] = eer
        result['ind_class_acc'] = ind_class_acc
        result['loss'] = total_loss / n_sample
        result['oos_ind_precision'] = oos_ind_precision
        result['oos_ind_recall'] = oos_ind_recall
        result['oos_ind_f_score'] = oos_ind_fscore
        result['auc'] = roc_auc_score(all_binary_y, y_score)
        result['y_score'] = y_score
        result['all_binary_y'] = all_binary_y

        freeze_data['valid_all_y'] = all_y
        freeze_data['vaild_all_pred'] = all_pred
        freeze_data['valid_score'] = y_score

        return result

    def test(dataset):
        load_model(model, path=config['model_save_path'], model_name='bert')
        test_dataloader = DataLoader(dataset, batch_size=args.predict_batch_size, shuffle=False, num_workers=2)
        n_sample = len(test_dataloader)
        result = dict()
        model.eval()

        # Loss function
        classified_loss = torch.nn.CrossEntropyLoss().to(device)
        all_pred = []
        total_loss = 0
        all_logit = []
        for sample in tqdm.tqdm(test_dataloader):
            sample = (i.to(device) for i in sample)
            token, mask, type_ids, y = sample
            batch = len(token)

            with torch.no_grad():
                logit = model(token, mask, type_ids)
                all_logit.append(logit)
                all_pred.append(torch.argmax(logit, 1))
                total_loss += classified_loss(logit, y.long())

        all_y = LongTensor(dataset.dataset[:, -1].astype(int)).cpu()  # [length, n_class]
        all_binary_y = (all_y != 0).long()  # [length, 1] label 0 is oos
        all_pred = torch.cat(all_pred, 0).cpu()
        all_logit = torch.cat(all_logit, 0).cpu()

        # classification report
        ind_class_acc = metrics.ind_class_accuracy(all_pred, all_y)
        report = metrics.classification_report(all_y, all_pred, output_dict=True)
        oos_ind_precision, oos_ind_recall, oos_ind_fscore, _ = metrics.binary_recall_fscore(all_pred,
                                                                                all_binary_y)
        result.update(report)
        # 只有二分类时候ERR才有意义
        y_score = all_logit.softmax(1)[:, 1].tolist()
        eer = metrics.cal_eer(all_binary_y, y_score)

        result['eer'] = eer
        result['ind_class_acc'] = ind_class_acc
        result['loss'] = total_loss / n_sample
        result['all_y'] = all_y.tolist()
        result['all_pred'] = all_pred.tolist()
        result['oos_ind_precision'] = oos_ind_precision
        result['oos_ind_recall'] = oos_ind_recall
        result['oos_ind_f_score'] = oos_ind_fscore
        result['auc'] = roc_auc_score(all_binary_y, y_score)
        result['y_score'] = y_score
        result['all_binary_y'] = all_binary_y

        freeze_data['test_all_y'] = all_y.tolist()
        freeze_data['test_all_pred'] = all_pred.tolist()
        freeze_data['test_score'] = y_score
        return result

    if args.do_train:
        if config['data_file'].startswith('binary'):
            text_train_set = processor.read_dataset(data_path, ['train'])
            text_dev_set = processor.read_dataset(data_path, ['val'])
        elif config['dataset'] == 'oos-eval':
            text_train_set = processor.read_dataset(data_path, ['train', 'oos_train'])
            text_dev_set = processor.read_dataset(data_path, ['val', 'oos_val'])
        elif config['dataset'] == 'smp':
            text_train_set = processor.read_dataset(data_path, ['train'])
            text_dev_set = processor.read_dataset(data_path, ['val'])

        train_features = processor.convert_to_ids(text_train_set)
        train_dataset = OOSDataset(train_features)
        dev_features = processor.convert_to_ids(text_dev_set)
        dev_dataset = OOSDataset(dev_features)

        train(train_dataset, dev_dataset)

    if args.do_eval:
        logger.info('#################### eval result at step {} ####################'.format(global_step))
        if config['data_file'].startswith('binary'):
            text_dev_set = processor.read_dataset(data_path, ['val'])
        elif config['dataset'] == 'oos-eval':
            text_dev_set = processor.read_dataset(data_path, ['val', 'oos_val'])
        elif config['dataset'] == 'smp':
            text_dev_set = processor.read_dataset(data_path, ['val'])

        dev_features = processor.convert_to_ids(text_dev_set)
        dev_dataset = OOSDataset(dev_features)
        eval_result = eval(dev_dataset)
        logger.info(eval_result)
        logger.info('eval_eer: {}'.format(eval_result['eer']))
        logger.info('eval_oos_ind_precision: {}'.format(eval_result['oos_ind_precision']))
        logger.info('eval_oos_ind_recall: {}'.format(eval_result['oos_ind_recall']))
        logger.info('eval_oos_ind_f_score: {}'.format(eval_result['oos_ind_f_score']))
        logger.info('eval_auc: {}'.format(eval_result['auc']))
        logger.info(
            'eval_fpr95: {}'.format(ErrorRateAt95Recall(eval_result['all_binary_y'], eval_result['y_score'])))
        gross_result['eval_eer'] = eval_result['eer']
        gross_result['eval_auc'] = eval_result['auc']
        gross_result['eval_fpr95'] = ErrorRateAt95Recall(eval_result['all_binary_y'], eval_result['y_score'])
        gross_result['eval_oos_ind_precision'] = eval_result['oos_ind_precision']
        gross_result['eval_oos_ind_recall'] = eval_result['oos_ind_recall']
        gross_result['eval_oos_ind_f_score'] = eval_result['oos_ind_f_score']

    if args.do_test:
        logger.info('#################### test result at step {} ####################'.format(global_step))
        if config['data_file'].startswith('binary'):
            text_test_set = processor.read_dataset(data_path, ['test'])
        elif config['dataset'] == 'oos-eval':
            text_test_set = processor.read_dataset(data_path, ['test', 'oos_test'])
        elif config['dataset'] == 'smp':
            text_test_set = processor.read_dataset(data_path, ['test'])

        test_features = processor.convert_to_ids(text_test_set)
        test_dataset = OOSDataset(test_features)
        test_result = test(test_dataset)
        save_result(test_result, os.path.join(args.output_dir, 'test_result'))
        logger.info(test_result)
        logger.info('test_eer: {}'.format(test_result['eer']))
        logger.info('test_ood_ind_precision: {}'.format(test_result['oos_ind_precision']))
        logger.info('test_ood_ind_recall: {}'.format(test_result['oos_ind_recall']))
        logger.info('test_ood_ind_f_score: {}'.format(test_result['oos_ind_f_score']))
        logger.info('test_auc: {}'.format(test_result['auc']))
        logger.info('test_fpr95: {}'.format(ErrorRateAt95Recall(test_result['all_binary_y'], test_result['y_score'])))
        gross_result['test_eer'] = test_result['eer']
        gross_result['test_auc'] = test_result['auc']
        gross_result['test_fpr95'] = ErrorRateAt95Recall(test_result['all_binary_y'], test_result['y_score'])
        gross_result['test_oos_ind_precision'] = test_result['oos_ind_precision']
        gross_result['test_oos_ind_recall'] = test_result['oos_ind_recall']
        gross_result['test_oos_ind_f_score'] = test_result['oos_ind_f_score']

        # 输出错误cases
        if config['dataset'] == 'oos-eval':
            texts = [line[0] for line in text_test_set]
        elif config['dataset'] == 'smp':
            texts = [line['text'] for line in text_test_set]
        else:
            raise ValueError('The dataset {} is not supported.'.format(args.dataset))

        output_cases(texts, test_result['all_y'], test_result['all_pred'],
                     os.path.join(args.output_dir, 'test_cases.csv'), processor)

        # confusion matrix
        plot_confusion_matrix(test_result['all_y'], test_result['all_pred'],
                              args.output_dir)

    with open(os.path.join(config['output_dir'], 'freeze_data.pkl'), 'wb') as f:
        pickle.dump(freeze_data, f)
    df = pd.DataFrame(data={'valid_y': freeze_data['valid_all_y'],
                            'valid_score': freeze_data['valid_score'],
                            })
    df.to_csv(os.path.join(config['output_dir'], 'valid_score.csv'))

    df = pd.DataFrame(data={'test_y': freeze_data['test_all_y'],
                            'test_score': freeze_data['test_score']
                            })
    df.to_csv(os.path.join(config['output_dir'], 'test_score.csv'))

    if args.result != 'no':
        pd_result = pd.DataFrame(gross_result)
        if args.seed == 16:
            pd_result.to_csv(args.result + '_gross_result.csv', index=False)
        else:
            pd_result.to_csv(args.result + '_gross_result.csv', index=False, mode='a', header=False)

if __name__ == '__main__':
    parser = argparse.ArgumentParser()

    # ------------------------data------------------------ #
    parser.add_argument('--dataset',
                        choices={'oos-eval', 'smp'}, required=True,
                        help='Which dataset will be used.')

    parser.add_argument('--data_file', required=False, type=str,
                        help="""Which type of dataset to be used,
                        i.e. binary_undersample.json, binary_wiki_aug.json. Detail in config/data.ini""")

    # ------------------------bert------------------------ #
    parser.add_argument('--bert_type',
                        choices={'bert-base-uncased', 'bert-large-uncased', 'bert-base-chinese'}, required=True,
                        help='Type of the pre-trained BERT to be used.')

    # ------------------------action------------------------ #
    parser.add_argument('--do_train', action='store_true',
                        help='Do training step')

    parser.add_argument('--do_eval', action='store_true',
                        help='Do evaluation on devset step')

    parser.add_argument('--do_test', action='store_true',
                        help='Do validation on testset step')

    parser.add_argument('--output_dir', required=True,
                        help='The output directory saving model and logging file.')

    parser.add_argument('--n_epoch', default=500, type=int,
                        help='Number of epoch for training.')

    parser.add_argument('--patience', default=10, type=int,
                        help='Number of epoch of early stopping patience.')

    parser.add_argument('--train_batch_size', default=32, type=int,
                        help='Batch size for training.')

    parser.add_argument('--predict_batch_size', default=16, type=int,
                        help='Batch size for evaluating and testing.')

    parser.add_argument('--gradient_accumulation_steps', default=1, type=int,
                        help='Number of updates steps to accumulate before performing a backward/update pass')

    parser.add_argument('--lr', type=float, default=4e-5,
                        help="Learning rate for Discriminator.")

    parser.add_argument('--fine_tune', action='store_true',
                        help='Whether to fine tune BERT during training.')
    parser.add_argument('--seed', type=int, required=True)
    parser.add_argument('--result', type=str)

    args = parser.parse_args()
    os.makedirs(args.output_dir, exist_ok=True)
    logger = Logger(os.path.join(args.output_dir, 'train.log'))
    main(args)


from socketserver import BaseRequestHandler, TCPServer
import tkinter as tk
from tkinter import ttk

#Override RequestHandler base function
class RequestHandler(BaseRequestHandler):

    def handle(self):
        print("Server connected to: ", self.client_address)
        while True:
            rsp = self.request.recv(512)
            if not rsp: break
            self.request.send(b'Server recieved: ' + rsp)

def start_server():
    server = TCPServer(('', 24000), RequestHandler)
    server.serve_forever()

win = tk.Tk()
win.title("Multi threading GUI")

button = ttk.Button(win, text="Button")
button.grid(column=0, row=0)

win.mainloop()


import os

import fastestimator as fe
from fastestimator.architecture.tensorflow import LeNet
from fastestimator.dataset.data import mnist
from fastestimator.op.numpyop.univariate import ExpandDims, Minmax
from fastestimator.op.tensorop.loss import CrossEntropy
from fastestimator.op.tensorop.model import ModelOp, UpdateOp
from fastestimator.schedule import cosine_decay
from fastestimator.search import GridSearch
from fastestimator.trace.adapt import LRScheduler
from fastestimator.trace.io import BestModelSaver, RestoreWizard
from fastestimator.trace.metric import Accuracy

def get_estimator(init_lr, batch_size, save_dir, restore_dir):
    # step 1
    train_data, eval_data = mnist.load_data()
    pipeline = fe.Pipeline(train_data=train_data,
                           eval_data=eval_data,
                           batch_size=batch_size,
                           ops=[ExpandDims(inputs="x", outputs="x"), Minmax(inputs="x", outputs="x")])

    # step 2
    model = fe.build(model_fn=LeNet, optimizer_fn="adam")
    network = fe.Network(ops=[
        ModelOp(model=model, inputs="x", outputs="y_pred"),
        CrossEntropy(inputs=("y_pred", "y"), outputs="ce"),
        UpdateOp(model=model, loss_name="ce")
    ])
    # step 3
    traces = [
        Accuracy(true_key="y", pred_key="y_pred"),
        BestModelSaver(model=model, save_dir=save_dir, metric="accuracy", save_best_mode="max"),
        LRScheduler(model=model, lr_fn=lambda step: cosine_decay(step, cycle_length=3750, init_lr=init_lr)),
        RestoreWizard(directory=restore_dir)
    ]
    estimator = fe.Estimator(pipeline=pipeline, network=network, epochs=2, traces=traces)
    return estimator

def score_fn(search_idx, init_lr, batch_size, save_dir, restore_dir):
    est = get_estimator(init_lr=init_lr,
                        restore_dir=os.path.join(restore_dir, str(search_idx)),
                        save_dir=os.path.join(save_dir, str(search_idx)),
                        batch_size=batch_size)
    hist = est.fit(summary="exp")
    best_acc = float(max(list(hist.history["eval"]["max_accuracy"].values())))
    return best_acc

def fastestimator_run(restore_dir, save_dir):
    score_fn_in_use = lambda search_idx, init_lr, batch_size: score_fn(search_idx, init_lr, batch_size, save_dir=save_dir, restore_dir=restore_dir)
    mnist_grid_search = GridSearch(eval_fn=score_fn_in_use,
                                   params={
                                       "batch_size": [32, 64], "init_lr": [1e-2, 1e-3]
                                   },
                                   best_mode="max")
    mnist_grid_search.fit(save_dir=restore_dir)


import sublime

import re
from concurrent import futures
from collections import namedtuple, deque

import requests

from .parsers import PREFIX

Request_ = namedtuple('Request', 'request, method, url, args, kwargs, ordering, session')
Response = namedtuple('Response', 'req, res, err')

methods = {
    'GET': requests.get,
    'OPTIONS': requests.options,
    'HEAD': requests.head,
    'POST': requests.post,
    'PUT': requests.put,
    'PATCH': requests.patch,
    'DELETE': requests.delete,
}

class Request(Request_):
    """Hashable `Request` namedtuple.
    """
    def __hash__(self):
        return hash(self.ordering)

    def __eq__(self, other):
        return self.ordering == other.ordering

    def __ne__(self, other):
        return not(self == other)

def parse_args(*args, **kwargs):
    """Used in conjunction with eval to parse args and kwargs from a string.
    """
    return args, kwargs

class ResponseThreadPool:
    """Allows requests to be invoked concurrently, and allows client code to
    inspect instance's responses as they are returned.
    """
    def get_response(self, request, ordering):
        """Calls request with specified args and kwargs parsed from request
        string.

        Also sets "Response" key in env to `Response` object, to provide true
        "chaining" of requests. If two requests are run serially, the second
        request can reference the response returned by the previous request.
        """
        if isinstance(request, Request):  # no need to prepare request
            req = request._replace(ordering=ordering)
        else:
            req = prepare_request(request, self.env, ordering)
        self.pending_requests.add(req)

        res, err = None, ''
        if self.is_done:  # prevents further requests from being made if pool is cancelled
            return Response(req, res, err)  # check using: https://requestb.in/

        try:
            if req.session:
                session = self.env.get(req.session)
                if isinstance(session, requests.sessions.Session):
                    res = getattr(session, req.method.lower())(*req.args, **req.kwargs)
                else:
                    err = 'Session Error: there is no session `{}` defined in your environment'.format(req.session)
            else:
                res = methods.get(req.method)(*req.args, **req.kwargs)
        except requests.Timeout:
            err = 'Timeout Error: the request timed out'
        except requests.ConnectionError:
            err = 'Connection Error: check your connection'
        except SyntaxError as e:
            err = '{}: {}\n\n{}'.format('Syntax Error', e,
                                        'Run "Requester: Show Syntax" to review properly formatted requests')
        except TypeError as e:
            err = '{}: {}'.format('Type Error', e)
        except Exception as e:
            err = '{}: {}'.format('Other Error', e)

        self.env['Response'] = res  # to allow "chaining" of serially executed requests
        return Response(req, res, err)

    def __init__(self, requests, env, max_workers):
        self.is_done = False
        self.responses = deque()
        self.requests = requests
        self.pending_requests = set()
        self.env = env
        self.max_workers = max_workers

    def get_pending_requests(self):
        """Getter for `self.pending_requests`. This is a `set` that's shared
        between threads, which makes iterating over it unsafe.
        """
        return self.pending_requests.copy()

    def run(self):
        """Concurrently invoke `get_response` for all of instance's `requests`.
        """
        with futures.ThreadPoolExecutor(
            max_workers=min(self.max_workers, len(self.requests))
        ) as executor:
            to_do = []
            for i, request in enumerate(self.requests):
                future = executor.submit(self.get_response, request, i)
                to_do.append(future)

            for future in futures.as_completed(to_do):
                result = future.result()
                # `responses` and `pending_requests` are instance properties, which means
                # client code can inspect instance to read responses as they are completed
                try:
                    self.pending_requests.remove(result.req)
                except KeyError:
                    print('{} was not in pending requests, this is weird...'.format(result.req))
                self.responses.append(result)
        self.is_done = True

def prepare_request(request, env, ordering):
    """Parse and evaluate args and kwargs in request string under context of
    env.

    Also, prepare request string: if request is not prefixed with "{var_name}.",
    prefix request with "requests." Accepts a request string and returns a
    `Request` instance.

    Finally, ensure request can time out so it doesn't hang indefinitely.
    http://docs.python-requests.org/en/master/user/advanced/#timeouts
    """
    req = request.strip()
    if not re.match(PREFIX, req):
        req = 'requests.' + req
    session = None
    if not req.startswith('requests.'):
        session = req.split('.')[0]

    env['__parse_args__'] = parse_args
    index = req.index('(')
    try:
        args, kwargs = eval('__parse_args__{}'.format(req[index:]), env)
    except:
        args, kwargs = [], {}
    else:
        args = list(args)

    method = req[:index].split('.')[1].strip().upper()
    url = kwargs.get('url', None)
    if url is not None:
        url = prepare_url(url)
        kwargs['url'] = url
    else:
        try:
            url = args[0]
        except:
            pass  # this method isn't responsible for raising exceptions
        else:
            url = prepare_url(url)
            args[0] = url

    if 'timeout' not in kwargs:
        kwargs['timeout'] = sublime.load_settings('Requester.sublime-settings').get('timeout', None)
    return Request(req, method, url, args, kwargs, ordering, session)

def prepare_url(url):
    """Prepend scheme to URL if necessary.
    """
    if type(url) is str and len(url.split('://')) == 1:
        return 'http://' + url
    return url


import pyodbc
import pandas as pd
import sqlite3
import os
import datetime
import numpy as np

from springbok.sda.sda_dict import sda_dict

import matplotlib.pyplot as plt

def access_check():
	r'''
	Returns an empty list if the AccessDatabaseEngine_x64 is not installed.

	If so force install AccessDatabaseEngine_x64.exe (2010 version) using cmd
	> path AccessDatabaseEngine_x64.exe /passive

	Note: Must either rename or delete HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Common\FilesPaths
	'''
	return [x for x in pyodbc.drivers() if x.startswith('Microsoft Access Driver')]

def sda_index(
	src = os.path.join(r'\\BHICalres01\Groups2\Inteq\Engineering - Well Planning\SDA Shared Files','SDA Index.accdb'),
	print_tables = False, save = True, dst = os.path.join(r'C:\1SDA'),
	):
	r'''
	Returns the SDA Index as a pandas dataframe.

	Uses standard network path if none supplied (src):
	\\BHICalres01\Groups2\Inteq\Engineering - Well Planning\SDA Shared Files\SDA Index.accdb,

	print_tables: default = False
	If True, will print out tables of the queried database

	save: default = False
	If True will save specified dst

	dst: default C:\1SDA
	Specified destination path

	'''
	db_file = src # Supplied source path
	conn_str = (
	r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};'
	r'DBQ='+db_file+';'
	)
	cnxn = pyodbc.connect(conn_str)
	crsr = cnxn.cursor()

	# Print Tables in the ACCDB
	if print_tables == True:
		for table_info in crsr.tables(tableType='TABLE'):
			print(table_info.table_name)

	query = "SELECT * FROM [SDA_Index]"
	sda_index = pd.read_sql(query, cnxn)
	cnxn.close()

	# Rename to convention
	sda_index.columns = [x.strip().lower() for x in sda_index.columns]
	sda_index = sda_index.rename(columns={
		'job number':'jobnum',
		'run number':'run',
		'target formation':'form',
		'hole size':'hsize',
		'date in':'datein',
		'date out':'dateout',
		'depth in':'depthin',
		'depth out':'depthout',
		'autotrak':'atk',
		'motor setting':'ako',
		'circulating hrs':'t_circ',
		'drilling hrs':'t_drill',
		'bit model':'bit_type',
		'bit provider':'bit_mfc',
		'bit grading':'bit_grade'
	})

	if save == True:
		# Create directory and save to C:\\1SDA\\SDA_Index.db
		directory = dst

		if not os.path.exists(directory):
			os.makedirs(directory)
		# SQLite
		con = sqlite3.connect(os.path.join(directory,'SDA_Index.db'))
		sda_index.to_sql('SDA_Index', con=con, if_exists='replace')
		con.close()
		# CSV
		csv_name = datetime.datetime.now().strftime("%Y-%m-%d")+'_SDA_Index.csv'
		sda_index.to_csv(os.path.join(directory,csv_name))

	return sda_index

def sda_table_query(cnxn, table_name, sda_dict = sda_dict):

	query = "SELECT * FROM [{}]".format(table_name)
	df_sda = pd.read_sql(query, cnxn)
	df_sda.columns = [x.strip().lower() for x in df_sda.columns]
	df_sda = df_sda.rename(columns=sda_dict)
	return df_sda

def sda_query(db_path):
	db_file = os.path.join(db_path)

	conn_str = (
		r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};'
		r'DBQ='+db_file+';'
		)
	cnxn = pyodbc.connect(conn_str)
	# crsr = cnxn.cursor() ### Unused
	# Extract table(s)
	df_survey = sda_table_query(cnxn,table_name='SurveyCalc',sda_dict=sda_dict)
	df_para = sda_table_query(cnxn,table_name='Calculations',sda_dict=sda_dict)
	df_header = sda_table_query(cnxn,table_name='Headers',sda_dict=sda_dict)
	df_activity = sda_table_query(cnxn,table_name='ActivityByFormation',sda_dict=sda_dict)
	df_form = sda_table_query(cnxn,table_name='FormationCalc',sda_dict=sda_dict)
	try:
		df_maps = pd.concat([
							sda_table_query(cnxn,table_name='MaPSRunData',sda_dict=sda_dict),
							sda_table_query(cnxn,table_name='MaPSMWDData',sda_dict=sda_dict),
							sda_table_query(cnxn,table_name='MaPSMotorData',sda_dict=sda_dict),
							sda_table_query(cnxn,table_name='MaPSMudData',sda_dict=sda_dict),
							],axis=1)
	except:
		print('No MaPs data available'.format())
		df_maps = pd.DataFrame()

	well = df_header.id[df_header.ref == 'Well'].iloc[0]
	try:
		jobnum = df_header.id[df_header.ref == 'Job Number'].iloc[0]
	except:
		jobnum = 'N/A'
		print('{}: No Job Number'.format(well))
	print('COMPLETED IMPORT - {} - {}'.format(jobnum,well))

	cnxn.close()
	return df_survey,df_para,df_header,df_activity,df_form,df_maps

def import_accdb(offset_list,comp_list,filter_w_maps=False,
				 color=[

				'#005EB8', # BLUE
				'#FE5000', # ORANGE
				'#00BF6F', # GREEN
				'#10069F', # DARK BLUE
				'#6a3d9a', ## PURPLE
				'#13294B',  # INDIGO

				'#02BC94', # LIGHT BH GREEN

				'#EAAA00', # LIGHT ORANGE
				'#00B5E2', # LIGHT BLUE
				'#000000',	# BLACK
				#'#B1B3B3', # LIGHT GREY
				#'#63666A', # GREY
				'#dd3497', # PINK
				'#fb9a99', #LIGHT RED
				'#97D700', # LIGHT GREEN
					],
				):
	'''
	Imports SDA .accdb and outputs:
	df_m: Master parameters
	df_m_maps: Master maps information
	df_m_form: Master formations
	df_m_survey: Master surveys (no vertical section)
	df_m_para_wform: Master parameters on-bottom with formations
	df_m_header: Master well information
	df_m_color: Master color to well mapping

	filter_w_maps

	'''
	import pandas as pd
	import itertools
	import springbok.sda.query as sb
	import os
	# All the wells you want to import broken into Offsets and Comparison
	well_list =  (
		offset_list+
		comp_list
	)
	comp_wells = []
	df_m = pd.DataFrame()
	df_m_maps = pd.DataFrame()
	df_m_form = pd.DataFrame()
	df_m_survey = pd.DataFrame()
	df_m_para = pd.DataFrame()
	df_m_header = pd.DataFrame()
	df_m_color = pd.DataFrame()

	for db,color in zip(well_list,itertools.cycle(color)):
		fig,ax= plt.subplots(1,1,figsize=(15,10))
		#file_path = os.path.join(directory,db)
		file_path = db
		print(f"IMPORT - {db.replace(os.getcwd(),'')}")
		df_survey,df_para,df_header,df_activity,df_form,df_maps = sb.sda_query(file_path)

		df_activity = pd.DataFrame() # NOT USED

		# Create copy of MaPs data with duplicated runs removed
		_ = df_maps.loc[:,~df_maps.columns.duplicated()][['run','depthin','depthout']].copy()
		# Pason Date and Time seperate
		if 'datetime' not in df_para.keys():
			time = pd.to_datetime(df_para['date'].iloc[:,0]).dt.strftime('%Y/%m/%d')
			date = pd.to_datetime(df_para['time']).dt.strftime('%H:%M:%S')
			# NOV data set check
			if date.iloc[-1] == '00:00:00':
				date = pd.to_datetime(df_para['date'].iloc[:,0]).dt.strftime('%H:%M:%S')

			df_para = df_para.assign(datetime = date.astype(str) +' '+ time.astype(str))
			df_para = df_para.assign(datetime = pd.to_datetime(df_para.datetime, errors = 'coerce'))

			time = pd.to_datetime(df_maps['datein']).dt.strftime('%Y/%m/%d')
			date = pd.to_datetime(df_maps['timein']).dt.strftime('%H:%M:%S')
			timeout = pd.to_datetime(df_maps['dateout']).dt.strftime('%Y/%m/%d')
			dateout = pd.to_datetime(df_maps['timeout']).dt.strftime('%H:%M:%S')
			df_maps = df_maps.assign(datetimein = date.astype(str) +' '+ time.astype(str))
			df_maps = df_maps.assign(datetimeout = dateout.astype(str) +' '+ timeout.astype(str))

			df_maps['datetimein'] = pd.to_datetime(df_maps.datetimein, format='%H:%M:%S %Y/%m/%d')
			df_maps['datetimeout'] = pd.to_datetime(df_maps.datetimeout, format='%H:%M:%S %Y/%m/%d')
			df_maps = df_maps.assign(well = df_header[df_header.ref == 'Well'].id.iloc[0])
			df_maps =df_maps.loc[:,~df_maps.columns.duplicated()]
			df_maps =df_maps.replace('DURAMAX','DURAMAXD075').replace('DURAMAXND20','DURAMAXD075').replace('°','')
			try:
				df_maps['avg_rop'] = df_maps['avg_rop'].replace('n/a',np.nan).astype(float).round(1)
			except:
				df_maps['avg_rop'] = len(df_maps['avg_rop'])*[np.nan]

			df_maps.run = df_maps.run.astype(int)

			df_m_maps = pd.concat([df_m_maps,df_maps])

			df_m_color = pd.concat([df_m_color,pd.DataFrame([{'well':df_header[df_header.ref == 'Well'].id.iloc[0],'color':color}])])
		###
		ax.plot(df_para.datetime,df_para.depth,label=df_header[df_header.ref == 'Well'].id.iloc[0]+ '2 - df_par/time original')
		###

		###
		df_para_wform = pd.merge_asof(df_para[df_para.depth == df_para.bdepth].sort_values('depth')
					[[x for x in df_para.keys() if x != 'form']],df_form[['depth','form']],
					left_on='depth',right_on='depth',
					allow_exact_matches = True,
					)
		###
		ax.plot(df_para_wform.datetime,df_para_wform.depth,label=df_header[df_header.ref == 'Well'].id.iloc[0]+ '2 - df_parawform/depth')
		###

		# Assign Well
		df_m_form = pd.concat([df_m_form,df_form.assign(well = df_header[df_header.ref == 'Well'].id.iloc[0])])
		df_m_survey = pd.concat([df_m_survey,df_survey.assign(well = df_header[df_header.ref == 'Well'].id.iloc[0])])

		# Assign filepath to each accdb directory
		df_header = pd.concat([df_header,pd.DataFrame([{'ref':'filepath','id':db}])])
		df_m_header = pd.concat([df_m_header,df_header.assign(well = df_header[df_header.ref == 'Well'].id.iloc[0])])
		# Assign the run data to DataFrame of MaPs merged on DepthIn and backfilling the missing data
		#df_para.run = pd.merge_asof(left = df_para[[x for x in df_para.keys() if x != 'run']].sort_values('depth'),right= _,left_on='depth',right_on='depthin').fillna(method='bfill').run.values # ALL Data (DEPTH)

		##TEMP##df_para_wform.run = pd.merge_asof(left = df_para_wform[[x for x in df_para_wform.keys() if x != 'run']],right= _.sort_values(by='depthin'),
		##TEMP##left_on='depth',right_on='depthin').fillna(method='bfill').run.values # OnBtm Data (DEPTH)

		df_para_wform.sort_values(by='datetime').run = pd.merge_asof(left = df_para_wform[[x for x in df_para_wform.keys() if x != 'run']].sort_values('datetime'),right= df_maps.loc[:,~df_maps.columns.duplicated()]
				  .sort_values('datetimein'),left_on='datetime',right_on='datetimein',allow_exact_matches=True).fillna(method='bfill').run.values # ALL Data (DateTime)
		df_para_wform =df_para_wform.dropna(subset=['run'])
		###
		ax.plot(df_para_wform.datetime,df_para_wform.depth,label=df_header[df_header.ref == 'Well'].id.iloc[0]+ '2 - df_parawform/depth')
		###
		df_para.run = pd.merge_asof(left = df_para[[x for x in df_para.keys() if x != 'run']].sort_values('datetime'),right= df_maps.loc[:,~df_maps.columns.duplicated()]
				  .sort_values('datetimein'),left_on='datetime',right_on='datetimein',allow_exact_matches=True).fillna(method='bfill').run.values # ALL Data (DateTime)
		###
		ax.plot(df_para.datetime,df_para.depth,label=df_header[df_header.ref == 'Well'].id.iloc[0]+ '3 - df_para/time')
		ax.legend()
		###
		# Assign wellbore from header
		df_para_wform = df_para_wform.assign(well = df_header[df_header.ref == 'Well'].id.iloc[0])
		df_para = df_para.assign(well = df_header[df_header.ref == 'Well'].id.iloc[0])
		# Remove Duplicated column headers, cannot append DataFrames with duplicates
		df_para_wform =df_para_wform.loc[:,~df_para_wform.columns.duplicated()]
		df_para =df_para.loc[:,~df_para.columns.duplicated()]
		# Concat List
		df_m_para = pd.concat([df_m_para,df_para])
		# Well to compare to are added to comp_list
		# This is you main wellbore, all others will be treated as offsets and averaged into a rolling benchmark
		if db in comp_list:
			print('>',db)
			comp_wells.append(df_para_wform.well.unique()[0])
		#df_m = df_m.append(df_para_wform, ignore_index=True, sort=False)
		df_m = pd.concat([df_para_wform,df_m], ignore_index=True, sort=False)

	# Calculate MSE Value
	df_m = df_m.assign(
		mse = ( (df_m.wob*2.248089)/(np.pi*(df_m.hsize*0.03937/2)**2) )
		+ (2*np.pi * df_m.rpm * df_m.torque*12)/((np.pi*(df_m.hsize*0.03937/2)**2)*df_m.rop*39.3701)
			)

	# Reverse list of comparison wells to ensure the list is ordered from newest to oldest
	comp_wells.reverse()
	# Save to CSV {operator} {Field} {PAD}
	df_m_maps.to_csv('{} {} {} Maps (all).csv'.format(
		df_header.id[df_header.ref == 'Operator'].iloc[0].split(' ')[0],
		df_header.id[df_header.ref == 'Field'].iloc[0].split(' ')[0],
		'-'.join([df_header.id[df_header.ref == 'Facility'].iloc[0].split('-')[0],
			  df_header.id[df_header.ref == 'Facility'].iloc[0].split('-')[1]])
	),index=False)

	return df_m,df_m_maps,df_m_form,df_m_survey,df_m_para,df_m_header,df_m_color,comp_wells

### ### ### ###
def main():
	return ''

if __name__ == "__main__":
	main()


"""A collection of functions to plot data."""

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib import cm
import mne

from ratios import calc_interacting_param_ratios
from settings import *
from paths import FIGS_PATHS as fp

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

def plot_interacting_sims(data, param1, param2, plot_log=False, show=False, save_fig=False,
                          file_path=fp.sims_interacting, file_name='InteractingSims'):
    """Plots heatmaps for interacting parameter simulations.

    Parameters
    ----------
    data : list of lists
        List of power spectra.
    param1 : string
        Param used in simulation.
    param2 : string
        Param used in simulation.
    plot_log : boolean
        Whether to log values before plotting the heatmap.
    show : boolean
        Whether to display to plot.
    save_fig : boolean
        Whether to save out the figure.
    file_path : string
        Path to save the plot to.
    file_name : string
        File name to save the plot with.
    """

    # Calculate ratios
    ratios = calc_interacting_param_ratios(data)

    if plot_log:
        ratios = np.log10(ratios)
        vmin, vmax = 0, 1.6
    else:
        vmin, vmax = None, None

    fig, ax = plt.subplots()
    sns.heatmap(ratios, vmin, vmax, xticklabels=PARAMS[param2], yticklabels=PARAMS[param1])
    plt.yticks(rotation=0)

    ax.invert_yaxis()
    plt.xlabel(param2, {'fontsize' : 14})
    plt.ylabel(param1, {'fontsize' : 14})
    plt.tight_layout()

    if save_fig:
        plt.savefig(fp.make_file_path(file_path, file_name, 'pdf'));

    if not show:
        plt.close()

def plot_param_ratio_corr(data, title="Ratio vs. Spectral Features",
                          y_labels=["Theta", "Alpha", "Beta"], show=True,
                          save_fig=False, file_path=fp.eeg_corrs,
                          file_name="Spectral_Features_Ratio_corr"):
    """Plot correlations between BandRatio measures and spectral features.

    Parameters
    ----------
    data: 2x3 ndarray
        Correlations of BandRatios to Spectral Features.
    title: string
        Title of plot.
    y_labels: list of strings
        Labels of slow and fast wave to use on y-axis.
    show : boolean
        Whether to display to plot.
    save_fig: boolean
        If True - save plot.
    file_path : string
        Path to save the plot to.
    file_name : string
        File name to save the plot with.
    """

    if not np.all(data):
        raise RuntimeError("No data - cannot proceed.")

    fig, ax2 = plt.subplots()
    ax2 = sns.heatmap(data, cmap="bwr", yticklabels=y_labels, xticklabels=FEATURE_LABELS,
                      annot=True, ax=ax2, vmin=-1, vmax=1, annot_kws={"size": 20});
    plt.yticks(rotation=45, verticalalignment='center');

    plt.tight_layout()

    if save_fig:
        plt.savefig(fp.make_file_path(file_path, file_name, 'pdf'));

    if not show:
        plt.close()

def plot_param_ratio_corr_exp(exp, title="Ratio vs. Spectral Features",
                              cbar=False, show=False, save_fig=False,
                              file_path=fp.eeg_corrs, file_name="Spectral_Features_Ratio_corr",):
    """Same as `plot_param_ratio_corr`, but for the exponent."""

    fig, ax1 = plt.subplots(figsize=(2.5, 1.75));
    ax1 = sns.heatmap(exp[0].reshape((1,1)), cmap="bwr", annot=True, cbar=cbar,
                      ax=ax1, vmin=-1, vmax=1, annot_kws={"size": 30});

    plt.tick_params(axis='both', which='both', bottom=False, top=False,
                    labelbottom=False, left=False, labelleft=False);

    if save_fig:
        plt.savefig(fp.make_file_path(file_path, file_name + '_exp', 'pdf'));

    if not show:
        plt.close()

def plot_param_topo(data, raw, label='', save=False):
    """Plots the topography of a spectral parameter."""

    fig, ax = plt.subplots();
    mne.viz.plot_topomap(data, raw.info, vmin=min(data), vmax=max(data),
                         cmap=cm.viridis, contours=0, axes=ax);
    ax.set_title(label)

    if save:
        fig.savefig(fp.make_file_path(fp.eeg_topos, label + '-topo', 'pdf'));


import numpy

N, M, P = map(int, input().split())

a1 =[]
a2 =[]
for i in range(N):
    rows = input().split()
    a1.append(rows)

for i in range(M):
    rows = input().split()
    a2.append(rows)

a1 = numpy.array(a1, int)
a2 = numpy.array(a2, int)

print(numpy.concatenate((a1, a2), axis = 0))


from tkinter import *

root = Tk()
root.geometry('250x150')

button1 = Button(text="Left")
button1.pack(side = LEFT)

button2 = Button(text="Top")
button2.pack(side = TOP)

button3 = Button(text="Right")
button3.pack(side = RIGHT)

button4 = Button(text="Bottom")
button4.pack(side = BOTTOM)

root.mainloop()


import tensorflow as tf

def shape_list(x):
    """Deal with dynamic shape in tensorflow cleanly."""
    static = x.shape.as_list()
    dynamic = tf.shape(x)
    return [dynamic[i] if s is None else s for i, s in enumerate(static)]

class PositionalEmbedding(tf.keras.layers.Layer):
    def __init__(self, demb, **kwargs):
        super().__init__(**kwargs)

        self.inv_freq = 1 / (10000 ** (tf.range(0, demb, 2.0) / demb))

    def call(self, pos_seq, bsz=None):
        sinusoid_inp = tf.einsum("i,j->ij", pos_seq, self.inv_freq)
        pos_emb = tf.concat([tf.sin(sinusoid_inp), tf.cos(sinusoid_inp)], -1)

        if bsz is not None:
            return tf.tile(pos_emb[:, None, :], [1, bsz, 1])
        else:
            return pos_emb[:, None, :]

class PositionwiseFF(tf.keras.layers.Layer):
    def __init__(self, d_model, d_inner, dropout, kernel_initializer,
                 pre_lnorm=False, **kwargs):
        super().__init__(**kwargs)

        self.d_model = d_model
        self.d_inner = d_inner
        self.dropout = dropout

        self.layer_1 = tf.keras.layers.Dense(
            d_inner, kernel_initializer=kernel_initializer, activation=tf.nn.relu, name='layer_1'
        )
        self.drop_1 = tf.keras.layers.Dropout(dropout, name='drop_1')
        self.layer_2 = tf.keras.layers.Dense(d_model, kernel_initializer=kernel_initializer, name='layer_2')
        self.drop_2 = tf.keras.layers.Dropout(dropout, name='drop_2')

        self.layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-6, name='layer_norm')
        self.pre_lnorm = pre_lnorm

    def call(self, inp, training=False):
        if self.pre_lnorm:
            # layer normalization + positionwise feed-forward
            core_out = self.layer_norm(inp)
            core_out = self.layer_1(core_out)
            core_out = self.drop_1(core_out, training=training)
            core_out = self.layer_2(core_out)
            core_out = self.drop_2(core_out, training=training)

            output = [core_out + inp]
        else:
            # positionwise feed-forward
            core_out = self.layer_1(inp)
            core_out = self.drop_1(core_out, training=training)
            core_out = self.layer_2(core_out)
            core_out = self.drop_2(core_out, training=training)

            output = [self.layer_norm(inp + core_out)]

        return output

class RelativeMultiHeadAttn(tf.keras.layers.Layer):
    def __init__(
        self,
        n_head,
        d_model,
        d_head,
        dropout,
        dropatt,
        kernel_initializer,
        pre_lnorm=False,
        r_r_bias=None,
        r_w_bias=None,
        **kwargs
    ):
        super().__init__(**kwargs)

        self.n_head = n_head
        self.d_model = d_model
        self.d_head = d_head
        self.dropout = dropout
        self.kernel_initializer=kernel_initializer

        self.qkv_net = tf.keras.layers.Dense(
            3 * n_head * d_head, kernel_initializer=kernel_initializer, use_bias=False, name="qkv"
        )
        self.r_net = tf.keras.layers.Dense(
            self.n_head * self.d_head, kernel_initializer=kernel_initializer, use_bias=False, name="r"
        )
        self.drop = tf.keras.layers.Dropout(dropout)
        self.dropatt = tf.keras.layers.Dropout(dropatt)
        self.o_net = tf.keras.layers.Dense(
            d_model, kernel_initializer=kernel_initializer, use_bias=False, name="o"
        )
        self.layer_norm = tf.keras.layers.LayerNormalization(epsilon=1e-6)

        self.scale = 1 / (d_head ** 0.5)

        if r_r_bias is not None and r_w_bias is not None:  # Biases are shared
            self.r_r_bias = r_r_bias
            self.r_w_bias = r_w_bias
        else:
            self.r_r_bias = self.add_weight(
                shape=(self.n_head, self.d_head), initializer="zeros", trainable=True, name="r_r_bias"
            )
            self.r_w_bias = self.add_weight(
                shape=(self.n_head, self.d_head), initializer="zeros", trainable=True, name="r_w_bias"
            )

        self.pre_lnorm = pre_lnorm

    def _rel_shift(self, x):
        x_size = shape_list(x)

        x = tf.pad(x, [[0, 0], [1, 0], [0, 0], [0, 0]])
        x = tf.reshape(x, [x_size[1] + 1, x_size[0], x_size[2], x_size[3]])
        x = tf.slice(x, [1, 0, 0, 0], [-1, -1, -1, -1])
        x = tf.reshape(x, x_size)

        return x

    def call(self, inputs, training=False):
        w, r, attn_mask, mems = inputs
        qlen, rlen, bsz = shape_list(w)[0], shape_list(r)[0], shape_list(w)[1]

        if mems is not None:
            cat = tf.concat([mems, w], 0)
        else:
            cat = w

        if self.pre_lnorm:
            cat = self.layer_norm(cat)

        w_heads = self.qkv_net(cat)
        r_head_k = self.r_net(r)

        w_head_q, w_head_k, w_head_v = tf.split(w_heads, 3, axis=-1)
        w_head_q = w_head_q[-qlen:]

        klen = shape_list(w_head_k)[0]

        w_head_q = tf.reshape(w_head_q, (qlen, bsz, self.n_head, self.d_head))
        w_head_k = tf.reshape(w_head_k, (klen, bsz, self.n_head, self.d_head))
        w_head_v = tf.reshape(w_head_v, (klen, bsz, self.n_head, self.d_head))

        r_head_k = tf.reshape(r_head_k, (rlen, self.n_head, self.d_head))

        rw_head_q = w_head_q + self.r_w_bias
        rr_head_q = w_head_q + self.r_r_bias

        AC = tf.einsum("ibnd,jbnd->ijbn", rw_head_q, w_head_k)
        BD = tf.einsum("ibnd,jnd->ijbn", rr_head_q, r_head_k)
        BD = self._rel_shift(BD)

        attn_score = AC + BD
        attn_score = attn_score * self.scale

        attn_mask_t = attn_mask[:, :, None, None]
        attn_score = attn_score * (1 - attn_mask_t) - 1e30 * attn_mask_t

        attn_prob = tf.nn.softmax(attn_score, axis=1)
        attn_prob = self.dropatt(attn_prob, training=training)

        attn_vec = tf.einsum("ijbn,jbnd->ibnd", attn_prob, w_head_v)
        size_t = shape_list(attn_vec)
        attn_vec = tf.reshape(attn_vec, (size_t[0], size_t[1], self.n_head * self.d_head))

        attn_out = self.o_net(attn_vec)
        attn_out = self.drop(attn_out, training=training)

        if self.pre_lnorm:
            outputs = [w + attn_out]
        else:
            outputs = [self.layer_norm(w + attn_out)]

        return outputs

class TransformerXLLayer(tf.keras.layers.Layer):
    def __init__(
        self,
        n_head,
        d_model,
        d_head,
        d_inner,
        dropout,
        dropatt,
        initializer,
        pre_lnorm=False,
        r_w_bias=None,
        r_r_bias=None,
        **kwargs
    ):
        super().__init__(**kwargs)

        self.n_head = n_head
        self.d_model = d_model
        self.d_head = d_head
        self.d_inner = d_inner
        self.dropout = dropout
        self.dropatt = dropatt
        self.initializer = initializer
        self.pre_lnorm = pre_lnorm

        self.xltran_attn = RelativeMultiHeadAttn(
            n_head=self.n_head,
            d_model=self.d_model,
            d_head=self.d_head,
            dropout=self.dropout,
            dropatt=self.dropatt,
            kernel_initializer=self.initializer,
            pre_lnorm=self.pre_lnorm,
            r_w_bias=r_w_bias,
            r_r_bias=r_r_bias,
            name="xltran_attn",
        )
        self.pos_ff = PositionwiseFF(
            d_model=self.d_model,
            d_inner=self.d_inner,
            dropout=self.dropout,
            kernel_initializer=self.initializer,
            pre_lnorm=self.pre_lnorm,
            name="pos_ff",
        )

    def call(self, inputs, training=False):
        inp, r, attn_mask, mems = inputs
        attn_outputs = self.xltran_attn([inp, r, attn_mask, mems], training=training)
        ff_output = self.pos_ff(attn_outputs[0], training=training)

        outputs = [ff_output[0]]

        return outputs

class AdaptiveEmbedding(tf.keras.layers.Layer):
    def __init__(self, n_token, d_embed, d_proj, cutoffs, initializer, \
                 proj_initializer=None, div_val=1, proj_same_dim=True, \
                 use_tpu=True, **kwargs):
        super().__init__(**kwargs)

        self.n_token = n_token
        self.d_embed = d_embed
        self.d_proj = d_proj

        self.cutoffs = cutoffs + [n_token]
        self.cutoff_ends = [0] + self.cutoffs

        self.initializer = initializer
        self.proj_initializer = proj_initializer if proj_initializer is not None else initializer

        self.div_val = div_val
        self.proj_same_dim = proj_same_dim

        self.use_tpu = use_tpu

        self.emb_scale = d_proj ** 0.5

        self.emb_weights = []
        self.emb_projs = []

        for i in range(len(self.cutoffs)):
            l_idx, r_idx = self.cutoff_ends[i], self.cutoff_ends[i + 1]
            d_emb_i = self.d_embed // (self.div_val ** i)
            self.emb_weights.append(
                self.add_weight(
                    shape=(r_idx - l_idx, d_emb_i),
                    initializer=self.initializer,
                    name="emb_weights_._{}".format(i),
                )
            )
            if d_emb_i == d_proj and \
                    (not self.proj_same_dim or self.div_val == 1):
                self.emb_projs.append(None)
            else:
                self.emb_projs.append(
                    self.add_weight(
                        shape=(d_emb_i, self.d_proj),
                        initializer=self.proj_initializer,
                        trainable=True,
                        name="emb_projs_._{}".format(i),
                    )
                )

    def get_weights(self):
        weights = {"emb_layers": [], "emb_projs": []}
        for i in range(len(self.emb_layers)):
            weights["emb_layers"].append(self.emb_layers[i].get_weights())
            weights["emb_projs"].append(self.emb_projs[i])
        return weights

    @staticmethod
    def _embedding_lookup(lookup_table, x, use_tpu=False):
        if use_tpu:
            n_token = shape_list(lookup_table)[0]
            one_hot_idx = tf.one_hot(x, n_token)
            if one_hot_idx.shape.ndims == 2:
                return tf.einsum('nd,in->id', lookup_table, one_hot_idx)
            else:
                return tf.einsum('nd,ibn->ibd', lookup_table, one_hot_idx)
        else:
            return tf.nn.embedding_lookup(lookup_table, x)

    def call(self, inp):
        inp_flat = tf.reshape(inp, (-1,))
        emb_flat = tf.zeros([shape_list(inp_flat)[0], self.d_proj])
        for i in range(len(self.cutoffs)):
            l_idx, r_idx = self.cutoff_ends[i], self.cutoff_ends[i + 1]

            mask_i = (inp_flat >= l_idx) & (inp_flat < r_idx)
            inp_i = tf.minimum(inp_flat, r_idx-1)
            inp_i = tf.maximum(inp_i-l_idx, 0)
            emb_i = self._embedding_lookup(self.emb_weights[i], inp_i, self.use_tpu)
            if self.emb_projs[i] is not None:
                emb_i = tf.einsum("id,de->ie", emb_i, self.emb_projs[i])

            mask_i = tf.tile(tf.reshape(mask_i, [-1, 1]), [1, self.d_proj])
            emb_flat = tf.where(mask_i, emb_i, emb_flat)

        embed_shape = shape_list(inp) + [self.d_proj]
        embed = tf.reshape(emb_flat, embed_shape)

        embed *= self.emb_scale

        return embed

class AdaptiveSoftmax(tf.keras.layers.Layer):
    def __init__(self, n_token, d_embed, d_proj, cutoffs, tie_projs, \
                 initializer=None, proj_initializer=None, div_val=1, \
                 proj_same_dim=True, tied_to=None, **kwargs):
        super().__init__(**kwargs)

        self.n_token = n_token
        self.d_embed = d_embed
        self.d_proj = d_proj

        self.cutoffs = cutoffs + [n_token]
        self.cutoff_ends = [0] + self.cutoffs
        self.n_clusters = len(self.cutoffs) - 1

        self.div_val = div_val
        self.proj_same_dim=True

        self.tied_to = tied_to
        assert tied_to is not None
        self.tie_projs = tie_projs

        self.out_weights = []
        self.out_biases = []
        self.out_projs = []

        if self.n_clusters > 0:
            self.cluster_weight = self.add_weight(
                shape=(self.n_clusters, self.d_embed), initializer="zeros", \
                    trainable=True, name="cluster_weight"
            )
            self.cluster_bias = self.add_weight(
                shape=(self.n_clusters,), initializer="zeros", trainable=True, \
                    name="cluster_bias"
            )

        for i, emb_weight in enumerate(self.tied_to.emb_weights):
            self.out_weights.append(emb_weight)
            vocab_size = shape_list(emb_weight)[0]
            self.out_biases.append(
                self.add_weight(
                    shape=(vocab_size,),
                    initializer="zeros",
                    trainable=True,
                    name="out_layers_._{}_.bias".
                        format(i)
                )
            )

        for i, emb_proj in enumerate(self.tied_to.emb_projs):
            out_proj = emb_proj
            if emb_proj is not None and not self.tie_projs[i]:
                out_proj = self.add_weight(
                    shape=shape_list(emb_proj),
                    initializer=proj_initializer,
                    trainable=True,
                    name="out_projs_._{}".format(i)
                )
            self.out_projs.append(out_proj)

    @staticmethod
    def _logit(x, W, b, proj=None):
        y = x
        if x.shape.ndims == 3:
            if proj is not None:
                y = tf.einsum("ibd,ed->ibe", y, proj)
            return tf.einsum("ibd,nd->ibn", y, W) + b
        else:
            if proj is not None:
                y = tf.einsum('id,ed->ie', y, proj)
            return tf.einsum('id,nd->in', y, W) + b

    @staticmethod
    def _gather_logprob(logprob, target):
        lp_size = shape_list(target)
        r = tf.range(lp_size[0])
        c = tf.range(lp_size[1])
        C, R = tf.meshgrid(c, r)
        idx = tf.stack([R, C, target], axis=2)
        return tf.gather_nd(logprob, idx)

    def call(self, inputs, return_mean=True):
        hidden, target = inputs
        head_logprob = 0
        if self.n_clusters == 0:
            output = self._logit(hidden, self.out_weights[0], self.out_biases[0], self.out_projs[0])
            loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=target, logits=output)
        else:
            hidden_sizes = shape_list(hidden)
            out = []
            loss = tf.zeros(hidden_sizes[:2], dtype=tf.float32)
            for i in range(len(self.cutoffs)):
                l_idx, r_idx = self.cutoff_ends[i], self.cutoff_ends[i + 1]

                mask = (target >= l_idx) & (target < r_idx)
                cur_target = tf.minimum(target, r_idx-1)
                cur_target = tf.maximum(cur_target-l_idx, 0)

                cur_W = self.out_weights[i]
                cur_b = self.out_biases[i]
                cur_P = self.out_projs[i]

                if i == 0:
                    cur_W = tf.concat([cur_W, self.cluster_weight], 0)
                    cur_b = tf.concat([cur_b, self.cluster_bias], 0)

                    head_logit = self._logit(hidden, cur_W, cur_b, cur_P)
                    head_logprob = tf.nn.log_softmax(head_logit)

                    cur_loss = self._gather_logprob(head_logprob, cur_target)
                    loss = tf.where(mask, cur_loss, loss)
                else:
                    tail_logit = self._logit(hidden, cur_W, cur_b, cur_P)
                    tail_logprob = tf.nn.log_softmax(tail_logit)

                    cluster_prob_idx = self.cutoffs[0] + i - 1
                    logprob_i = head_logprob[..., cluster_prob_idx, None] + tail_logprob

                    cur_loss = self._gather_logprob(logprob_i, cur_target)
                    loss = tf.where(mask, cur_loss, loss)
            loss = -loss
        if return_mean:
            loss = tf.reduce_mean(loss)

        return loss

class TransformerXL(tf.keras.Model):
    def __init__(self, n_token, n_layer, d_model, d_embed, n_head, d_head, d_inner, \
                 dropout, dropatt, initializer, proj_initializer=None, pre_lnorm=False, tgt_len=None, \
                 mem_len=0, cutoffs=[], div_val=1, tie_projs=[], same_length=False, \
                 clamp_len=-1, untie_r=False, proj_same_dim=True, use_tpu=True):

        super(TransformerXL, self).__init__()

        self.n_token = n_token
        self.n_layer = n_layer
        self.d_model = d_model
        self.d_embed = d_embed
        self.n_head = n_head
        self.d_head = d_head
        self.d_inner = d_inner

        self.tgt_len = tgt_len
        self.mem_len = mem_len

        self.dropout = dropout
        self.dropatt = dropatt

        self.cutoffs = cutoffs
        self.div_val = div_val
        self.tie_projs = tie_projs
        self.same_length = same_length
        self.clamp_len = clamp_len
        self.untie_r = untie_r
        self.proj_same_dim = proj_same_dim

        self.initializer = initializer
        self.proj_initializer = proj_initializer if proj_initializer is not None else initializer

        self.pre_lnorm = pre_lnorm
        self.use_tpu = use_tpu

        self.embedding_layer = AdaptiveEmbedding(
                n_token=self.n_token,
                d_embed=self.d_embed,
                d_proj=self.d_model,
                cutoffs=self.cutoffs,
                initializer=self.initializer,
                proj_initializer=self.proj_initializer,
                div_val=self.div_val,
                proj_same_dim=self.proj_same_dim,
                use_tpu=self.use_tpu,
                name='emb_layer'
            )
        self.pos_emb = PositionalEmbedding(d_model)

        self.emb_dropout = tf.keras.layers.Dropout(dropout, name='emb_drop')
        self.pos_dropout = tf.keras.layers.Dropout(dropout, name='pos_drop')

        if not self.untie_r:
            self.r_w_bias = self.add_weight(
                shape=(self.n_head, self.d_head), initializer="zeros", trainable=True, name="r_w_bias"
            )
            self.r_r_bias = self.add_weight(
                shape=(self.n_head, self.d_head), initializer="zeros", trainable=True, name="r_r_bias"
            )

        self.tran_layers = []
        for i in range(self.n_layer):
            self.tran_layers.append(
                TransformerXLLayer(
                    n_head=self.n_head,
                    d_model=self.d_model,
                    d_head=self.d_head,
                    d_inner=self.d_inner,
                    dropout=self.dropout,
                    dropatt=self.dropatt,
                    initializer=self.initializer,
                    pre_lnorm=self.pre_lnorm,
                    r_w_bias=None if self.untie_r else self.r_w_bias,
                    r_r_bias=None if self.untie_r else self.r_r_bias,
                    name='layers_._{}'.format(i)
                )
            )

        self.out_dropout = tf.keras.layers.Dropout(dropout, name='out_drop')
        self.logsoftmax_layer = AdaptiveSoftmax(
                n_token=self.n_token,
                d_embed=self.d_embed,
                d_proj=self.d_model,
                cutoffs=self.cutoffs,
                tie_projs=self.tie_projs,
                initializer=self.initializer,
                proj_initializer=self.proj_initializer,
                div_val=self.div_val,
                proj_same_dim=self.proj_same_dim,
                tied_to=self.embedding_layer,
                name='softmax_layer'
            )

    def reset_length(self, tgt_len, mem_len):
        self.tgt_len = tgt_len
        self.mem_len = mem_len

    def init_mems(self, bsz, mem_len):
        mems = []
        for i in range(self.n_layer):
            empty = tf.zeros([mem_len, bsz, self.d_model])
            mems.append(empty)
        return mems

    def _update_mems(self, hids, mems):
        if mems is None:
            return None
        assert len(hids) == len(mems), "len(hids) != len(mems)"
        new_mems = []
        for i in range(len(hids)):
            cat = tf.concat([mems[i], hids[i]], axis=0)
            cat = tf.stop_gradient(cat)
            mlen = shape_list(mems[i])[0]
            if mlen > 0:
                new_mems.append(cat[-mlen:])
            else:
                shape = [mlen]+shape_list(cat)[1:]
                new_mems.append(tf.zeros(shape))
        return new_mems

    def _create_mask(self, qlen, mlen, same_length=False):
        attn_mask = tf.ones([qlen, qlen])
        mask_u = tf.linalg.band_part(attn_mask, 0, -1)
        mask_dia = tf.linalg.band_part(attn_mask, 0, 0)
        attn_mask_pad = tf.zeros([qlen, mlen])
        ret = tf.concat([attn_mask_pad, mask_u - mask_dia], 1)
        if same_length:
            mask_l = tf.linalg.band_part(attn_mask, -1, 0)
            ret = tf.concat([ret[:, :qlen] + mask_l - mask_dia, ret[:, qlen:]], 1)
        return ret

    def call(self, inp, tgt, mems=None, return_mean=False, training=False):
        # the original code for Transformer-XL used shapes [len, bsz]
        # so we transpose here from shape [bsz, len] to shape [len, bsz]
        inp = tf.transpose(inp, perm=(1, 0))
        tgt = tf.transpose(tgt, perm=(1, 0))

        qlen, bsz = shape_list(inp)

        if mems is None:
            mlen = self.mem_len
        else:
            mlen = shape_list(mems)[1]
        klen = mlen + qlen

        if mems is None:
            mems = self.init_mems(bsz, mlen)
        else:
            mems = tf.unstack(mems, axis=0)
            assert(shape_list(mems[0])[1] == bsz)
            assert(len(mems) == self.n_layer)

        attn_mask = self._create_mask(qlen, mlen, self.same_length)

        word_emb = self.embedding_layer(inp)
        d_word_emb = self.emb_dropout(word_emb, training=training)

        pos_seq = tf.range(klen - 1, -1, -1.0)
        if self.clamp_len > 0:
            pos_seq = tf.minimum(pos_seq, self.clamp_len)
        pos_emb = self.pos_emb(pos_seq)
        d_pos_emb = self.pos_dropout(pos_emb, training=training)

        core_out = d_word_emb
        hids = []
        for i, layer in enumerate(self.tran_layers):
            hids.append(core_out)

            mems_i = mems[i]
            all_out = layer([core_out, d_pos_emb, attn_mask, mems_i], training=training)
            core_out = all_out[0]
        core_out = self.out_dropout(core_out, training=training)

        new_mems = self._update_mems(hids, mems)
        new_mems = tf.stack(new_mems)

        loss = self.logsoftmax_layer([core_out, tgt], return_mean=return_mean, training=training)

        # transpose loss back to shape [bsz, len] if necessary
        if loss.shape.ndims == 2:
            loss = tf.transpose(loss, [1, 0])

        return loss, new_mems


import maya
maya.utils.loadStringResourcesForModule(__name__)

import maya.cmds as cmds
import maya.mel as mel

from maya import OpenMayaUI as omui

from PySide2.QtCore import Qt
from PySide2.QtGui import QMouseEvent, QPixmap, QIcon
from PySide2.QtWidgets import QLabel, QLineEdit, QWidget, QHBoxLayout, QPushButton, QFrame, QSizePolicy
from shiboken2 import wrapInstance

import maya.app.renderSetup.common.utils as commonUtils
import maya.app.renderSetup.model.plug as plug
from maya.app.renderSetup.model.renderLayerSwitchObservable import RenderLayerSwitchObservable
from maya.app.renderSetup.views.propertyEditor.collectionPropertyEditorStrings import kNbObjects, kOK, kSelectAll
from functools import partial

kExpandedStateString = "expandedState"

kApplyLayer = maya.stringTable['y_utils.kApplyLayer' ]
kUnapplyLayer = maya.stringTable['y_utils.kUnapplyLayer' ]
kApplyOverride = maya.stringTable['y_utils.kApplyOverride' ]
kUnapplyOverride = maya.stringTable['y_utils.kUnapplyOverride' ]

_DPI_SCALE = 1.0 if not hasattr(cmds, "mayaDpiSetting") else cmds.mayaDpiSetting(query=True, realScaleValue=True)

def dpiScale(value):
    return value * _DPI_SCALE

def updateMouseEvent(event):
    # Handles one and two button mice CMD-click and Control-click events in
    # order to make it possible to right click and middle click with those mice.
    if cmds.about(mac=True):
        numMouseButtons = cmds.mouse(mouseButtonTrackingStatus=True)
        if numMouseButtons == 1:
            if event.modifiers() & Qt.MetaModifier:
                return QMouseEvent(event.type(),
                                   event.localPos(),
                                   event.windowPos(),
                                   event.screenPos(),
                                   Qt.RightButton,
                                   event.buttons(),
                                   event.modifiers() & ~Qt.MetaModifier,
                                   event.source())
            elif int(event.buttons()) & int(Qt.LeftButton) and event.modifiers() & Qt.ControlModifier:
                return QMouseEvent(event.type(),
                                   event.localPos(),
                                   event.windowPos(),
                                   event.screenPos(),
                                   event.button(),
                                   Qt.MouseButtons(int(event.buttons())|Qt.MiddleButton&~Qt.LeftButton),
                                   event.modifiers() & ~Qt.ControlModifier,
                                   event.source())
            elif event.modifiers() & Qt.ControlModifier:
                return QMouseEvent(event.type(),
                                   event.localPos(),
                                   event.windowPos(),
                                   event.screenPos(),
                                   Qt.MiddleButton,
                                   event.buttons(),
                                   event.modifiers() & ~Qt.ControlModifier,
                                   event.source())

        elif numMouseButtons == 2:
            if event.button() == Qt.LeftButton and event.modifiers() & Qt.ControlModifier:
                return QMouseEvent(event.type(),
                                   event.localPos(),
                                   event.windowPos(),
                                   event.screenPos(),
                                   Qt.MiddleButton,
                                   event.buttons(),
                                   event.modifiers() & ~Qt.ControlModifier,
                                   event.source())
            elif int(event.buttons()) & int(Qt.LeftButton) and event.modifiers() & Qt.ControlModifier:
                return QMouseEvent(event.type(),
                                   event.localPos(),
                                   event.windowPos(),
                                   event.screenPos(),
                                   event.button(),
                                   Qt.MouseButtons(int(event.buttons())|Qt.MiddleButton&~Qt.LeftButton),
                                   event.modifiers() & ~Qt.ControlModifier,
                                   event.source())
    return event

def createPixmap(imageName, width=0, height=0):
    rawPixmap = omui.MQtUtil.createPixmap(imageName)
    if rawPixmap is None:
        raise RuntimeError("Error: image not found: " + imageName)
    pixmap = wrapInstance(long(rawPixmap), QPixmap)
    if (width != 0 and height != 0):
        return pixmap.scaled(width, height)
    return pixmap

def createIcon(iconName):
    rawIcon = omui.MQtUtil.createIcon(iconName)
    if rawIcon is None:
        raise RuntimeError("Error: icon not found: " + iconName)
    icon = wrapInstance(long(rawIcon), QIcon)
    return icon

class ProgressBar(object):

    def __init__(self):
        super(ProgressBar, self).__init__()
        self.gMainProgressBar = mel.eval('$tmp = $gMainProgressBar')
        self.progress = 0

    def stepProgressBar(self):
        delta = ((int)(100*RenderLayerSwitchObservable.getInstance().progress()) - self.progress)
        if self.gMainProgressBar and delta > 0:
            (layerName, ovrName, applying) = RenderLayerSwitchObservable.getInstance().info()
            text = kApplyLayer % layerName if layerName else kUnapplyLayer
            if ovrName:
                text += (kApplyOverride if applying else kUnapplyOverride) % ovrName
            cmds.progressBar(self.gMainProgressBar, edit=True, step=delta, status=text)
            self.progress += delta

    def createProgressBar(self):
        self.progress = 0
        if self.gMainProgressBar:
            cmds.progressBar(self.gMainProgressBar,
                                edit=True,
                                beginProgress=True,
                                isInterruptable=False,
                                status="",
                                maxValue=100)
            RenderLayerSwitchObservable.getInstance().addRenderLayerSwitchObserver(self.stepProgressBar)
            cmds.progressBar(self.gMainProgressBar, edit=True, step=1, status="") #without this progress bar is not shown (if layer has no overrides)
            self.progress = 1

    def endProgressBar(self):
        if self.gMainProgressBar:
            RenderLayerSwitchObservable.getInstance().removeRenderLayerSwitchObserver(self.stepProgressBar)
            cmds.progressBar(self.gMainProgressBar, edit=True, endProgress=True)

def setExpandedState(node, value):
    """ Sets an attribute on the node storing the expanded state of
    this node in the view. Creates it if it doesn't exist """

    # Get the plug associated with the expanded state attribute
    plugRef = commonUtils.findPlug(node, kExpandedStateString)
    if plugRef is None:
        # If it doesn't exist, we create it. It's a Plug object, Python side
        plugRef = plug.Plug.createAttribute(node, kExpandedStateString,
            kExpandedStateString, {'type': 'Bool', 'connectable': False},
            plug.kNotUndoable)
        plugRef.value = value
    else:
        # If it already exists, we set its value. It's a MPlug object, OpenMaya side
        plugRef.setBool(value)

def getExpandedState(node):
    """ Retrieves the expanded state attribute of the node """

    plugRef = commonUtils.findPlug(node, kExpandedStateString)

    # If the attribte doesn't exist, just return False
    return plugRef.asBool() if plugRef is not None else False

def browse(fileNameAttr):
    result = cmds.fileDialog2(returnFilter=1, dialogStyle=2, fileMode=1)
    if result and len(result) > 0:
        cmds.setAttr(fileNameAttr, result[0], type='string')

class NodeListView:
    def __init__(self, title):
        self.title = title
        # self.first is used for efficient selection command
        # on first selection => replace the current selection (~= clear + select)
        # on other selections => add/remove to the current selection
        self.first = True

    def show(self, names):
        self.first = True
        cmds.layoutDialog(ui=partial(self.buildViewObjects, names=names), title=self.title)

    def buildViewObjects(self, names):
        vSpc = 3
        hSpc = 10
        # Get the layoutDialog's formLayout.
        #
        form = cmds.setParent(q=True)

        # layoutDialog's are unfortunately not resizable, so hard code a size
        # here, to make sure all UI elements are visible.
        #
        layout = cmds.formLayout(form, e=True, width=500, height=500)

        nbObjects = cmds.text(label=(kNbObjects % len(names)))

        treeView = cmds.treeView(allowDragAndDrop=False, allowReparenting=False, attachButtonRight=False)
        cmds.treeView(treeView, e=True, addItem = [(name,"") for name in names], itemDblClickCommand=lambda x:False)
        cmds.treeView(treeView, e=True, selectCommand=self.selectTreeCallBack)

        selectAllBtn = cmds.button(label=kSelectAll,command=partial(self.onSelectAllButton, treeView=treeView, names=names))
        okBtn = cmds.button(label=kOK,command=partial(self.onOKButton, msg='ok'))

        cmds.formLayout(
            form, edit=True,
            attachForm=[(nbObjects,   'top',    vSpc),
                        (nbObjects,   'left',   hSpc),
                        (treeView,    'left',   hSpc),
                        (treeView,    'right',  hSpc),
                        (okBtn,       'bottom', vSpc),
                        (okBtn,       'right',  hSpc),
                        (selectAllBtn,'bottom', hSpc)],
            attachControl=[(treeView, 'top', vSpc, nbObjects),
                           (treeView, 'bottom', vSpc, okBtn),
                           (selectAllBtn, 'top', vSpc, treeView),
                           (selectAllBtn, 'right', hSpc, okBtn)])

    def onSelectAllButton(self, data, treeView, names):
        for name in names:
            cmds.treeView(treeView, e=True, selectItem=(name,1))
        cmds.select(names, noExpand=True, add=(not self.first))
        self.first = False

    def onOKButton(self, data, msg):
        cmds.layoutDialog(dismiss=msg)

    def selectTreeCallBack(self, *args):
        cmds.select(args[0], noExpand=True, add=(not self.first), deselect=(not args[1]))
        self.first = False
        return True

class LabelFieldButtonGrp(QWidget):
    '''Same as cmds.textFieldButtonGrp, but with better controls on each different widgets.
    (ex: more control on callbacks, tooltips and such).'''

    def __init__(self, label=None, text=None, placeholder=None, tooltip=None, button=None):
        super(LabelFieldButtonGrp, self).__init__()
        self._layout = QHBoxLayout()
        self.setLayout(self._layout)

        # label
        self._label = QLabel(label) if label else QLabel()
        self._layout.addWidget(self._label)

        # text field
        self._field = QLineEdit()
        if tooltip:
            self._field.setToolTip(tooltip)
        if placeholder:
            self._field.setPlaceholderText(placeholder)
        self._layout.addWidget(self._field)

        # button
        self._button = QPushButton(button) if button else QPushButton()
        self._layout.addWidget(self._button)

    @property
    def layout(self):
         return self._layout

    @property
    def label(self):
        return self._label

    @property
    def field(self):
        return self._field

    @property
    def button(self):
        return self._button

class Separator(QWidget):
    '''Same as cmds.separator(), except it allows to add a text in the middle of the separator.
    Ex: -------------- My Section --------------'''

    def __init__(self, text=None):
        super(Separator,self).__init__()

        layout = QHBoxLayout()
        self.setLayout(layout)

        def createLine():
            line = QFrame()
            line.setFrameShape(QFrame.HLine)
            return line
        layout.addWidget(createLine())
        if text:
            label = QLabel(text)
            label.setAlignment(Qt.AlignCenter)
            label.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed)
            layout.addWidget(label)
            layout.addWidget(createLine())
# ===========================================================================
# Copyright 2017 Autodesk, Inc. All rights reserved.
#
# Use of this software is subject to the terms of the Autodesk license
# agreement provided at the time of installation or download, or which
# otherwise accompanies this software in either electronic or hard copy form.
# ===========================================================================


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('trygame', '0060_memberarticle_is_good'),
    ]

    operations = [
        migrations.CreateModel(
            name='ArticleVote',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('ip', models.CharField(max_length=50, verbose_name=b'IP', blank=True)),
                ('created', models.PositiveIntegerField(default=0, verbose_name=b'\xe5\xae\x8c\xe6\x88\x90\xe6\x97\xb6\xe9\x97\xb4')),
                ('article', models.ForeignKey(related_name='votes', verbose_name=b'\xe7\x94\xa8\xe6\x88\xb7', to='trygame.MemberArticle')),
            ],
            options={
                'db_table': 'mg_article_vote',
                'verbose_name': '\u70b9\u8d5e',
                'verbose_name_plural': '\u70b9\u8d5e',
            },
            bases=(models.Model,),
        ),
    ]


# 为了 Python2 玩家们
from __future__ import print_function, division

# 第三方
import tensorflow as tf
from sklearn.metrics import confusion_matrix
import numpy as np

# 我们自己
import load

train_samples, train_labels = load._train_samples, load._train_labels
test_samples, test_labels = load._test_samples, load._test_labels

print('Training set', train_samples.shape, train_labels.shape)
print('    Test set', test_samples.shape, test_labels.shape)

image_size = load.image_size
num_labels = load.num_labels
num_channels = load.num_channels

def get_chunk(samples, labels, chunkSize):
	'''
	Iterator/Generator: get a batch of data
	这个函数是一个迭代器/生成器，用于每一次只得到 chunkSize 这么多的数据
	用于 for loop， just like range() function
	'''
	if len(samples) != len(labels):
		raise Exception('Length of samples and labels must equal')
	stepStart = 0  # initial step
	i = 0
	while stepStart < len(samples):
		stepEnd = stepStart + chunkSize
		if stepEnd < len(samples):
			yield i, samples[stepStart:stepEnd], labels[stepStart:stepEnd]
			i += 1
		stepStart = stepEnd

class Network():
	def __init__(self, train_batch_size, test_batch_size, pooling_scale):
		'''
		@num_hidden: 隐藏层的节点数量
		@batch_size：因为我们要节省内存，所以分批处理数据。每一批的数据量。
		'''
		self.batch_size = train_batch_size
		self.test_batch_size = test_batch_size

		# Hyper Parameters
		self.conv_config = []		# list of dict
		self.fc_config = []			# list of dict
		self.conv_weights = []
		self.conv_biases = []
		self.fc_weights = []
		self.fc_biases = []
		self.pooling_scale = pooling_scale
		self.pooling_stride = pooling_scale

		# Graph Related
		self.tf_train_samples = None
		self.tf_train_labels = None
		self.tf_test_samples = None
		self.tf_test_labels = None

		# 统计
		self.merged = None
		self.train_summaries = []
		self.test_summaries = []

		# 初始化
		# self.define_inputs()

		# TensorBoard Visualization

	def add_conv(self, *, patch_size, in_depth, out_depth, activation='relu', pooling=False, name):
		'''
		This function does not define operations in the graph, but only store config in self.conv_layer_config
		'''
		self.conv_config.append({
			'patch_size': patch_size,
			'in_depth': in_depth,
			'out_depth': out_depth,
			'activation': activation,
			'pooling': pooling,
			'name': name
		})
		with tf.name_scope(name):
			weights = tf.Variable(
				tf.truncated_normal([patch_size, patch_size, in_depth, out_depth], stddev=0.1), name=name+'_weights')
			biases = tf.Variable(tf.constant(0.1, shape=[out_depth]), name=name+'_biases')
			self.conv_weights.append(weights)
			self.conv_biases.append(biases)

	def add_fc(self, *, in_num_nodes, out_num_nodes, activation='relu', name):
		'''
		add fc layer config to slef.fc_layer_config
		'''
		self.fc_config.append({
			'in_num_nodes': in_num_nodes,
			'out_num_nodes': out_num_nodes,
			'activation': activation,
			'name': name
		})
		with tf.name_scope(name):
			weights = tf.Variable(tf.truncated_normal([in_num_nodes, out_num_nodes], stddev=0.1))
			biases = tf.Variable(tf.constant(0.1, shape=[out_num_nodes]))
			self.fc_weights.append(weights)
			self.fc_biases.append(biases)
			self.train_summaries.append(tf.histogram_summary(str(len(self.fc_weights))+'_weights', weights))
			self.train_summaries.append(tf.histogram_summary(str(len(self.fc_biases))+'_biases', biases))

	# should make the definition as an exposed API, instead of implemented in the function
	def define_inputs(self):
		# 这里只是定义图谱中的各种变量
		with tf.name_scope('inputs'):
			self.tf_train_samples = tf.placeholder(
				tf.float32, shape=(self.batch_size, image_size, image_size, num_channels), name='tf_train_samples'
			)
			self.tf_train_labels = tf.placeholder(
				tf.float32, shape=(self.batch_size, num_labels), name='tf_train_labels'
			)
			self.tf_test_samples = tf.placeholder(
				tf.float32, shape=(self.test_batch_size, image_size, image_size, num_channels), name='tf_test_samples'
			)

	def define_model(self):
		'''
		定义我的的计算图谱
		'''
		def model(data_flow, train=True):
			'''
			@data: original inputs
			@return: logits
			'''
			# Define Convolutional Layers
			for i, (weights, biases, config) in enumerate(zip(self.conv_weights, self.conv_biases, self.conv_config)):
				with tf.name_scope(config['name'] + '_model'):
					with tf.name_scope('convolution'):
						# default 1,1,1,1 stride and SAME padding
						data_flow = tf.nn.conv2d(data_flow, filter=weights, strides=[1, 1, 1, 1], padding='SAME')
						data_flow = data_flow + biases
						if not train:
							self.visualize_filter_map(data_flow, how_many=config['out_depth'], display_size=32//(i//2+1), name=config['name']+'_conv')
					if config['activation'] == 'relu':
						data_flow = tf.nn.relu(data_flow)
						if not train:
							self.visualize_filter_map(data_flow, how_many=config['out_depth'], display_size=32//(i//2+1), name=config['name']+'_relu')
					else:
						raise Exception('Activation Func can only be Relu right now. You passed', config['activation'])
					if config['pooling']:
						data_flow = tf.nn.max_pool(
							data_flow,
							ksize=[1, self.pooling_scale, self.pooling_scale, 1],
							strides=[1, self.pooling_stride, self.pooling_stride, 1],
							padding='SAME')
						if not train:
							self.visualize_filter_map(data_flow, how_many=config['out_depth'], display_size=32//(i//2+1)//2, name=config['name']+'_pooling')

			# Define Fully Connected Layers
			for i, (weights, biases, config) in enumerate(zip(self.fc_weights, self.fc_biases, self.fc_config)):
				if i == 0:
					shape = data_flow.get_shape().as_list()
					data_flow = tf.reshape(data_flow, [shape[0], shape[1] * shape[2] * shape[3]])
				with tf.name_scope(config['name'] + 'model'):
					data_flow = tf.matmul(data_flow, weights) + biases
					if config['activation'] == 'relu':
						data_flow = tf.nn.relu(data_flow)
					elif config['activation'] is None:
						pass
					else:
						raise Exception('Activation Func can only be Relu or None right now. You passed', config['activation'])
			return data_flow

		# Training computation.
		logits = model(self.tf_train_samples)
		with tf.name_scope('loss'):
			self.loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits, self.tf_train_labels))
			self.train_summaries.append(tf.scalar_summary('Loss', self.loss))

		# Optimizer.
		with tf.name_scope('optimizer'):
			self.optimizer = tf.train.GradientDescentOptimizer(0.0001).minimize(self.loss)

		# Predictions for the training, validation, and test data.
		with tf.name_scope('train'):
			self.train_prediction = tf.nn.softmax(logits, name='train_prediction')
		with tf.name_scope('test'):
			self.test_prediction = tf.nn.softmax(model(self.tf_test_samples, train=False), name='test_prediction')

		self.merged_train_summary = tf.merge_summary(self.train_summaries)
		self.merged_test_summary = tf.merge_summary(self.test_summaries)

	def run(self):
		'''
		用到Session
		'''
		# private function
		def print_confusion_matrix(confusionMatrix):
			print('Confusion    Matrix:')
			for i, line in enumerate(confusionMatrix):
				print(line, line[i] / np.sum(line))
			a = 0
			for i, column in enumerate(np.transpose(confusionMatrix, (1, 0))):
				a += (column[i] / np.sum(column)) * (np.sum(column) / 26000)
				print(column[i] / np.sum(column), )
			print('\n', np.sum(confusionMatrix), a)

		self.writer = tf.train.SummaryWriter('./board', tf.get_default_graph())

		with tf.Session(graph=tf.get_default_graph()) as session:
			tf.initialize_all_variables().run()

			### 训练
			print('Start Training')
			# batch 1000
			for i, samples, labels in get_chunk(train_samples, train_labels, chunkSize=self.batch_size):
				_, l, predictions, summary = session.run(
					[self.optimizer, self.loss, self.train_prediction, self.merged_train_summary],
					feed_dict={self.tf_train_samples: samples, self.tf_train_labels: labels}
				)
				self.writer.add_summary(summary, i)
				# labels is True Labels
				accuracy, _ = self.accuracy(predictions, labels)
				if i % 50 == 0:
					print('Minibatch loss at step %d: %f' % (i, l))
					print('Minibatch accuracy: %.1f%%' % accuracy)
			###

			# ### 测试
			accuracies = []
			confusionMatrices = []
			for i, samples, labels in get_chunk(test_samples, test_labels, chunkSize=self.test_batch_size):
				print('samples shape', samples.shape)
				result, summary = session.run(
					[self.test_prediction, self.merged_test_summary],
					feed_dict={self.tf_test_samples: samples}
				)
				# result = self.test_prediction.eval(feed_dict={self.tf_test_samples: samples})
				self.writer.add_summary(summary, i)
				accuracy, cm = self.accuracy(result, labels, need_confusion_matrix=True)
				accuracies.append(accuracy)
				confusionMatrices.append(cm)
				print('Test Accuracy: %.1f%%' % accuracy)
			print(' Average  Accuracy:', np.average(accuracies))
			print('Standard Deviation:', np.std(accuracies))
			print_confusion_matrix(np.add.reduce(confusionMatrices))
		###

	def accuracy(self, predictions, labels, need_confusion_matrix=False):
		'''
		计算预测的正确率与召回率
		@return: accuracy and confusionMatrix as a tuple
		'''
		_predictions = np.argmax(predictions, 1)
		_labels = np.argmax(labels, 1)
		cm = confusion_matrix(_labels, _predictions) if need_confusion_matrix else None
		# == is overloaded for numpy array
		accuracy = (100.0 * np.sum(_predictions == _labels) / predictions.shape[0])
		return accuracy, cm

	def visualize_filter_map(self, tensor, *, how_many, display_size, name):
		print(tensor.get_shape)
		filter_map = tensor[-1]
		print(filter_map.get_shape())
		filter_map = tf.transpose(filter_map, perm=[2, 0, 1])
		print(filter_map.get_shape())
		filter_map = tf.reshape(filter_map, (how_many, display_size, display_size, 1))
		print(how_many)
		self.test_summaries.append(tf.image_summary(name, tensor=filter_map, max_images=how_many))

if __name__ == '__main__':
	net = Network(train_batch_size=64, test_batch_size=500, pooling_scale=2)
	net.define_inputs()

	#
	net.add_conv(patch_size=3, in_depth=num_channels, out_depth=16, activation='relu', pooling=False, name='conv1')
	net.add_conv(patch_size=3, in_depth=16, out_depth=16, activation='relu', pooling=True, name='conv2')
	net.add_conv(patch_size=3, in_depth=16, out_depth=16, activation='relu', pooling=False, name='conv3')
	net.add_conv(patch_size=3, in_depth=16, out_depth=16, activation='relu', pooling=True, name='conv4')

	# 4 = 两次 pooling, 每一次缩小为 1/2
	# 16 = conv4 out_depth
	net.add_fc(in_num_nodes=(image_size // 4) * (image_size // 4) * 16, out_num_nodes=16, activation='relu', name='fc1')
	net.add_fc(in_num_nodes=16, out_num_nodes=10, activation=None, name='fc2')

	net.define_model()
	net.run()