import torch
import torch.nn as nn
import torch.optim as optim
import torchtext
from torchtext.datasets import SST
from torchtext.data import Field, LabelField, BucketIterator
from torchtext.vocab import Vectors, GloVe, CharNGram, FastText
import time
import torch.nn.functional as F
from network import LSTM
import argparse
import numpy as np
from losses import loss
from optimizer import create_optimizer
from engine import train, test, validate
from dataset import data_load
from plot import plot_loss_and_acc

import warnings
warnings.filterwarnings('ignore')

def get_args_parser():
    parser = argparse.ArgumentParser('CNN Training', add_help=False)
    parser.add_argument('--dataset', default='SST', type=str,
                        help='choose dataset (default: SST)')
    parser.add_argument('--batch_size', type=int, default=64)
    parser.add_argument('--epoch', type=int, default=10)
    # Optimization parameters
    parser.add_argument('--opt', default='adam', type=str, metavar='OPTIMIZER',
                        help='Optimizer (default: "adam"')
    parser.add_argument('--momentum', type=float, default=0.9, metavar='M',
                        help='SGD momentum (default: 0.9)')
    parser.add_argument('--weight_decay', type=float, default=0.0001,
                        help='weight decay (default: 0.05)')
    parser.add_argument('--lr', type=float, default=3e-4, metavar='LR',
                        help='learning rate (default: 4e-3), with total batch size 4096')
    parser.add_argument('--layer_decay', type=float, default=1.0)

    parser.add_argument('--loss', type=str, default='ce')

    parser.add_argument('--device', type=str, default='cuda')

    parser.add_argument('--exp', type=str, default='debug')

    parser.add_argument('--model', type=str, default='lstm')
    parser.add_argument('--tag', type=str, default='debug')

    parser.add_argument('--hidden_dim', type=int, default=128)
    parser.add_argument('--num_layers', type=int, default=1)
    parser.add_argument('--dropout', type=float, default=0.5)
    parser.add_argument('--pretrained', type=int, default=1)

    return parser

def main(args):
    # set up fields
    TEXT = Field(fix_length=60)
    LABEL = Field(sequential=False,dtype=torch.long)

    # make splits for data
    # DO NOT MODIFY: fine_grained=True, train_subtrees=False
    train_data, val_data, test_data = SST.splits(
    TEXT, LABEL, fine_grained=True, train_subtrees=False)

    # print information about the data
    print('train.fields', train_data.fields)
    print('len(train)', len(train_data))
    print('vars(train[0])', vars(train_data[0]))

    # build the vocabulary
    # you can use other pretrained vectors, refer to https://github.com/pytorch/text/blob/master/torchtext/vocab.py
    TEXT.build_vocab(train_data, vectors=Vectors(name='vector.txt', cache='./data'))
    LABEL.build_vocab(train_data)
    # We can also see the vocabulary directly using either the stoi (string to int) or itos (int to string) method.
    print("itos", TEXT.vocab.itos[:10])
    print("stoi", LABEL.vocab.stoi)
    print("most_common", TEXT.vocab.freqs.most_common(20))

    # print vocab information
    print('len(TEXT.vocab)', len(TEXT.vocab))
    print('TEXT.vocab.vectors.size()', TEXT.vocab.vectors.size())

    batch_size = 64
    # make iterator for splits
    train_it, val_it, test_it = BucketIterator.splits(
    (train_data, val_data, test_data), batch_size=batch_size,
    device=torch.device('cuda' if torch.cuda.is_available() else 'cpu'))

    # 初始化模型
    vocab_size = len(TEXT.vocab)
    # print(vocab_size)
    # time.sleep(100)
    embedding_dim = 300
    hidden_dim = args.hidden_dim
    output_dim = 5
    num_layers = args.num_layers
    dropout = args.dropout
    model = LSTM(vocab_size, embedding_dim, hidden_dim, output_dim, num_layers, dropout)

    # Copy the pre-trained word embeddings we loaded earlier into the embedding layer of our model.
    pretrained_embeddings = TEXT.vocab.vectors

    print(pretrained_embeddings.shape)

    # you should maintain a nn.embedding layer in your network
    if args.pretrained:
        model.embedding.weight.data.copy_(pretrained_embeddings)
        model.embedding.requires_grad = False
    # 设置训练设备
    device = torch.device(args.device)
    # 定义模型
    model = model.to(device)
    # 打印信息
    print(f"使用 {device} device")
    print(f"数据集:{args.dataset}")
    print(f"模型:{args.model}")

    # 定义代价函数
    criterion = loss(args)
    # 定义优化器
    optimizer = create_optimizer(args, model)
    # 训练
    model_trained, train_los, train_acc, val_los, val_acc = train(model=model,
                                    criterion=criterion,
                                    train_iter=train_it,
                                    val_iter=val_it,
                                    optimizer=optimizer,
                                    device=device,
                                    max_epoch=args.epoch,
                                    disp_freq=100)
    # 测试
    test(model=model,
        criterion=criterion,
        test_iter=test_it,
        device=device)

    # 模型保存
    # torch.save(model.state_dict(), 'model/my_model.pth')

    # 绘制损失和准确率图
    suffix1 = args.tag + args.dataset + '_' + args.model + '_lr' + str(args.lr) + '_' + str(args.opt) + '_wd' + str(args.weight_decay) + '_epoch' + str(args.epoch) +  '.png'
    path1 = ['los_acc/train_loss_' + suffix1, 'los_acc/train_acc_' + suffix1]
    suffix2 = args.tag + args.dataset + '_' + args.model + '_lr' + str(args.lr) + '_' + str(args.opt) + '_wd' + str(args.weight_decay) + '_epoch' + str(args.epoch) +  '.png'
    path2 = ['los_acc/val_loss_' + suffix2, 'los_acc/val_acc_' + suffix2]
    plot_loss_and_acc({'TRAIN': [train_los, train_acc]}, path1)
    plot_loss_and_acc({'VAL': [val_los, val_acc]}, path2)

if __name__ == "__main__":
    """
    Please design the initial and target state.
    """
    parser = argparse.ArgumentParser('Prombelm solver', parents=[get_args_parser()])
    args = parser.parse_args()
    main(args)


# Idea was thought of back in June of 2016 in regards to creating a way for qvpython script to easily manipulate an excel spreadsheet. After obtaining help from Vaso Vasich, this script was actually made in an effort by Vaso Vasich under the SDEP business, which is a subset of Arce Enterprises.
# 2016
# First Author: Vaso Vasich
# Second Author: David Arce

# Program is designed to make a fluid way for product to be added to an excel sheet with minimal effort in order to make it quicker to add mass amounts of product. This excel sheet is then uploaded to an ecommerce website with no changes needed.

part_types = {
    'Rocker Arms': {
        'specs': [
            'Stud Diameter(in.):',
            'Ratio:'
        ],
        'set': 16,
        'images': {
        # still need to add more
            'Ultra Pro Magnum': [
                'https://s25.postimg.org/vd6zj9x8v/ultra_pro_magnum_rocker_arms_1.jpg',
                'https://s25.postimg.org/l4eidg973/ultra_pro_magnum_rocker_arms_2.jpg'
            ],
            'Ultra Gold Aluminum': [
                'https://s25.postimg.org/k73hqu8b3/ultra_gold_rocker_arms_1.jpg'
            ],
        }
    }

}

def inven():
    import openpyxl
    from openpyxl.styles import Alignment
    wb = openpyxl.load_workbook('testSheet.xlsx')
    sheet = wb.active

    #VARIABLES
    running = True
    placer = 0
    brand = ""
    productNum = ""
    prodPrice = 0
    prodName = ""
    trackInventory = "TRUE"
    quantity = 4
    backorder1 = "FALSE"
    prodWeight = ""
    taxable= "TRUE"
    hidden = "FALSE"
    prodCategory = ""
    prodCategoryWeb = "http://sandiegoengineparts.com/t/"
    prodBrandWeb = "http://sandiegoengineparts.com/t/"
    prodNameWeb = "http://sandiegoengineparts.com/products?keywords="
    prodImageUrl = ""
    imageIndex = 0

    while(running):
        question = input("New Product to add! \n Is new product similar to last? y or n: ")
        if(question == 'y'):
            placer = int(placer)
            placer += 1
            placer = str(placer)
            productNum = input("Part #: ")
            prodPrice = float(input("Price: "))
            prodPrice = round(prodPrice,2)
            imageIndex = checkImages(part_types[prodType]['images'][prodLine], prodType, imageIndex)
            prodImageUrl = part_types[prodType]['images'][prodLine][imageIndex]
            imageIndex += 1
            sheet['A'+placer].alignment = Alignment(wrapText=True)
            sheet['A'+placer].value = prodName + " " + productNum
            sheet['B'+placer].alignment = Alignment(wrapText=True)
            sheet['B'+placer].value = productNum
            sheet['C'+placer].alignment = Alignment(wrapText=True)
            sheet['C'+placer].value = prodPrice
            sheet['F'+placer].alignment = Alignment(wrapText=True)
            sheet['F'+placer].value = trackInventory
            sheet['G'+placer].alignment = Alignment(wrapText=True)
            sheet['G'+placer].value = quantity
            sheet['H'+placer].alignment = Alignment(wrapText=True)
            sheet['H'+placer].value = backorder1
            appliesTo = applies()
            prodSpecs = getSpecifications(prodType)
            sheet['E'+placer].alignment = Alignment(wrapText=True)
            sheet['E'+placer].value ="""

{1} {2} Specifications

Brand: {3}

Manufacturer's Part Number: {1}

Part Type: {2}

Product Line: {0}

    {9}

Sold in Set of {4}

Applies to:

{5}

""".format(prodName,productNum,prodType,prodBrand,prodSet,appliesTo,prodBrandWeb,prodCategoryWeb,prodNameWeb,prodSpecs)

            sheet['I'+placer].alignment = Alignment(wrapText=True)
            sheet['I'+placer].value = prodWeight
            sheet['J'+placer].alignment = Alignment(wrapText=True)
            sheet['J'+placer].value = taxable
            sheet['K'+placer].alignment = Alignment(wrapText=True)
            sheet['K'+placer].value = hidden
            sheet['L'+placer].alignment = Alignment(wrapText=True)
            sheet['L'+placer].value = prodCategory
            sheet['M'+placer].alignment = Alignment(wrapText=True)
            sheet['M'+placer].value = prodImageUrl
            sheet['N'+placer].alignment = Alignment(wrapText=True)
            sheet['N'+placer].value = prodName + " " + productNum
            sheet['O'+placer].alignment = Alignment(wrapText=True)
            sheet['O'+placer].value = "Find " + prodName + " " + productNum +" at San Diego Engine Parts where high quality engine parts meet low costs."
            wb.save('testSheet.xlsx')

        # New Product
        else:
            if(question == 'n'):
                prodType = input("Type of Part(eg. Rocker Arms): ")
                # If (prodType in part_types) do all this...don't need check necessarily now
                prodBrand = input("Brand (eg. COMP Cams): ")
                prodLine = input("Product Line (eg. Ultra Pro Magnum): ")
                productNum = input("Part #: ")
                prodCategory = makeCategories(prodType, prodBrand)

                prodCategoryWeb += prodType.replace(' ', '-').lower()
                # prodCategoryWeb += input("Type of Part URL: ")
                prodBrandWeb += prodBrand.replace(' ', '-').lower()
                # prodBrandWeb += input("Brand URL: ")
                prodName = prodBrand + ' ' + prodLine + ' ' + prodType
                # prodName = input("(Brand - Product Line - Type): ")
                prodNameWeb += prodName.replace(' ', '+').lower()
                # prodNameWeb += input("Product Line URL: ")
                prodWeight = int(input("Weight: "))
                prodSet = part_types[prodType]['set']
                placer = input("Row: ")
                # prodRAdiameter = input("Diameter: ")
                # prodRAratio = input("Ratio: ")
                prodPrice = float(input("Price: "))
                prodPrice = round(prodPrice,2)
                if (prodLine in part_types[prodType]['images']):
                    prodImageUrl = part_types[prodType]['images'][prodLine][0]
                    imageIndex += 1
                else:
                    print('No Image was found for ' + prodLine)
                # prodImageUrl = input("Image Url: ")
                sheet['A'+placer].alignment = Alignment(wrapText=True)
                sheet['A'+placer].value = prodName + " " + productNum
                sheet['B'+placer].alignment = Alignment(wrapText=True)
                sheet['B'+placer].value = productNum
                sheet['C'+placer].alignment = Alignment(wrapText=True)
                sheet['C'+placer].value = prodPrice
                sheet['F'+placer].alignment = Alignment(wrapText=True)
                sheet['F'+placer].value = trackInventory
                sheet['G'+placer].alignment = Alignment(wrapText=True)
                sheet['G'+placer].value = quantity
                sheet['H'+placer].alignment = Alignment(wrapText=True)
                sheet['H'+placer].value = backorder1
                # running = True
                appliesTo = applies()
                prodSpecs = getSpecifications(prodType)
                sheet['E'+placer].alignment = Alignment(wrapText=True)
                sheet['E'+placer].value = """

{1} {2} Specifications

Brand: {3}

Manufacturer's Part Number: {1}

Part Type: {2}

Product Line: {0}

    {9}

Sold in Set of {4}

Applies to:

{5}

""".format(prodName,productNum,prodType,prodBrand,prodSet,appliesTo,prodBrandWeb,prodCategoryWeb,prodNameWeb,prodSpecs)
# .format(prodName,productNum,prodType,prodBrand,prodSet,appliesTo,prodBrandWeb,prodCategoryWeb,prodNameWeb,prodRAratio,prodRAdiameter)

                sheet['I'+placer].alignment = Alignment(wrapText=True)
                sheet['I'+placer].value = prodWeight
                sheet['J'+placer].alignment = Alignment(wrapText=True)
                sheet['J'+placer].value = taxable
                sheet['K'+placer].alignment = Alignment(wrapText=True)
                sheet['K'+placer].value = hidden
                sheet['L'+placer].alignment = Alignment(wrapText=True)
                sheet['L'+placer].value = prodCategory
                sheet['M'+placer].alignment = Alignment(wrapText=True)
                sheet['M'+placer].value = prodImageUrl
                sheet['N'+placer].alignment = Alignment(wrapText=True)
                sheet['N'+placer].value = prodName + " " + productNum
                sheet['O'+placer].alignment = Alignment(wrapText=True)
                sheet['O'+placer].value = "Find " + prodName + " " + productNum +" at San Diego Engine Parts where high quality engine parts meet low costs."
                wb.save('testSheet.xlsx')
            else:
              if(question == 'x'):
                running = False
        wb.save('testSheet.xlsx')

def applies():
    running = True
    appliesTo = ""
    while(running):
        question = input("Continue adding Applies to? y or n: ")
        if(question == 'y'):
            appliesTo = appliesTo + '
' + input("Applies to: ") + '
\n'
        else:
            if(question == 'n'):
                return appliesTo

def getSpecifications(product_type):
    running = True
    prodSpecs = ""
    while(running):
        for k in part_types[product_type]['specs']:
            v = input('Get ' + k)
            prodSpecs += '
' + k + ' ' + v + '
\n'
        return prodSpecs

def makeCategories(product_type, product_brand):
    categories = product_type + ', Brands/' + product_brand + ', Brands/' + product_brand + '/' + product_brand + ' ' + product_type
    return categories

def checkImages(product_line, product_type, index):
    imageGroupLength = len(part_types[product_type]['images'])
    if (imageGroupLength == 1):
        index = 0
        return index
    else:
        if (index < imageGroupLength):
            return index
        else:
            index = 0
            return index

inven()


# coding: utf-8

from traitlets import Type, Instance, default
from .baseapp import NbGrader
from ..plugins import ExportPlugin, CsvExportPlugin
from ..api import Gradebook

aliases = {
    'log-level' : 'Application.log_level',
    'db': 'CourseDirectory.db_url',
    'to' : 'ExportPlugin.to',
    'exporter': 'ExportApp.plugin_class',
    'assignment' : 'ExportPlugin.assignment',
    'student': 'ExportPlugin.student',
    'course': 'CourseDirectory.course_id'
}
flags = {}

class ExportApp(NbGrader):

    name = u'nbgrader-export'
    description = u'Export information from the database to another format.'

    aliases = aliases
    flags = flags

    examples = """

        The default is to export to a file called "grades.csv", i.e.:

            nbgrader export

        You can customize the filename with the --to flag:

            nbgrader export --to mygrades.csv

        You can export the grades for a single (or limited set) of students
        or assignments with the --assignment and/or --student flag:

            nbgrader export --assignment [assignmentID]
                            --student [studentID1,studentID2]

        Where the studentIDs and assignmentIDs are a list of IDs and
        assignments. The assignments or studentIDs need to quoted if they
        contain not only numbers. The square brackets are obligatory.

        To change the export type, you will need a class that inherits from
        nbgrader.plugins.ExportPlugin. If your exporter is named
        `MyCustomExporter` and is saved in the file `myexporter.py`, then:

            nbgrader export --exporter=myexporter.MyCustomExporter

        """

    plugin_class = Type(
        CsvExportPlugin,
        klass=ExportPlugin,
        help="The plugin class for exporting the grades."
    ).tag(config=True)

    plugin_inst = Instance(ExportPlugin).tag(config=False)

    def init_plugin(self):
        self.log.info("Using exporter: %s", self.plugin_class.__name__)
        self.plugin_inst = self.plugin_class(parent=self)

    @default("classes")
    def _classes_default(self):
        classes = super(ExportApp, self)._classes_default()
        classes.append(ExportApp)
        classes.append(ExportPlugin)
        return classes

    def start(self):
        super(ExportApp, self).start()
        self.init_plugin()
        with Gradebook(self.coursedir.db_url, self.coursedir.course_id) as gb:
            self.plugin_inst.export(gb)


# dash_callbacks.py

from dash.dependencies import Input, Output
from dashboard.dash_app import app
from dashboard.dash_aux import get_pending_html_table
from session.sc_helpers import QuitMode
from dashboard.sc_df_manager import DataframeManager
from binance import enums as k_binance
from datetime import datetime, timedelta
from basics.sc_perfect_trade import PerfectTradeStatus
from basics.sc_asset import Asset

print('dash_callbacks.py')

dfm = DataframeManager()

# first line data
@app.callback(Output('current-time', 'children'),
              Output('neb', 'children'),  # perfect trade net profit
              Output('qty', 'children'),  # orders quantity
              Output('target', 'children'),  # session target net profit
              Output('max-negative-profit-allowed', 'children'),  # if reached, session ended at price
              Input('update', 'n_intervals'))
def display_value(value):
    symbol_name = dfm.dashboard_active_symbol.name
    quote_name = dfm.dashboard_active_symbol.quote_asset().name()
    base_name = dfm.dashboard_active_symbol.base_asset().name()

    return \
        f'{datetime.now().strftime("%H:%M:%S")}',\
        f'n: {dfm.sm.active_sessions[symbol_name].P_NET_QUOTE_BALANCE:,.2f} {quote_name}',\
        f'q: {dfm.sm.active_sessions[symbol_name].P_QUANTITY:,.4f} {base_name}',\
        f't: {dfm.sm.active_sessions[symbol_name].checks_manager.P_TARGET_TOTAL_NET_PROFIT:,.2f} {quote_name}',\
        f'({dfm.sm.active_sessions[symbol_name].checks_manager.P_MAX_NEGATIVE_PROFIT_ALLOWED:,.2f})'

# **********************************
# ********** Session data **********
# **********************************

# elapsed time
@app.callback(Output('session-count', 'children'),
              Output('session-cycle-count', 'children'),
              Input('update', 'n_intervals'))
def display_value(value):
    symbol_name = dfm.dashboard_active_symbol.name
    return f'#{dfm.sm.session_count[symbol_name]:03d}', \
           f'{timedelta(seconds=dfm.sm.active_sessions[symbol_name].cmp_count)}'

# perfect trade status info
@app.callback(Output('pt-new', 'children'),
              Output('pt-buy', 'children'),
              Output('pt-sell', 'children'),
              Output('pt-end', 'children'),
              Input('update', 'n_intervals'))
def display_value(value):
    symbol_name = dfm.dashboard_active_symbol.name
    ptm = dfm.sm.active_sessions[symbol_name].ptm
    return \
        len(ptm.get_pt_by_request(pt_status=[PerfectTradeStatus.NEW])),\
        len(ptm.get_pt_by_request(pt_status=[PerfectTradeStatus.BUY_TRADED])),\
        len(ptm.get_pt_by_request(pt_status=[PerfectTradeStatus.SELL_TRADED])),\
        len(ptm.get_pt_by_request(pt_status=[PerfectTradeStatus.COMPLETED]))

# span, depth, momentum & TBD data
@app.callback(Output('pt-span', 'children'),
              Output('pt-span-buy', 'children'),
              Output('pt-span-sell', 'children'),
              Output('pt-depth', 'children'),
              Output('pt-depth-buy', 'children'),
              Output('pt-depth-sell', 'children'),
              Output('pt-mtm', 'children'),
              Output('pt-mtm-buy', 'children'),
              Output('pt-mtm-sell', 'children'),
              Input('update', 'n_intervals'))
def display_value(value):
    session_orders = dfm.get_session_orders()

    symbol_name = dfm.dashboard_active_symbol.name
    active_session = dfm.sm.active_sessions[symbol_name]
    cmp = active_session.cmp
    gap = active_session.gap

    buy_gap_span, sell_gap_span = active_session.helpers.get_gap_span_from_list(orders=session_orders, cmp=cmp, gap=gap)
    total_gap_span = buy_gap_span + sell_gap_span
    buy_gap_depth, sell_gap_depth = active_session.helpers.get_gap_depth_from_list(orders=session_orders, cmp=cmp, gap=gap)
    total_gap_depth = buy_gap_depth + sell_gap_depth
    buy_gap_momentum, sell_gap_momentum = active_session.helpers.get_gap_momentum_from_list(orders=session_orders, cmp=cmp, gap=gap)
    total_gap_momentum = buy_gap_momentum + sell_gap_momentum
    return \
        f'{total_gap_span:.2f}', \
        f'{buy_gap_span:.2f}', \
        f'{sell_gap_span:.2f}', \
        f'{total_gap_depth:.2f}', \
        f'{buy_gap_depth:.2f}', \
        f'{sell_gap_depth:.2f}', \
        f'{total_gap_momentum:.2f}', \
        f'{buy_gap_momentum:.2f}', \
        f'{sell_gap_momentum:.2f}'

# ********** Session STOP profits **********
@app.callback(Output('actual-profit', 'children'),
              Output('stop-price-profit', 'children'),
              Output('ntc', 'children'),
              Output('time-to-next-try', 'children'),
              Output('is-active', 'children'),
              Input('update', 'n_intervals'))
def display_value(value):
    symbol = dfm.dashboard_active_symbol
    symbol_name = symbol.name
    cmp = dfm.sm.active_sessions[symbol_name].cmp
    qp = symbol.quote_asset().pv()
    base_ntc = dfm.sm.active_sessions[symbol_name].checks_manager.base_negative_try_count
    quote_ntc = dfm.sm.active_sessions[symbol_name].checks_manager.quote_negative_try_count

    cycles_count_for_inactivity = dfm.sm.active_sessions[symbol_name].cycles_count_for_inactivity
    cycles_to_new_pt = cycles_count_for_inactivity - dfm.sm.active_sessions[symbol_name].cycles_from_last_trade
    cycles_to_new_pt = 0.0 if cycles_to_new_pt < 0 else cycles_to_new_pt
    time_to_next_try = timedelta(seconds=cycles_to_new_pt)

    is_active = 'ON' if dfm.sm.active_sessions[symbol_name].is_active else 'OFF'

    return f'{dfm.sm.active_sessions[symbol_name].ptm.get_total_actual_profit_at_cmp(cmp=cmp):,.{qp}f}',\
           f'{dfm.sm.active_sessions[symbol_name].ptm.get_stop_price_profit(cmp=cmp):,.{qp}f}', \
           f'{base_ntc} - {quote_ntc}', \
           f'{time_to_next_try}', \
           f'{is_active}'

# @app.callback(Output('cycles-to-new-pt', 'children'), Input('update', 'n_intervals'))
# def display_value(value):
#     symbol_name = dfm.dashboard_active_symbol.name
#     cycles_count_for_inactivity = dfm.sm.active_sessions[symbol_name].cycles_count_for_inactivity
#     cycles_to_new_pt = cycles_count_for_inactivity - dfm.sm.active_sessions[symbol_name].cycles_from_last_trade
#     time_to_new_pt = timedelta(seconds=cycles_to_new_pt)
#     return f'({cycles_count_for_inactivity})  {time_to_new_pt}'

# **********************************
# ********** Global data **********
# **********************************

# ********** Global elapsed time **********
@app.callback(Output('global-cycle-count', 'children'), Input('update', 'n_intervals'))
def display_value(value):
    symbol_name = dfm.dashboard_active_symbol.name
    global_cmp = dfm.sm.terminated_sessions[symbol_name]["global_cmp_count"]
    session_cmp = dfm.sm.active_sessions[symbol_name].cmp_count
    return f'{timedelta(seconds=global_cmp + session_cmp)}'

# isolated orders info
@app.callback(
    Output('isol-orders-placed', 'children'),
    Output('isol-orders-pending', 'children'),
    Output('isol-orders-pending-buy', 'children'),
    Output('isol-orders-pending-sell', 'children'),
    Input('update', 'n_intervals'))
def display_value(value):
    symbol_name = dfm.dashboard_active_symbol.name

    placed = dfm.sm.terminated_sessions[symbol_name]['global_placed_orders_count_at_price']
    sell = len(
        [order for order in dfm.sm.iom.isolated_orders
         if order.k_side == k_binance.SIDE_SELL and order.symbol.name == symbol_name])
    buy = len(
        [order for order in dfm.sm.iom.isolated_orders
         if order.k_side == k_binance.SIDE_BUY and order.symbol.name == symbol_name])
    pending = buy + sell
    return placed, pending, buy, sell

# Global span, depth, momentum & TBD data
@app.callback(Output('is-span', 'children'),
              Output('is-span-buy', 'children'),
              Output('is-span-sell', 'children'),
              Output('is-depth', 'children'),
              Output('is-depth-buy', 'children'),
              Output('is-depth-sell', 'children'),
              Output('is-mtm', 'children'),
              Output('is-mtm-buy', 'children'),
              Output('is-mtm-sell', 'children'),
              Input('update', 'n_intervals'))
def display_value(value):
    all_orders = dfm.get_all_orders()

    symbol_name = dfm.dashboard_active_symbol.name
    active_session = dfm.sm.active_sessions[symbol_name]
    cmp = active_session.cmp
    gap = active_session.gap

    buy_gap_span, sell_gap_span = active_session.helpers.get_gap_span_from_list(orders=all_orders, cmp=cmp, gap=gap)
    total_gap_span = buy_gap_span + sell_gap_span
    buy_gap_depth, sell_gap_depth = active_session.helpers.get_gap_depth_from_list(orders=all_orders, cmp=cmp, gap=gap)
    total_gap_depth = buy_gap_depth + sell_gap_depth
    buy_gap_momentum, sell_gap_momentum = \
        active_session.helpers.get_gap_momentum_from_list(orders=all_orders, cmp=cmp, gap=gap)
    total_gap_momentum = buy_gap_momentum + sell_gap_momentum
    return \
        f'{total_gap_span:.2f}',\
        f'{buy_gap_span:.2f}',\
        f'{sell_gap_span:.2f}', \
        f'{total_gap_depth:.2f}', \
        f'{buy_gap_depth:.2f}', \
        f'{sell_gap_depth:.2f}', \
        f'{total_gap_momentum:.2f}', \
        f'{buy_gap_momentum:.2f}', \
        f'{sell_gap_momentum:.2f}'

# ********** Global STOP profits **********
@app.callback(Output('consolidated-profit', 'children'),
              Output('expected-profit-at-cmp', 'children'),
              Output('expected-profit', 'children'),
              Output('actions-info', 'children'),
              Output('actions-rate', 'children'),
              Output('canceled-count', 'children'),
              Input('update', 'n_intervals'))
def display_value(value):
    symbol = dfm.dashboard_active_symbol
    symbol_name = symbol.name
    cmp = dfm.sm.active_sessions[symbol_name].cmp  # s[-1]
    qp = symbol.quote_asset().pv()
    # coin_symbol = symbol.quote_asset().name()
    # called the method in session to check buy_count == sell_count
    consolidated = dfm.sm.terminated_sessions[symbol_name]['global_consolidated_profit']
    expected = dfm.sm.terminated_sessions[symbol_name]['global_expected_profit']
    expected_at_cmp = dfm.sm.iom.get_expected_profit_at_cmp(cmp=cmp, symbol_name=symbol_name)
    buy_actions_count, sell_actions_count, actions_balance = \
        dfm.sm.active_sessions[symbol_name].checks_manager.get_actions_balance()
    buy_actions_rate = consolidated / (buy_actions_count +1)
    sell_actions_rate = consolidated / (sell_actions_count +1)
    canceled_buy_orders = [order for order in dfm.sm.iom.canceled_orders if order.k_side == k_binance.SIDE_BUY]
    canceled_sell_orders = [order for order in dfm.sm.iom.canceled_orders if order.k_side == k_binance.SIDE_SELL]

    if consolidated + expected_at_cmp > 100.0:
        global_cmp = dfm.sm.terminated_sessions[symbol_name]["global_cmp_count"]
        session_cmp = dfm.sm.active_sessions[symbol_name].cmp_count
        raise Exception(f'TARGET ACHIEVED!!! in {timedelta(seconds=global_cmp + session_cmp)}'
                        f' DONE: {consolidated} ACTUAL AL CMP: {expected_at_cmp}')

    return f'{consolidated:,.{qp}f}',\
           f'{expected_at_cmp:,.{qp}f}',\
           f'{expected:,.{qp}f}', \
           f'{buy_actions_count}/{sell_actions_count} {actions_balance:,.2f}', \
           f'{buy_actions_rate:,.0f} / {sell_actions_rate:,.0f}', \
           f'{len(canceled_buy_orders)} / {len(canceled_sell_orders)}'

# ********** PT count / traded orders count **********
# @app.callback(Output('trade-info', 'children'), Input('update', 'n_intervals'))
# def display_value(value):
#     symbol_name = dfm.dashboard_active_symbol.name
#     pt_count = len(dfm.sm.active_sessions[symbol_name].ptm.perfect_trades)
#     buy_count = dfm.sm.active_sessions[symbol_name].buy_count
#     sell_count = dfm.sm.active_sessions[symbol_name].sell_count
#     return f'pt: {pt_count}   b: {buy_count}   s: {sell_count}'

# @app.callback(Output('short-prediction', 'children'),
#               Output('long-prediction', 'children'),
#               Input('update', 'n_intervals'))
# def display_value(value):
#     symbol_name = dfm.dashboard_active_symbol.name
#     session = dfm.sm.active_sessions[symbol_name]
#     short_prediction = session.strategy_manager.get_tendency(session.cmp_pattern_short) - session.cmp
#     long_prediction = session.strategy_manager.get_tendency(session.cmp_pattern_long) - session.cmp
#     return f'short: {short_prediction:,.0f}', f'long: {long_prediction:,.0f}'

# @app.callback(Output('accounts-info', 'children'), Input('update', 'n_intervals'))
# def display_value(value):
#     accounts_info = [f'{account.name}: {account.free:,.2f} ' for account in dfm.sm.am.accounts.values()]
#     accounts_info_s = ' '.join(map(str, accounts_info))
#     return accounts_info_s

# ********** symbol & accounts data **********
@app.callback(
    Output('symbol', 'children'),
    Output('cmp-max', 'children'),
    Output('cmp', 'children'),
    Output('cmp-min', 'children'),
    Output('base-asset', 'children'),
    Output('base-asset-locked', 'children'),
    Output('base-asset-alive', 'children'),
    Output('base-asset-free', 'children'),
    Output('base-asset-total', 'children'),
    Output('quote-asset', 'children'),
    Output('quote-asset-locked', 'children'),
    Output('quote-asset-alive', 'children'),
    Output('quote-asset-free', 'children'),
    Output('quote-asset-total', 'children'),
    Output('bnb-locked', 'children'),
    Output('bnb-alive', 'children'),
    Output('bnb-free', 'children'),
    Output('bnb-total', 'children'),
    Input('update', 'n_intervals')
)
def display_value(value):
    symbol = dfm.dashboard_active_symbol
    symbol_name = symbol.name
    # am = dfm.sm.active_sessions[symbol_name].am
    am = dfm.sm.am
    base_account = am.get_account(symbol.base_asset().name())
    quote_account = am.get_account(symbol.quote_asset().name())
    bnb_account = am.get_account('BNB')
    quote_pv = symbol.quote_asset().pv()

    base_alive = dfm.sm.get_liquidity_for_alive_orders(asset=symbol.base_asset())
    quote_alive = dfm.sm.get_liquidity_for_alive_orders(asset=symbol.quote_asset())
    bnb_alive = dfm.sm.get_liquidity_for_alive_orders(asset=Asset(name='BNB', pv=6))
    # bnb_alive = 1.0

    return \
        symbol_name, \
        f'{dfm.sm.active_sessions[symbol_name].max_cmp:,.{quote_pv}f}', \
        f'{dfm.sm.active_sessions[symbol_name].cmp:,.{quote_pv}f}', \
        f'{dfm.sm.active_sessions[symbol_name].min_cmp:,.{quote_pv}f}', \
        symbol.base_asset().name(),\
        f'{base_account.locked:,.{symbol.base_asset().pv()}f}', \
        f'{base_alive:,.{symbol.base_asset().pv()}f}', \
        f'{base_account.free - base_alive:,.{symbol.base_asset().pv()}f}', \
        f'{base_account.get_total():,.{symbol.base_asset().pv()}f}', \
        symbol.quote_asset().name(), \
        f'{quote_account.locked:,.{symbol.quote_asset().pv()}f}', \
        f'{quote_alive:,.{symbol.quote_asset().pv()}f}', \
        f'{quote_account.free - quote_alive:,.{symbol.quote_asset().pv()}f}',\
        f'{quote_account.get_total():,.{symbol.quote_asset().pv()}f}',\
        f'{bnb_account.locked:,.6f}',\
        f'{bnb_alive:,.6f}', \
        f'{bnb_account.free - bnb_alive:,.6f}', \
        f'{bnb_account.get_total():,.6f}'

# ********** alert message **********
@app.callback(Output('alert-msg', 'children'),
              Input('update', 'n_intervals'))
def display_value(value):
    symbol = dfm.dashboard_active_symbol

    # check bnb liquidity and raise ALERT
    bnb_liquidity = dfm.sm.active_sessions[symbol.name].am.get_account('BNB').free
    if bnb_liquidity < 1.0:
        return f'BNB LIQUIDITY ALERT {bnb_liquidity:,.6f}'
    else:
        return ''

# ********** symbol selection buttons *********
@app.callback(Output('button-symbols', 'children'),
              Input('button-symbols', 'n_clicks'),
              )
def on_button_click(n):
    # set BTCEUR as active symbol if button pressed
    current_symbol_name = dfm.dashboard_active_symbol.name
    if n is not None:
        next_symbol = dfm.get_next_symbol(symbol_name=current_symbol_name)
        dfm.set_dashboard_active_symbol(symbol_name=next_symbol)
        return next_symbol
    else:
        return current_symbol_name

# Stop buttons
@app.callback(Output('button-stop-cmp', 'children'), Input('button-stop-cmp', 'n_clicks'))
def on_button_click(n):
    if n is not None:
        symbol = dfm.dashboard_active_symbol
        symbol_name = symbol.name
        session = dfm.sm.active_sessions[symbol_name]
        session.helpers.quit_particular_session(
            quit_mode=QuitMode.TRADE_ALL_PENDING,
            session_id=session.session_id,
            symbol=session.symbol,
            cmp=session.cmp,
            iom=session.iom,
            cmp_count=session.cmp_count)

    return 'STOP-CMP'

@app.callback(Output('button-stop-price', 'children'), Input('button-stop-price', 'n_clicks'))
def on_button_click(n):
    if n is not None:
        symbol = dfm.dashboard_active_symbol
        symbol_name = symbol.name
        session = dfm.sm.active_sessions[symbol_name]
        session.helpers.quit_particular_session(
            quit_mode=QuitMode.PLACE_ALL_PENDING,
            session_id=session.session_id,
            symbol=session.symbol,
            cmp=session.cmp,
            iom=session.iom,
            cmp_count=session.cmp_count)

    return 'STOP-PRICE'

@app.callback(Output('button-stop-cancel', 'children'), Input('button-stop-cancel', 'n_clicks'))
def on_button_click(n):
    if n is not None:
        symbol = dfm.dashboard_active_symbol
        symbol_name = symbol.name
        session = dfm.sm.active_sessions[symbol_name]
        session.helpers.quit_particular_session(
            quit_mode=QuitMode.CANCEL_ALL,
            session_id=session.session_id,
            symbol=session.symbol,
            cmp=session.cmp,
            iom=session.iom,
            cmp_count=session.cmp_count)
    return 'STOP-CANCEL'

@app.callback(Output('button-reboot-global-session', 'children'), Input('button-reboot-global-session', 'n_clicks'))
def on_button_click(n):
    if n is not None:
        # as first step, perform STOP-PRICE actions
        symbol = dfm.dashboard_active_symbol
        symbol_name = symbol.name
        for session in dfm.sm.active_sessions.values():
            # session = dfm.sm.active_sessions[symbol_name]
            session.helpers.quit_particular_session(
                quit_mode=QuitMode.PLACE_ALL_PENDING,
                session_id=session.session_id,
                symbol=session.symbol,
                cmp=session.cmp,
                iom=session.iom,
                cmp_count=session.cmp_count)

        # finish app ans it will cause a gunicorn workers reboot (reset-like app)
        dfm.sm.reboot_global_session()
    return 'REBOOT-SESSION'

@app.callback(Output('button-new-pt', 'children'), Input('button-new-pt', 'n_clicks'))
def on_button_click(n):
    if n:
        symbol = dfm.dashboard_active_symbol
        symbol_name = symbol.name
        dfm.sm.active_sessions[symbol_name].manually_create_new_pt()
    return 'NEW-PT'

@app.callback(Output('button-increase-cmp', 'children'), Input('button-increase-cmp', 'n_clicks'))
def on_button_click(n):
    if n:
        symbol_name = dfm.dashboard_active_symbol.name
        dfm.sm.client_manager.on_button_step(symbol_name=symbol_name, step=10.0)
    return '+ 10.0 €'

@app.callback(Output('button-decrease-cmp', 'children'), Input('button-decrease-cmp', 'n_clicks'))
def on_button_click(n):
    if n:
        symbol_name = dfm.dashboard_active_symbol.name
        dfm.sm.client_manager.on_button_step(symbol_name=symbol_name, step=-10.0)
    return '- 10.0 €'

# ********** others **********
@app.callback(
    Output('new-table', 'children'),
    Input('update', 'n_intervals')
)
def update_table(timer):
    df = dfm.get_all_orders_df_with_cmp()
    # sort by price
    df1 = df.sort_values(by=['price'], ascending=False)
    # filter by status for each table (monitor-placed & traded)
    df_pending = df1[df1.status.isin(['monitor', 'active', 'cmp', 'to_be_traded', 'canceled'])]
    qp = dfm.dashboard_active_symbol.quote_asset().pv()
    df_pending['price'] = df_pending['price'].map(f'{{:,.{qp}f}}'.format)  # two {{ }} to escape { in f-string
    df_pending['total'] = df_pending['total'].map(f'{{:,.{qp}f}}'.format)

    return get_pending_html_table(df=df_pending[['pt_id', 'name', 'price', 'amount', 'total', 'status']])


import argparse
import os
import pickle
from datetime import datetime, timedelta
from matplotlib.dates import YearLocator, DateFormatter, MonthLocator

import numpy
from matplotlib import pyplot as plt
from pandas.io.data import get_data_yahoo

class Investor(object):
    """Represents a single investor with initial cash, income, and
    set buy/sell thresholds.

    :param buy_at   float   if the pe ratio is less than or equal to this
      value, the investor will buy all the shares she can
    :param sell_at  float   if the pe ratio is greater than this value, the
      investor will sell all her shares (if any)
    :param init_cash float  initial cash
    :param shares   float   initial shares
    :param income   float   cash increase on call to `get_paid`

    """
    def __init__(self, buy_at, sell_at=None, init_cash=10000., shares=0.,
                 income=2000.):
        self.buy_at = buy_at
        if sell_at is None:
            sell_at = buy_at
        self.sell_at = sell_at
        self.init_cash = self.cash = init_cash
        self.shares = shares
        self.income = income

    def get_paid(self):
        """Receive the income"""
        self.cash += self.income

    def get_net_worth(self, market_price):
        """Total net worth is cash + worth of shares"""
        return self.cash + self.shares * market_price

    def sell_all(self, market_price):
        """Convert all stocks to cash"""
        self.cash += market_price * self.shares
        self.shares = 0.

    def buy_all(self, market_price):
        """Buy all shares I can afford"""
        self.shares += self.cash / market_price
        self.cash = 0.

    def react_to_pe(self, pe_ratio, market_price):
        """React to P/E depending on investor thresholds (buy, sell, or hold)

        """
        if self.shares and pe_ratio > self.sell_at:
            self.sell_all(market_price)
        elif self.cash and pe_ratio <= self.buy_at:
            self.buy_all(market_price)

class CapeValidator(object):
    """
    Compares the performance of a suite of investors with different buy/sell
    thresholds for CAPE ratio.

    :param pe_data_file str csv of pe_data. TODO: write script to download
    :param start_date   datetime    datetime at which to start analysis
    :param buy_thresholds   [float, ...]    list of buy thresholds for suite
        of investors. Each entry will instantiate a new investor.
    :param sell_thresholds [float, ...]     list of sell thresholds
        corresponding to `buy_thresholds`. If None, will be equal to
        `buy_thresholds`.
    :param end_date datetime    datetime at which to stop analysis. If None,
        will go to current day.
    :param index    str     stock symbol of index to invest in.

    """
    def __init__(self, pe_data_file, start_date, buy_thresholds,
                 sell_thresholds=None, end_date=None, index='^GSPC'):
        if sell_thresholds is None:
            sell_thresholds = [None] * len(buy_thresholds)
        if len(buy_thresholds) != len(sell_thresholds):
            raise RuntimeError("Buy and Sell Thresholds must be equal length")
        if end_date is None:
            end_date = datetime.now()
        self.investors = []
        self.pe_array = []
        self.index = index
        self.index_cache = {}

        self.load_pe_array(pe_data_file, start_date, end_date)
        self.init_investors(buy_thresholds, sell_thresholds)
        self.load_index_cache()
        size = (len(self.investors), len(self.pe_array))
        self.worth_matrix = numpy.empty(size)
        self.shares_matrix = numpy.empty(size)
        self.cash_matrix = numpy.empty(size)

    @property
    def _cache_filename(self):
        return '.cache_{}.pkl'.format(self.index)

    def _parse_pe_date(self, date_str):
        # the date_str is the beginning of the month, but we want the end
        # because the CAPE for a given month is the avg of prices for the
        # entire month
        date0 = datetime.strptime(date_str, '%m/%Y')
        date = date0 + timedelta(27)
        while date.month == date0.month or date.weekday() > 4:
            date += timedelta(1)
        return date

    def load_pe_array(self, pe_data_file, start_date, end_date):
        """Load the CAPE data from the specified file"""
        with open(pe_data_file) as fp:
            for line in fp:
                line = line.strip()
                if line:
                    date_str, pe = line.split(',')
                    pe = float(pe)
                    date = self._parse_pe_date(date_str)
                    if start_date <= date <= end_date:
                        self.pe_array.append([date, pe])

    def init_investors(self, buy_thresholds, sell_thresholds):
        """Initialize Investor instances from threshold lists"""
        for b, s in zip(buy_thresholds, sell_thresholds):
            self.investors.append(Investor(b, s))

    def load_index_cache(self):
        """Load the cache for the specified index, if available"""
        if os.path.exists(self._cache_filename):
            with open(self._cache_filename, 'rb') as fp:
                self.index_cache = pickle.load(fp)

    def save_index_cache(self):
        """Save the cache to disk"""
        with open(self._cache_filename, 'wb') as fp:
            pickle.dump(self.index_cache, fp)

    def _get_market_price(self, date, try_next=2):
        """Get the market price for the given date from yahoo or the cache.

        Tries to account for holidays by stepping backwards through time when
        the specified date is not found. Intermittent network errors may cause
        unexpected results here.

        """
        while date.weekday() > 4:
            date -= timedelta(1)
        if date in self.index_cache:
            return self.index_cache[date]
        try:
            df = get_data_yahoo(self.index, date, date)
            price = df['Adj Close'][0]
        except (IndexError, OSError):
            # try to account for holidays and wutnot
            if try_next:
                date1 = date - timedelta(1)
                return self._get_market_price(date1, try_next - 1)
            else:  # pragma no cover
                raise
        self.index_cache[date] = price
        return price

    def calculate_worth_vs_time(self):
        """Calculate the worth, shares, and cash of all the investors across
        the specified time interval

        """
        i = 0
        for date, pe_ratio in self.pe_array:
            market_price = self._get_market_price(date)
            for j, investor in enumerate(self.investors):
                investor.get_paid()
                investor.react_to_pe(pe_ratio, market_price)
                self.worth_matrix[j][i] = investor.get_net_worth(market_price)
                self.shares_matrix[j][i] = investor.shares
                self.cash_matrix[j][i] = investor.cash
            i += 1
        self.save_index_cache()

    def plot_worth_vs_time(self, names=None):
        """Plot the worth of each investor vs. time. If names is specified,
        will use these names in the legend. Otherwise, will name the investors
        based off their thresholds.

        """
        if names is None:
            names = [
                'Investor ({:0.2f},{:0.2f})'.format(inv.buy_at, inv.sell_at)
                for inv in self.investors]
        dates = [x[0] for x in self.pe_array]
        year = YearLocator()
        date_fmt = DateFormatter('%Y')
        plt.xkcd()

        # investor worth plots
        fig = plt.figure()
        ax = fig.gca()
        lines = []
        for i in range(len(self.investors)):
            result = ax.plot_date(dates, self.worth_matrix[i], '-')
            lines.append(result[0])
        ax.xaxis.set_major_locator(year)
        ax.xaxis.set_major_formatter(date_fmt)
        # ax.xaxis.set_minor_formatter(MonthLocator())
        ax.autoscale_view()
        ax.legend(lines, names, 'upper left')
        fig.autofmt_xdate()
        return fig

    def plot_pe_ratio(self):
        """
        Plot the CAPE values for the time interval in question.

        """
        dates = [x[0] for x in self.pe_array]
        year = YearLocator()
        date_fmt = DateFormatter('%Y')

        fig = plt.figure()
        ax_pe = fig.gca()
        ax_pe.plot_date(dates, [x[1] for x in self.pe_array], '-')
        ax_pe.xaxis.set_major_locator(year)
        ax_pe.xaxis.set_major_formatter(date_fmt)
        ax_pe.autoscale_view()
        ax_pe.set_title('PE Ratio vs. Time')
        fig.autofmt_xdate()
        return fig

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="CAPE Value determination")
    default_thresholds = ','.join(str(i) for i in range(16, 26)) + ',1000'
    parser.add_argument('-t', '--buy_thresholds',  default=default_thresholds)
    parser.add_argument('--sell_thresholds', default=None)
    parser.add_argument('--pe_file', default='pe_data.csv')
    parser.add_argument('--index', default='^GSPC')
    parser.add_argument('--start_date', default='01/1980')
    parser.add_argument('--end_date', default=None)
    args = parser.parse_args()

    buys = [float(b) for b in args.buy_thresholds.split(',')]
    sells = args.sell_thresholds
    if sells:
        sells = [float(b) for b in sells.split(',')]
    d0 = datetime.strptime(args.start_date, '%m/%Y')
    if args.end_date:
        d1 = datetime.strptime(args.end_date, '%m/%Y')
    else:
        d1 = datetime.now()

    validator = CapeValidator(args.pe_file, d0, buys, sells, d1, args.index)
    validator.calculate_worth_vs_time()
    import ipdb; ipdb.set_trace()
    validator.plot_worth_vs_time()
    # validator.plot_pe_ratio()
    plt.show()


from django.urls import path
from app_feria.views import *
from django.contrib.auth.views import LogoutView
from app_feria import views
"""

urlpatterns = [
    path('', inicio, name="Inicio"),
    path('vuelo/', vuelo),
    path('personal/', personal),
    path('pasajero/', pasajero),
    path('sobrenostros', sobrenosotros, name="Sobrenosotros"),

#URL DE CREACION
    path('formulario1/', formulariovuelo, name="Crear Vuelos"),
    path('formulario2/', formulariopersonal, name="Crear Personal"),
    path('formulario3/', formulariopasajero, name="Crear Pasajeros"),

#URL DE LEER
    path('leerVuelos/',leerVuelos, name="Leer Vuelos"),
    path('leerPersonal/',leerPersonal, name="Leer Personal"),
    path('leerPasajeros/',leerPasajero, name="Leer Pasajeros"),

#URL DE EDICION
    path('editaVuelo/<numVuelo>/', editaVuelo, name = "EditaVuelo"),
    path('editarPersonal/<profesionPersonal>/', editarPersonal, name = "EditarPersonal"),
    path('editarPasajero/<idvueloPasajero>/', editarPasajero, name = "EditarPasajero"),

#URL DE ELIMINACION
    path('eliminaVuelo/<numVuelo>/', eliminaVuelo, name = "EliminaVuelo"),
    path('eliminaPersonal/<profesionPersonal>/', eliminaPersonal, name = "EliminaPersonal"),
    path('eliminaPasajero/<idvueloPasajero>/', eliminaPasajero, name = "EliminaPasajero"),

#URL DE BUSQUEDAS
    path('bus/', bus, name="Buscar"),
    path('buscarVuelos/', busquedaVuelos, name="Buscar Vuelos"),
    path('buscarPersonal/', busquedaPersonal, name="Buscar Personal"),
    path('buscarPasajero/', busquedaPasajero, name="Buscar Pasajeros"),
##
    path('buscar_pasa/',buscar_pasa),
    path('buscar_per/',buscar_per),
    path('buscar/',buscar),

#URL DE LOGIN Y LOGOUT
    path('login/',InicioSesion, name="Login"),
    path('registro/',registro, name="Registrarse"),
    path('logout/', LogoutView.as_view(template_name="app_feria/logout.html"), name="Logout"),

#URL DE EDICIONUSUARIO
    path('editUser/',editarUsuario, name="Editar Usuario"),
    path('avatar/', agregarAvatar, name="Avatar"),

    ]

"""

urlpatterns = [
    path('', inicio, name="Inicio"),
    path('editar_registro/', editar_registro, name="Editarosalir"),
    path('registro_inicio/', registro_inicio, name="Iniciar_o_registrar"),
    path('sobrenostros/', sobrenosotros, name="Sobrenosotros"),

    path('jean_detail/<int:codigo>/', views.jean_detail, name="Detalle"),
    path('remera_detail/<int:codigo>/', views.remera_detail, name="Detalle_remera"),
    path('camisa_detail/<int:codigo>/', views.camisa_detail, name="Detalle_camisa"),
    path('calzado_detail/<int:codigo>/', views.calzado_detail, name="Detalle_calzado"),
    path('todo100_detail/<int:codigo>/', views.todo100_detail, name="Detalle_todo100"),
    path('invernal_detail/<int:codigo>/', views.invernal_detail, name="Detalle_invernal"),
    path('pantalon_detail/<int:codigo>/', views.pantalon_detail, name="Detalle_pantalon"),
    path('campera_detail/<int:codigo>/', views.campera_detail, name="Detalle_campera"),

#URL DE CREACION
    path('formulario1/', formulariojean, name="Crear Jeans"),
    path('formulario2/', formularioremera, name="Crear Remera"),
    path('formulario3/', formulariocamisa, name="Crear Camisa"),
    path('formulario4/', formulariotodo, name="Crear todo por 100"),
    path('formulario5/', formulariocalzado, name="Crear Calzado"),
    path('formulario6/', formularioinvernal, name="Crear Invernal"),
    path('formulario7/', formulariopantalon, name="Crear Pantalon"),
    path('formulario8/', formulariocampera, name="Crear Campera"),

#URL DE LEER
    path('leerJeans',leerJeans, name="Leer Jeans"),
    path('leerRemera/',leerRemera, name="Leer Remera"),
    path('leerCamisas/',leerCamisa, name="Leer Camisas"),
    path('leerTodo100/',leerTodo, name="Leer todo por 100"),
    path('leerCalzado/',leerCalzado, name="Leer Calzado"),
    path('leerInvernal/',leerInvernal, name="Leer Invernal"),
    path('leerPantalon/',leerPantalon, name="Leer Pantalon"),
    path('leerCampera',leerCampera, name="Leer Campera"),

#URL DE EDICION
    path('editaJean/<numJean>/', editaJean, name = "EditaJean"),
    path('editarRemera/<generoRemera>/', editarRemera, name = "EditarRemera"),
    path('editarCamisa/<generoCamisa>/', editarCamisa, name = "EditarCamisa"),
    path('editarTodo/<generoTodo>/', editarTodo, name = "Editar todo por 100"),
    path('editarCalzado/<generoCalzado>/', editarCalzado, name = "EditarCalzado"),
    path('editarInvernal/<generoInvernal>/', editarInvernal, name = "EditarInvernal"),
    path('editarPantalon/<generoPantalon>/', editarPantalon, name = "EditarPantalon"),
    path('editarCampera/<generoCampera>/', editarCampera, name = "EditarCampera"),

#URL DE ELIMINACION
    path('eliminaJean/<numJean>/', eliminaJean, name = "EliminaJean"),
    path('eliminaRemera/<generoRemera>/', eliminaRemera, name = "EliminaRemera"),
    path('eliminaCamisa/<generoCamisa>/', eliminaCamisa, name = "EliminaCamisa"),
    path('eliminaTodo/<generoTodo>/', eliminaTodo, name = "Elimina todo por 100"),
    path('eliminaCalzado/<generoCalzado>/', eliminaCalzado, name = "EliminaCalzado"),
    path('eliminaInvernal/<generoInvernal>/', eliminaInvernal, name = "EliminaInvernal"),
    path('eliminaPantalon/<generoPantalon>/', eliminaPantalon, name = "EliminaPantalon"),
    path('eliminaCampera/<generoCampera>/', eliminaCampera, name = "EliminaCampera"),

#URL DE BUSQUEDAS
    path('bus/', bus, name="Buscar"),
    path('buscarJeans/', busquedaJeans, name="Buscar Jeans"),
    path('buscarRemera/', busquedaRemera, name="Buscar Remera"),
    path('buscarCamisa/', busquedaCamisa, name="Buscar Camisa"),
    path('buscarCalzado/', busquedaCalzado, name="Buscar Calzado"),
    path('buscarInvernal/', busquedaInvernal, name="Buscar Invernal"),
    path('buscarPantalon/', busquedaPantalon, name="Buscar Pantalon"),
    path('buscarCampera/', busquedaCampera, name="Buscar Campera"),

##
    path('buscar_campe/',buscar_campe),
    path('buscar_panta/',buscar_panta),
    path('buscar_inve/',buscar_inve),
    path('buscar_calza/',buscar_calza),
    path('buscar_cami/',buscar_cami),
    path('buscar_rem/',buscar_rem),
    path('buscar/',buscar),

#URL DE LOGIN Y LOGOUT
    path('login/',InicioSesion, name="Login"),
    path('registro/',registro, name="Registrarse"),
    path('logout/', LogoutView.as_view(template_name="app_feria/logout.html"), name="Logout"),

#URL DE EDICIONUSUARIO
    path('editUser/',editarUsuario, name="Editar Usuario"),

    ]

"""

About

"""


## modified the code: args.batch_size_val == 1

import os
import random
import numpy as np
import torch
import torch.backends.cudnn as cudnn
import torch.nn as nn
import torch.nn.functional as F
import torch.nn.parallel
import torch.utils.data
from visdom_logger import VisdomLogger
from collections import defaultdict
from .dataset.dataset import get_val_loader
from .util import AverageMeter, batch_intersectionAndUnionGPU, get_model_dir, main_process
from .util import find_free_port, setup, cleanup, to_one_hot, intersectionAndUnionGPU
from .classifier import Classifier
from .model.pspnet import get_model
import torch.distributed as dist
from tqdm import tqdm
from .util import load_cfg_from_cfg_file, merge_cfg_from_list
import argparse
from torch.nn.parallel import DistributedDataParallel as DDP
import torch.multiprocessing as mp
import time
from .visu import make_episode_visualization
from typing import Tuple

def parse_args() -> None:
    parser = argparse.ArgumentParser(description='Testing')
    parser.add_argument('--config', type=str, required=True, help='config file')
    parser.add_argument('--opts', default=None, nargs=argparse.REMAINDER)
    args = parser.parse_args()
    assert args.config is not None
    cfg = load_cfg_from_cfg_file(args.config)
    if args.opts is not None:
        cfg = merge_cfg_from_list(cfg, args.opts)
    return cfg

def main_worker(rank: int,
                world_size: int,
                args: argparse.Namespace) -> None:

    print(f"==> Running DDP checkpoint example on rank {rank}.")
    setup(args, rank, world_size)

    if args.manual_seed is not None:
        cudnn.benchmark = False
        cudnn.deterministic = True
        torch.cuda.manual_seed(args.manual_seed + rank)
        np.random.seed(args.manual_seed + rank)
        torch.manual_seed(args.manual_seed + rank)
        torch.cuda.manual_seed_all(args.manual_seed + rank)
        random.seed(args.manual_seed + rank)

    # ========== Model  ==========
    model = get_model(args).to(rank)
    model = nn.SyncBatchNorm.convert_sync_batchnorm(model)
    model = DDP(model, device_ids=[rank])

    root = get_model_dir(args)

    if args.ckpt_used is not None:
        filepath = os.path.join(root, f'{args.ckpt_used}.pth')
        assert os.path.isfile(filepath), filepath
        print("=> loading weight '{}'".format(filepath))
        checkpoint = torch.load(filepath)
        model.load_state_dict(checkpoint['state_dict'])
        print("=> loaded weight '{}'".format(filepath))
    else:
        print("=> Not loading anything")

    # ========== Data  ==========
    episodic_val_loader, _ = get_val_loader(args)

    # ========== Test  ==========
    val_Iou = episodic_validate(args=args,
                                          val_loader=episodic_val_loader,
                                          model=model,
                                          use_callback=(args.visdom_port != -1),
                                          suffix=f'test')
    if args.distributed:
        dist.all_reduce(val_Iou)
        val_Iou /= world_size

    cleanup()

def episodic_validate(args: argparse.Namespace,
                      val_loader: torch.utils.data.DataLoader,
                      model: DDP,
                      use_callback: bool,
                      suffix: str = 'test') -> Tuple[torch.tensor, torch.tensor]:

    print('==> Start testing')

    model.eval()
    nb_episodes = int(args.test_num)

    # ========== Metrics initialization  ==========

    H, W = args.image_size, args.image_size
    c = model.module.bottleneck_dim
    if args.image_size == 473:
        h, w = 60, 60
    else:
        h, w = model.module.feature_res   # (53, 53)

    runtimes = torch.zeros(args.n_runs)
    deltas_init = torch.zeros((args.n_runs, nb_episodes, 1))
    deltas_final = torch.zeros((args.n_runs, nb_episodes, 1))
    val_IoUs0 = np.zeros(args.n_runs)

    # ========== Perform the runs  ==========
    for run in tqdm(range(args.n_runs)):

        # =============== Initialize the metric dictionaries ===============

        loss_meter = AverageMeter()
        iter_num = 0
        cls_intersection0 = defaultdict(int)  # Default value is 0
        cls_union0 = defaultdict(int)
        IoU0 = defaultdict(int)

        cls_intersection1 = defaultdict(int)  # Default value is 0
        cls_union1 = defaultdict(int)
        IoU1 = defaultdict(int)

        # =============== episode = group of tasks ===============
        runtime = 0
        for e in tqdm(range(nb_episodes)):
            t0 = time.time()
            iter_num += 1

            try:
                q_img, q_label, s_img, s_label, subcls, _, _ = iter_loader.next()
            except:
                iter_loader = iter(val_loader)
                q_img, q_label, s_img, s_label, subcls, _, _ = iter_loader.next()
            iter_num += 1
            q_img = q_img.to(dist.get_rank(), non_blocking=True)      # [1, 3, h, w]
            q_label = q_label.to(dist.get_rank(), non_blocking=True)  # [1, h, w]
            s_img = s_img.to(dist.get_rank(), non_blocking=True)      # [1, 1, 3, h, w]
            s_label = s_label.to(dist.get_rank(), non_blocking=True)  # [1, 1, h, w]

            classes = [[class_.item() for class_ in subcls]]  # All classes considered in the tasks, list of list

            def fit_model(s_img_, s_label_, q_img_, q_label_, classes):
                features_s = torch.zeros(1, args.shot * args.meta_aug, c, h, w).to(dist.get_rank())  # [1, 2, c, h, w]
                features_q = torch.zeros(1, 1, c, h, w).to(dist.get_rank())                          # [1, 1, c, h, w]
                gt_s = 255 * torch.ones(1, args.shot * args.meta_aug, args.image_size, args.image_size).long().to(dist.get_rank())  # [1, 2, h, w]
                gt_q = 255 * torch.ones(1, 1, args.image_size, args.image_size).long().to(dist.get_rank())                          # [1, 1, h, w]
                n_shots = torch.zeros(1).to(dist.get_rank())

                # =========== Generate tasks and extract features for each task ===============
                with torch.no_grad():
                    f_s = model.module.extract_features(s_img_.squeeze(0))    # [shot, ch, h, w]
                    f_q = model.module.extract_features(q_img_)               # [1, ch, h, w]

                    shot = f_s.size(0)
                    n_shots[0] = shot
                    features_s[0, :shot] = f_s.detach()
                    features_q[0] = f_q.detach()
                    gt_s[0, :shot] = s_label_   # [1, 2/shot, h, w]   ====
                    gt_q[i, 0] = q_label_       # [1, h, w]           ====

                # =========== Normalize features along channel dimension ===============
                if args.norm_feat:
                    features_s = F.normalize(features_s, dim=2)
                    features_q = F.normalize(features_q, dim=2)

                # =========== Create a callback is args.visdom_port != -1 ===============
                callback = VisdomLogger(port=args.visdom_port) if use_callback else None

                # ===========  Initialize the classifier + prototypes + F/B parameter Π ===============
                classifier = Classifier(args)
                classifier.init_prototypes(features_s, features_q, gt_s, gt_q, classes, callback)
                batch_deltas = classifier.compute_FB_param(features_q=features_q, gt_q=gt_q)
                deltas_init[run, e, :] = batch_deltas.cpu()

                # =========== Perform RePRI inference ===============
                batch_deltas = classifier.RePRI(features_s, features_q, gt_s, gt_q, classes, n_shots, callback)
                deltas_final[run, e, :] = batch_deltas

                logits = classifier.get_logits(features_q)  # [n_tasks, shot, h, w]
                logits = F.interpolate(logits, size=(H, W), mode='bilinear', align_corners=True)
                probas = classifier.get_probas(logits).detach()
                intersection, union, _ = batch_intersectionAndUnionGPU(probas, gt_q, 2)  # [n_tasks, shot, num_class]
                intersection, union = intersection.cpu(), union.cpu()
                return intersection, union

            intersection0, union0 = fit_model(s_img[:,:1], s_label[:, :1], q_img, q_label, classes)   # s_img [1, 1, 3, h, w] s_label # [1, 1, h, w]
            intersection1, union1 = fit_model(s_img, s_label, q_img, q_label, classes)
            runtime += time.time() - t0
            # ================== Log metrics ==================

            for i, task_classes in enumerate(classes):
                for j, class_ in enumerate(task_classes):
                    cls_intersection0[class_] += intersection0[i, 0, j + 1]  # Do not count background
                    cls_union0[class_] += union0[i, 0, j + 1]
                    cls_intersection1[class_] += intersection1[i, 0, j + 1]  # Do not count background
                    cls_union1[class_] += union1[i, 0, j + 1]

            for class_ in cls_union0:
                IoU0[class_] = cls_intersection0[class_] / (cls_union0[class_] + 1e-10)
                IoU1[class_] = cls_intersection1[class_] / (cls_union1[class_] + 1e-10)

            if (iter_num % 200 == 0):
                mIoU0 = np.mean([IoU0[i] for i in IoU0])
                mIoU1 = np.mean([IoU1[i] for i in IoU1])
                print('Test: [{}/{}] '
                      'mIoU0 {:.4f}, mIoU1 {:.4f}'.format(iter_num, args.test_num, mIoU0, mIoU1))

            # ================== Visualization ==================

        runtimes[run] = runtime
        mIoU0 = np.mean(list(IoU0.values()))
        mIoU1 = np.mean(list(IoU1.values()))
        print('mIoU---Val result: mIoU0 {:.4f}, mIoU1 {:.4f}.'.format(mIoU0, mIoU1))
        for class_ in cls_union0:
            print("Class {} : IoU0 {:.4f}, IoU1 {:.4f}".format(class_, IoU0[class_], IoU1[class_]))

        val_IoUs0[run] = mIoU0

    # ================== Save metrics ==================
    if args.save_oracle:
        root = os.path.join('plots', 'oracle')
        os.makedirs(root, exist_ok=True)
        np.save(os.path.join(root, 'delta_init.npy'), deltas_init.numpy())
        np.save(os.path.join(root, 'delta_final.npy'), deltas_final.numpy())

    print('Average mIoU over {} runs --- {:.4f}.'.format(args.n_runs, val_IoUs0.mean()))
    print('Average runtime / run --- {:.4f}.'.format(runtimes.mean()))

    return val_IoUs0.mean()

def standard_validate(args: argparse.Namespace,
                      val_loader: torch.utils.data.DataLoader,
                      model: DDP,
                      use_callback: bool,
                      suffix: str = 'test') -> Tuple[torch.tensor, torch.tensor]:

    print('==> Standard validation')
    model.eval()
    loss_fn = torch.nn.CrossEntropyLoss(ignore_index=255)
    iterable_val_loader = iter(val_loader)

    bar = tqdm(range(len(iterable_val_loader)))

    loss = 0.
    intersections = torch.zeros(args.num_classes_tr).to(dist.get_rank())
    unions = torch.zeros(args.num_classes_tr).to(dist.get_rank())

    with torch.no_grad():
        for i in bar:
            images, gt = iterable_val_loader.next()
            images = images.to(dist.get_rank(), non_blocking=True)
            gt = gt.to(dist.get_rank(), non_blocking=True)
            logits = model(images).detach()
            loss += loss_fn(logits, gt)
            intersection, union, _ = intersectionAndUnionGPU(logits.argmax(1),
                                                             gt,
                                                             args.num_classes_tr,
                                                             255)
            intersections += intersection
            unions += union
        loss /= len(val_loader.dataset)

    if args.distributed:
        dist.all_reduce(loss)
        dist.all_reduce(intersections)
        dist.all_reduce(unions)

    mIoU = (intersections / (unions + 1e-10)).mean()
    loss /= dist.get_world_size()
    return mIoU, loss

if __name__ == "__main__":
    args = parse_args()
    os.environ["CUDA_VISIBLE_DEVICES"] = ','.join(str(x) for x in args.gpus)

    if args.debug:
        args.test_num = 500
        args.n_runs = 2

    world_size = len(args.gpus)
    distributed = world_size > 1
    args.distributed = distributed
    args.port = find_free_port()
    mp.spawn(main_worker,
             args=(world_size, args),
             nprocs=world_size,
             join=True)


import csv
import datetime

FILE_NAME_READ = "Before Eod.csv"
FILE_NAME_WRITE = "After Eod.csv"
FIELDS_NAME = [
    "id",
    "Nama",
    "Age",
    "Balanced",
    "No 2b Thread-No",
    "No 3 Thread-No",
    "Previous Balanced",
    "Average Balanced",
    "No 1 Thread-No",
    "Free Transfer",
    "No 2a Thread-No",
]

# This will handle question no 1.
def rataanBalance(currentBalance, previousBalance):
    return (currentBalance + previousBalance) / 2

# This will handle question no 3.
def additionalBalanceToTop100(users):
    for user in users[:100]:
        currentBalance = user[FIELDS_NAME[3]]
        user[FIELDS_NAME[3]] = currentBalance + 10

def getDataFromCSV(filename):
    print(f"Start Read Data From {FILE_NAME_READ} at {datetime.datetime.now()}")
    users = []
    with open(filename, 'r') as csv_file:
        dataFromCSV = csv.DictReader(csv_file, delimiter=';')
        for row in dataFromCSV:
            balance = int(row['Balanced'])
            prevBalance = int(row['Previous Balanced'])
            freeTransfer = int(row['Free Transfer'])
            users.append(
                {
                    FIELDS_NAME[0]: row[FIELDS_NAME[0]],
                    FIELDS_NAME[1]: row[FIELDS_NAME[1]],
                    FIELDS_NAME[2]: row[FIELDS_NAME[2]],
                    FIELDS_NAME[3]: 25 + balance if balance > 150 else balance,
                    FIELDS_NAME[4]: '',
                    FIELDS_NAME[5]: '',
                    FIELDS_NAME[6]: prevBalance,
                    FIELDS_NAME[7]: rataanBalance(balance, prevBalance),
                    FIELDS_NAME[8]: '',
                    FIELDS_NAME[9]: 5 + freeTransfer if 100 <= balance <= 150 else freeTransfer,
                    FIELDS_NAME[10]: '',
                }
            )
        additionalBalanceToTop100(users)
    print(f"Finish Read Data from {FILE_NAME_READ} at {datetime.datetime.now()}")
    return users

def writeDataToCSV(filename, users):
    print(f"Start Write Data to {FILE_NAME_WRITE} at {datetime.datetime.now()}")
    with open(filename, 'w') as csv_file:
        writer = csv.DictWriter(csv_file, fieldnames=FIELDS_NAME)
        writer.writeheader()
        writer.writerows(users)
    print(f"Finish Write Data to {FILE_NAME_WRITE} at {datetime.datetime.now()}")

if __name__ == '__main__':
    users = getDataFromCSV(FILE_NAME_READ)
    writeDataToCSV(FILE_NAME_WRITE, users)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Tests for :mod:`orion.algo.evolution_es`."""

import copy
import hashlib

import numpy as np
import pytest

from orion.algo.evolution_es import BracketEVES, EvolutionES, compute_budgets
from orion.algo.space import Fidelity, Real, Space

@pytest.fixture
def space():
    """Create a Space with a real dimension and a fidelity value."""
    space = Space()
    space.register(Real("lr", "uniform", 0, 1))
    space.register(Fidelity("epoch", 1, 9, 1))
    return space

@pytest.fixture
def space1():
    """Create a Space with two real dimensions and a fidelity value."""
    space = Space()
    space.register(Real("lr", "uniform", 0, 1))
    space.register(Real("weight_decay", "uniform", 0, 1))
    space.register(Fidelity("epoch", 1, 8, 2))
    return space

@pytest.fixture
def space2():
    """Create a Space with two real dimensions."""
    space = Space()
    space.register(Real("lr", "uniform", 0, 1))
    space.register(Real("weight_decay", "uniform", 0, 1))
    return space

@pytest.fixture
def budgets():
    """Return a configuration for a bracket."""
    return [(30, 4), (30, 5), (30, 6)]

@pytest.fixture
def evolution(space1):
    """Return an instance of EvolutionES."""
    return EvolutionES(space1, repetitions=1, nums_population=4)

@pytest.fixture
def bracket(budgets, evolution, space1):
    """Return a `Bracket` instance configured with `b_config`."""
    return BracketEVES(evolution, budgets, 1, space1)

@pytest.fixture
def evolution_customer_mutate(space1):
    """Return an instance of EvolutionES."""
    return EvolutionES(
        space1,
        repetitions=1,
        nums_population=4,
        mutate="orion.core.utils.tests.customized_mutate_example",
    )

@pytest.fixture
def rung_0():
    """Create fake points and objectives for rung 0."""
    points = np.linspace(0, 8, 9)
    return dict(
        n_trials=9,
        resources=1,
        results={
            hashlib.md5(str([point]).encode("utf-8")).hexdigest(): (point, (1, point))
            for point in points
        },
    )

@pytest.fixture
def rung_1(rung_0):
    """Create fake points and objectives for rung 1."""
    values = map(
        lambda v: (v[0], (3, v[0])), list(sorted(rung_0["results"].values()))[:3]
    )
    return dict(
        n_trials=3,
        resources=3,
        results={
            hashlib.md5(str([value[0]]).encode("utf-8")).hexdigest(): value
            for value in values
        },
    )

@pytest.fixture
def rung_2(rung_1):
    """Create fake points and objectives for rung 2."""
    values = map(
        lambda v: (v[0], (9, v[0])), list(sorted(rung_1["results"].values()))[:1]
    )
    return dict(
        n_trials=1,
        resources=9,
        results={
            hashlib.md5(str([value[0]]).encode("utf-8")).hexdigest(): value
            for value in values
        },
    )

@pytest.fixture
def rung_3():
    """Create fake points and objectives for rung 3."""
    points = np.linspace(1, 4, 4)
    return dict(
        n_trials=4,
        resources=1,
        results={
            hashlib.md5(str([point]).encode("utf-8")).hexdigest(): (
                point,
                (np.power(2, (point - 1)), 1.0 / point, 1.0 / (point * point)),
            )
            for point in points
        },
    )

@pytest.fixture
def rung_4():
    """Create duplicated fake points and objectives for rung 4."""
    points = np.linspace(1, 4, 4)
    return dict(
        n_trials=4,
        resources=1,
        results={
            hashlib.md5(str([point]).encode("utf-8")).hexdigest(): (
                point,
                (1, point // 2, point // 2),
            )
            for point in points
        },
    )

def test_compute_budgets():
    """Verify proper computation of budgets on a logarithmic scale"""
    # Check typical values
    assert compute_budgets(1, 3, 1, 2, 1) == [[(2, 1), (2, 2), (2, 3)]]
    assert compute_budgets(1, 4, 2, 4, 2) == [[(4, 1), (4, 2), (4, 4)]]

def test_customized_mutate_population(space1, rung_3, budgets):
    """Verify customized mutated candidates is generated correctly."""
    customerized_dict = {
        "function": "orion.testing.state.customized_mutate_example",
        "multiply_factor": 2.0,
        "add_factor": 1,
    }
    algo = EvolutionES(
        space1, repetitions=1, nums_population=4, mutate=customerized_dict
    )
    algo.brackets[0] = BracketEVES(algo, budgets, 1, space1)

    red_team = [0, 2]
    blue_team = [1, 3]
    population_range = 4
    for i in range(4):
        for j in [1, 2]:
            algo.brackets[0].eves.population[j][i] = list(rung_3["results"].values())[
                i
            ][1][j]
        algo.brackets[0].eves.performance[i] = list(rung_3["results"].values())[i][0]

    org_data = np.stack(
        (
            list(algo.brackets[0].eves.population.values())[0],
            list(algo.brackets[0].eves.population.values())[1],
        ),
        axis=0,
    ).T

    org_data = copy.deepcopy(org_data)

    algo.brackets[0]._mutate_population(
        red_team, blue_team, rung_3["results"], population_range
    )

    mutated_data = np.stack(
        (
            list(algo.brackets[0].eves.population.values())[0],
            list(algo.brackets[0].eves.population.values())[1],
        ),
        axis=0,
    ).T

    # Winner team will be [0, 2], so [0, 2] will be remained, [1, 3] will be mutated.
    assert org_data.shape == mutated_data.shape
    assert (mutated_data[0] == org_data[0]).all()
    assert (mutated_data[2] == org_data[2]).all()
    assert (mutated_data[1] != org_data[1]).any()
    assert (mutated_data[3] != org_data[3]).any()
    assert (mutated_data[1] != org_data[0]).any()
    assert (mutated_data[3] != org_data[2]).any()

    # For each individual, mutation occurs in only one dimension chosen from two.
    # Customized test mutation function is divided by 2 for real type.
    if mutated_data[1][0] == org_data[0][0] / customerized_dict["multiply_factor"]:
        assert mutated_data[1][1] == org_data[0][1]
    else:
        assert (
            mutated_data[1][1] == org_data[0][1] / customerized_dict["multiply_factor"]
        )

    if mutated_data[3][0] == org_data[2][0] / customerized_dict["multiply_factor"]:
        assert mutated_data[3][1] == org_data[2][1]
    else:
        assert (
            mutated_data[3][1] == org_data[2][1] / customerized_dict["multiply_factor"]
        )

class TestEvolutionES:
    """Tests for the algo Evolution."""

    def test_register(self, evolution, bracket, rung_0, rung_1):
        """Check that a point is registered inside the bracket."""
        evolution.brackets = [bracket]
        bracket.hyperband = evolution
        bracket.eves = evolution
        bracket.rungs = [rung_0, rung_1]
        point = (1, 0.0)
        point_hash = hashlib.md5(str([0.0]).encode("utf-8")).hexdigest()

        evolution.observe([point], [{"objective": 0.0}])

        assert len(bracket.rungs[0])
        assert point_hash in bracket.rungs[0]["results"]
        assert (0.0, point) == bracket.rungs[0]["results"][point_hash]

class TestBracketEVES:
    """Tests for `BracketEVES` class.."""

    def test_get_teams(self, bracket, rung_3):
        """Test that correct team is promoted."""
        bracket.rungs[0] = rung_3
        rung, population_range, red_team, blue_team = bracket._get_teams(0)
        assert len(list(rung.values())) == 4
        assert bracket.search_space_remove_fidelity == [1, 2]
        assert population_range == 4
        assert set(red_team).union(set(blue_team)) == {0, 1, 2, 3}
        assert set(red_team).intersection(set(blue_team)) == set()

    def test_mutate_population(self, bracket, rung_3):
        """Verify mutated candidates is generated correctly."""
        red_team = [0, 2]
        blue_team = [1, 3]
        population_range = 4
        for i in range(4):
            for j in [1, 2]:
                bracket.eves.population[j][i] = list(rung_3["results"].values())[i][1][
                    j
                ]
            bracket.eves.performance[i] = list(rung_3["results"].values())[i][0]

        org_data = np.stack(
            (
                list(bracket.eves.population.values())[0],
                list(bracket.eves.population.values())[1],
            ),
            axis=0,
        ).T

        org_data = copy.deepcopy(org_data)

        bracket._mutate_population(
            red_team, blue_team, rung_3["results"], population_range
        )

        mutated_data = np.stack(
            (
                list(bracket.eves.population.values())[0],
                list(bracket.eves.population.values())[1],
            ),
            axis=0,
        ).T

        # Winner team will be [0, 2], so [0, 2] will be remained, [1, 3] will be mutated.
        assert org_data.shape == mutated_data.shape
        assert (mutated_data[0] == org_data[0]).all()
        assert (mutated_data[2] == org_data[2]).all()
        assert (mutated_data[1] != org_data[1]).any()
        assert (mutated_data[3] != org_data[3]).any()
        assert (mutated_data[1] != org_data[0]).any()
        assert (mutated_data[3] != org_data[2]).any()

        # For each individual, mutation occurs in only one dimension chosen from two.
        if mutated_data[1][0] != org_data[0][0]:
            assert mutated_data[1][1] == org_data[0][1]
        else:
            assert mutated_data[1][1] != org_data[0][1]

        if mutated_data[3][0] != org_data[2][0]:
            assert mutated_data[3][1] == org_data[2][1]
        else:
            assert mutated_data[3][1] != org_data[2][1]

    def test_duplicated_mutated_population(self, bracket, rung_4):
        """Verify duplicated candidates can be found and processed correctly."""
        red_team = [0, 2]
        blue_team = [0, 2]  # no mutate occur at first.
        population_range = 4
        for i in range(4):
            for j in [1, 2]:
                bracket.eves.population[j][i] = list(rung_4["results"].values())[i][1][
                    j
                ]
        points, nums_all_equal = bracket._mutate_population(
            red_team, blue_team, rung_4["results"], population_range
        )

        # In this case, duplication will occur, and we can make it mutate one more time.
        # The points 1 and 2 should be different, while one of nums_all_equal should be 1.
        if points[1][1] != points[2][1]:
            assert points[1][2] == points[2][2]
        else:
            assert points[1][2] != points[2][2]

        assert nums_all_equal[0] == 0
        assert nums_all_equal[1] == 0
        assert nums_all_equal[2] == 1
        assert nums_all_equal[3] == 0

    def test_mutate_points(self, bracket, rung_3):
        """Test that correct point is promoted."""
        red_team = [0, 2]
        blue_team = [0, 2]
        population_range = 4
        for i in range(4):
            for j in [1, 2]:
                bracket.eves.population[j][i] = list(rung_3["results"].values())[i][1][
                    j
                ]
        points, nums_all_equal = bracket._mutate_population(
            red_team, blue_team, rung_3["results"], population_range
        )
        assert points[0] == (1.0, 1.0, 1.0)
        assert points[1] == (2, 1.0 / 2, 1.0 / 4)
        assert (nums_all_equal == 0).all()


from selenium import webdriver
from selenium.webdriver.common.by import By
from web_test_base import WebTestBase
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.keys import Keys

class TestOrder(WebTestBase):

    def test_valid_zipcode_works(self):
        driver = self.driver
        driver.get(self.WEBSITE_URL)

        zipcode_field = driver.find_element(By.CLASS_NAME, "zipcode-field")

        input_element = zipcode_field.find_element(By.ID, "order-form")
        confirm_button = driver.find_element(By.CLASS_NAME, "order-confirm-button")

        input_element.send_keys("98139")
        confirm_button.click()

        self.assertIn("Vi levererar till dig", driver.page_source)

    def test_invalid_zipcode_works(self):
        driver = self.driver
        driver.get(self.WEBSITE_URL)

        zipcode_field = driver.find_element(By.CLASS_NAME, "zipcode-field")

        input_element = zipcode_field.find_element(By.ID, "order-form")
        confirm_button = driver.find_element(By.CLASS_NAME, "order-confirm-button")

        input_element.send_keys("123456")
        confirm_button.click()

        self.assertIn("Tyvärr kör vi inte ut inom detta område", driver.page_source)

    def test_keyshortcuts_works(self):
        driver = self.driver
        driver.get(self.WEBSITE_URL)

        zipcode_field = driver.find_element(By.CLASS_NAME, "zipcode-field")

        input_element = zipcode_field.find_element(By.ID, "order-form")
        input_element.send_keys("98139")
        input_element.send_keys(Keys.RETURN)

        self.assertIn("Vi levererar till dig", driver.page_source)


from config import *
from lib import cords, led
from utils.time import sleep_ms

def _is_row(side):
    return side == cords.TOP or side == cords.BOTTOM

def lines(gen, source=cords.TOP):
    side = DISPLAY_ROWS if _is_row(source) else DISPLAY_COLUMNS
    other_side = DISPLAY_COLUMNS if _is_row(source) else DISPLAY_ROWS
    for i in range(side):
        color = gen.generate()
        for j in range(other_side):
            pos = cords.Cords(j, i)
            if source == cords.RIGHT or source == cords.BOTTOM:
                pos.mirror_x()
            if source == cords.LEFT or source == cords.RIGHT:
                pos.flip()
            led._pixel(color, pos)
        led._show()
        sleep_ms(100)


from tkinter import *
from tkinter import messagebox
from PIL import ImageTk, Image
import pygame
import time
import threading
import serial

pygame.mixer.init()
arduinoData = serial.Serial('COM3', 9600)
test = False
musica = False
'''
Esta función se encarga de crear la ventana principal, donde se muestra la consola de comandos y el robot virtual.
Parámetros:
    None
Retorna:
    No retorna
'''
def ventana():
    ventana = Tk()
    ventana.title('Robot Virtual')
    ventana.minsize(1280, 720)
    ventana.resizable(width=NO, height=NO)
    ventana.configure(background='#C3DFF4')

    canvas = Canvas(ventana, width=450, height=400, background='#7293C4')
    canvas.place(x=40, y=150)
    canvas2 = Canvas(ventana, width=650, height=600, background='White')
    canvas2.place(x=600, y=50)

    '''
    Objeto Robot
    atributos: ventana, nombre (str), imagen, fecha_creacion (str), felicidad (int), contador (int), anim (boolean)
    metódos:
    hello_ani(): se encarga de crear la animación del robot saludando
    sayhello(): muestra en un messagebox  el nombre del robot y llama a la función hello_ani
    forward_ani(): se encarga de crear la animación del robot caminando hacia adelante
    forward(): cambia la imagen del robot para que este mire hacia adelante
    backward_ani(): se encarga de crear la animación del robot caminando hacia atrás
    backward(): cambia la imagen del robot para que este mire hacia atrás
    stop(): se encarga de detener cualquier animación
    backflip_ani(): se encarga de crear la animación del robot haciendo un backflip
    backflip(): se encarga de llamar a la funcion backflip_ani
    music_on(): carga un archivo mp3 y lo reproduce
    music_off(): detiene la reproducción del archivo mp3 y lo cierra
    '''
    class Robot:
        def __init__(self, ventana, nombre, imagen, contador, anim):
            self.ventana = ventana
            self.nombre = nombre
            self.imagen = imagen
            self.contador = contador
            self.anim = anim

        def hello_ani(self):
            self.anim = True
            canvas2.delete('imgR')
            while self.contador != 12:
                if self.anim == False:
                    break
                nombre = 'Imagenes/wave/wave'+str(self.contador)+'.jpg'
                imgR = ImageTk.PhotoImage(Image.open(nombre).resize((700,400)))
                canvas2.create_image(0,100, image=imgR, anchor=NW, tag='imgR')
                self.contador+=1
                time.sleep(0.15)
                canvas2.delete('imgR')
            self.contador = 1
            canvas2.create_image(0, 100, image=self.imagen, anchor=NW)

        def sayhello(self):
            messagebox.showinfo(title='Nombre:', message='Hola! Mi nombre es ' + str(self.nombre))
            threading.Thread(target=self.hello_ani).start()

        def forward_ani(self):
            self.anim = True
            canvas2.delete('imgR')
            while self.contador != 22:
                if self.anim == False:
                    break
                nombre = 'Imagenes/walkF/walkF'+str(self.contador)+'.jpg'
                imgR = ImageTk.PhotoImage(Image.open(nombre).resize((700,400)))
                canvas2.create_image(0, 100, image=imgR, anchor=NW, tag='imgR')
                self.contador+=1
                time.sleep(0.15)
                canvas2.delete('imgR')
            self.contador = 1
            canvas2.create_image(0, 100, image=self.imagen, anchor=NW)

        def forward(self):
            canvas2.delete('imgR')
            self.imagen = ImageTk.PhotoImage(Image.open('Imagenes/defaultF.png').resize((700,400)))
            canvas2.create_image(0,100, image=self.imagen, anchor=NW, tag='imgR')
            threading.Thread(target=self.forward_ani).start()

        def backward_ani(self):
            self.anim = True
            canvas2.delete('imgR')
            while self.contador != 22:
                if self.anim == False:
                    break
                nombre = 'Imagenes/walkB/walkB'+str(self.contador)+'.jpg'
                imgR = ImageTk.PhotoImage(Image.open(nombre).resize((700,400)))
                canvas2.create_image(0, 100, image=imgR, anchor=NW, tag='imgR')
                self.contador+=1
                time.sleep(0.15)
                canvas2.delete('imgR')
            self.contador = 1
            canvas2.create_image(0, 100, image=self.imagen, anchor=NW)

        def backward(self):
            canvas2.delete('imgR')
            self.imagen = ImageTk.PhotoImage(Image.open('Imagenes/defaultB.png').resize((700,400)))
            canvas2.create_image(0,100, image=self.imagen, anchor=NW, tag='imgR')
            threading.Thread(target=self.backward_ani).start()

        def stop(self):
            self.anim = False

        def backflip_ani(self):
            self.anim = True
            canvas2.delete('imgR')
            while self.contador != 38:
                if self.anim == False:
                    break
                nombre = 'Imagenes/backflip/backflip ('+str(self.contador)+').jpg'
                imgR = ImageTk.PhotoImage(Image.open(nombre).resize((700,400)))
                canvas2.create_image(0, 100, image=imgR, anchor=NW, tag='imgR')
                self.contador+=1
                time.sleep(0.15)
                canvas2.delete('imgR')
            self.contador = 1
            canvas2.create_image(0, 100, image=self.imagen, anchor=NW)

        def backflip(self):
            threading.Thread(target=self.backflip_ani).start()

        def music_on(self):
            pygame.mixer.music.load('aespa.mp3')
            pygame.mixer.music.play()

        def music_off(self):
            pygame.mixer.music.stop()
            pygame.mixer.music.unload()

    '''
    Esta función se encarga de recibir un dato por medio de una entry y devuelve uno de los métodos del objeto robot segun lo que se introdujo en la entry
    Parámetros:
        None
    Retorna:
        No retorna
    '''
    def aceptar():
        comando = consola.get()
        if comando == 'sayhello':
            R.sayhello()
        if comando == 'forward':
            R.forward()
        if comando == 'backward':
            R.backward()
        if comando == 'stop':
            R.stop()
        if comando == 'backflip':
            R.backflip()
        if comando == 'music_on':
            R.music_on()
        if comando == 'music_off':
            R.music_off()

    '''
    Esta funcion se encarga de cambiar la variable test a un valor boolean True
    Parametros:
        None
    Retorna:
        wait_for_button(test)
    '''
    def test1():
        global test
        test = True
        return wait_for_button(test)

    '''
    Esta funcion se encarga de cambiar la variable test a un valor boolean True
    Parametros:
        test: se encarga de
    Retorna:
        Segun el boton que se presiona, retorna uno de los comandos del robot
    '''
    def wait_for_button(test):
        global musica
        while test == True:
            command = arduinoData.read(2)
            if len(command) == 2:
                if command == b'B1':
                    test = False
                    R.sayhello()
                elif command == b'B2':
                    test = False
                    R.forward()
                elif command == b'B3':
                    test = False
                    R.backward()
                elif command == b'B4':
                    test = False
                    R.backflip()
                elif command == b'B5':
                    if musica == True:
                        test = False
                        musica = False
                        R.music_off()
                    else:
                        test = False
                        musica = True
                        R.music_on()

    Label0 = Label(canvas, text='Consola de comandos', bg='#A2C4EC', fg='#383A3D', font=('Baskerville Old Face', 10))
    Label0.place(x=20, y=10)
    Label1 = Label(canvas, text='Los comandos disponibles son: ', bg='#A2C4EC', fg='#383A3D', font=('Baskerville Old Face', 10), width=25)
    Label2 = Label(canvas, text='- sayhello\n- forward\n- backward\n- stop\n- dance\n- music_on\n- music_off', bg='#A2C4EC', width=10, justify=LEFT, fg='#383A3D', font=('Baskerville Old Face', 10), anchor='w')
    Label1.place(x=20, y=120)
    Label2.place(x=110, y=150)

    consola = Entry(canvas, bg='#A2C4EC')
    consola.place(x=20, y=35)

    btn = Button(canvas, text='Aceptar', bg='#A2C4EC', fg='#383A3D', font=('Baskerville Old Face', 10), command=test1)
    btn.place(x=60, y=60)

    imgR = ImageTk.PhotoImage(Image.open('Imagenes/defaultF.png').resize((700,400)))
    canvas2.create_image(0,100, image=imgR, anchor=NW, tag='imgR')
    R = Robot(ventana, 'Linaria', imgR, 1, False)
    ventana.mainloop()

ventana()


from __future__ import nested_scopes

from twisted.internet import defer
import sys

class _DeferredCache:
    """ Wraps a call that returns a deferred in a cache. Any subsequent
        calls with the same argument will wait for the first call to
        finish and return the same result (or errback).
    """

    hashableArgs = False
    inProgressOnly = True

    def __init__(self, op, hashableArgs=None, inProgressOnly=None):
        self.op = op
        self.cache = {}
        if hashableArgs is not None:
            self.hashableArgs = hashableArgs
        if inProgressOnly is not None:
            self.inProgressOnly = inProgressOnly

    def cb_triggerUserCallback(self, res, deferred):
        #print "triggering", deferred
        deferred.callback(res)
        return res

    def cb_triggerUserErrback(self, failure, deferred):
        deferred.errback(failure)
        return failure

    def _genCache(self, args, kwargs):
        # This could be better, probably
        try:
            arghash = hash(args)
        except TypeError:
            return None
        kwit = kwargs.items()
        kwit.sort()
        try:
            kwhash = hash(tuple(kwit))
        except TypeError:
            return None
        return (arghash, kwhash)

    def _removeCacheVal(self, res, cacheVal):
        del self.cache[cacheVal]
        return res

    def clearCache(self):
        self.cache = {}

    def call(self, *args, **kwargs):
        # Currently not in progress - start it
        #print "called with", args
        cacheVal = self._genCache(args, kwargs)
        if cacheVal is None and self.hashableArgs:
            raise TypeError('DeferredCache(%s) arguments must be hashable'%(
                                self.op.func_name))

        opdef = self.cache.get(cacheVal)
        if not opdef:
            # XXX assert that it returns a deferred?
            opdef = self.op(*args, **kwargs)
            if cacheVal is not None:
                self.cache[cacheVal] = opdef
            if self.inProgressOnly and cacheVal:
                opdef.addCallbacks(lambda x: self._removeCacheVal(x, cacheVal),
                                   lambda x: self._removeCacheVal(x, cacheVal))

        userdef = defer.Deferred()
        opdef.addCallbacks(lambda x: self.cb_triggerUserCallback(x, userdef),
                           lambda x: self.cb_triggerUserErrback(x, userdef))
        return userdef

def DeferredCache(op=None, hashableArgs=None, inProgressOnly=None):
    """ Use this as a decorator for a function or method that returns a
        deferred. Any subsequent calls using the same arguments will
        be all triggered off the original deferred, all returning the
        same result.
    """
    if op is None:
        return lambda x: DeferredCache(x, hashableArgs, inProgressOnly)
    c = _DeferredCache(op, hashableArgs, inProgressOnly)
    def func(*args, **kwargs):
        return c.call(*args, **kwargs)
    if sys.version_info > (2,4):
        func.func_name = op.func_name
    func.clearCache = c.clearCache
    func.cache_hashableArgs = c.hashableArgs
    func.cache_inProgressOnly = c.inProgressOnly
    return func


import socket
from socket import setdefaulttimeout
import ipaddress
import itertools
import json
from multiprocessing.pool import ThreadPool
import subprocess
import argparse
import base64
import os

class IPScan():
    def __init__(self):
        setdefaulttimeout(0.10)
        self.open_ports = []
        self.ports = list(range(0,1000))

    def scan_ips(self, start_ip, end_ip):
        start_ip = ipaddress.IPv4Address(start_ip)
        end_ip = ipaddress.IPv4Address(end_ip)
        results = []
        for ip in range(int(start_ip), int(end_ip)):
            results.append(self.host(ipaddress.IPv4Address(ip)))
        return results
    def network_scan(self, network_expression):
        results = []
        for ip in ipaddress.IPv4Network(network_expression):
            ip = str(ip)
            results.append(self.host(ip))
        return results

    def port_check(self, ip, port):
        try:
            sock = socket.socket()
            sock.settimeout(0.10)
            result = sock.connect_ex((ip, port))
            try:
                if result == 0:
                    self.open_ports.append("port {0}: open".format(str(port)))
                else:
                    self.open_ports.append("port {0}: closed".format(str(port)))
            except Exception as e:
                self.open_ports.append("port {0} conn fail: {1}".format(str(port), e))
            finally:
                sock.close()
        except:
            self.open_ports.append("networking failed for port {0} : {1}".format(str(port), e))

    def scan_host(self, ip):
        _host_temp = str(ip)
        returns = {}
        returns['_hostname'] = socket.getfqdn(_host_temp)
        returns['ipAddress'] = _host_temp
        self.threads = []
        pool = ThreadPool(10)
        results = pool.starmap(self.port_check, zip(itertools.repeat(_host_temp), self.ports))
        pool.close()
        pool.join()
        self.open_ports.sort()
        returns['openPorts'] = self.open_ports
        return returns

    def set_ports(self, ports):
        self.ports = ports
        return None