import torch
import torch.nn.functional as F
import torch.distributions as distributions
import numpy as np
from sklearn.decomposition import PCA

from meta_rl.models import PrefrontalLSTM
from meta_rl.training import train, evaluate
from meta_rl.tasks import TaskOne

import matplotlib.pyplot as plt

def cumulative_regret(probabilities, rewards):
    regrets = []
    max_p = max(probabilities)
    reward_sum = 0
    expected_sum = 0
    for i, r in enumerate(rewards):
        reward_sum += r
        expected_sum += max_p
        regrets.append(expected_sum - reward_sum)
    return regrets

def run_episode(env, model, probs=None, return_values=False, return_infos=False):
    state = env.reset(probs)
    done = False
    reward = 0.0
    rewards = []
    actions = []
    values = []
    infos = []
    action = torch.tensor(0)
    hidden = None
    cell = None
    with torch.no_grad():
        while not done:
            value, action_space, (hidden, cell) = model(state, reward, action, hidden=hidden, cell=cell)
            action_distribution = distributions.Categorical(action_space)
            action = action_distribution.sample()
            state, reward, done, info = env.step(action.item())
            actions.append(action.item())
            rewards.append(reward)
            values.append(value.item())
            infos.append(info)
    return_ = [actions, rewards]
    if return_values:
        return_.append(values)
    if return_infos:
        return_.append(infos)
    return return_

def get_regrets(model_path, probabilities=[0.75, 0.25], n_samples=500):
    model = PrefrontalLSTM(0, 2)
    model.load_state_dict(torch.load(model_path))
    model.eval()

    env = TaskOne(mode='bandit')

    all_regrets = []
    all_actions = []
    all_rewards = []

    for _ in range(500):
        actions, rewards = run_episode(env, model, probs=probabilities.copy())
        all_regrets.append(cumulative_regret(probabilities, rewards))
        all_rewards.append(rewards)
        all_actions.append(actions)

    all_regrets = np.array(all_regrets)
    all_actions = np.array(all_actions)
    all_rewards = np.array(all_rewards)
    return all_regrets, all_actions, all_rewards

def cumulative_regret_plot(independent_bandit_regret, correlated_bandit_regret):
    fig, ax = plt.subplots()
    ax.plot(independent_bandit_regret.mean(axis=0), label="Independent bandits")
    ax.plot(correlated_bandit_regret.mean(axis=0), label="Correlated bandits")
    ax.legend()
    ax.set_xlabel("Trials")
    ax.set_ylabel("Cumulative regret")
    plt.show()

def pca_plot(model_path, probabilities=[0.99, 0.01]):
    model = PrefrontalLSTM(0, 2)
    model.load_state_dict(torch.load(model_path))
    model.eval()

    activations = {}
    layer2name = {}
    hook_function = lambda m, i, o: activations[layer2name[m]].append(o)
    for name, layer in model._modules.items():
        layer2name[layer] = name
        activations[name] = []
        layer.register_forward_hook(hook_function)

    env = TaskOne(mode='bandit')

    #because of the seed, we don't need to worry about different PCA projections
    for _ in range(10):
        run_episode(env, model)

    activation_mat = torch.cat([x[0] for x in activations['lstm']]).squeeze().numpy()
    pca = PCA(n_components=2)
    pca.fit(activation_mat)

    activations['lstm'] = []
    actions, _ = run_episode(env, model, probabilities)
    actions = np.array(actions)

    activation_mat = torch.cat([x[0] for x in activations['lstm']]).squeeze().numpy()
    activation_x_y = pca.transform(activation_mat)

    fig, ax = plt.subplots()
    ax.set_xlabel("PCA 1")
    ax.set_ylabel("PCA 2")
    l_idx = actions == 0
    ax.scatter(activation_x_y[l_idx, 0], activation_x_y[l_idx, 1], c=np.arange(100)[l_idx], cmap='copper')
    ax.scatter(activation_x_y[~l_idx, 0], activation_x_y[~l_idx, 1], c=np.arange(100)[~l_idx], marker='x', cmap='copper')
    ax.set_title(f"P_l={probabilities[0]}, P_r={probabilities[1]}")
    plt.show()


# make a 2d grid, a 3d grid, a 4d grid and a 5d grid
# coords: 0 up to 9

dims = [2, 3, 4, 5]
for d in dims:
    with open(f"datasets/dataset{d}.txt", "w+") as f:
        num = 0
        while num < 10**d:
            points = [str(int((num / 10**x) % 10)) for x in range(d)]
            print(points)
            num += 1
            f.write(f"{', '.join(points)}\n")


from enum import Enum

import attrs
import pygame
import pygame.freetype

from . import colours
from .action import Action

@attrs.frozen
class Difficulty:
    rows: int = attrs.field()
    columns: int = attrs.field()
    mines: int = attrs.field()

EASY = Difficulty(rows=9, columns=9, mines=10)
MEDIUM = Difficulty(rows=16, columns=16, mines=40)
HARD = Difficulty(rows=16, columns=30, mines=99)

class DifficultyMenu:
    def __init__(
        self,
        font: pygame.freetype.Font,
        title_font: pygame.freetype.Font,
        screen: pygame.Surface,
    ):
        self.font = font
        self.title_font = title_font
        self.screen = screen
        self.btns: list[tuple[pygame.Rect, Action]] = []

    def display(self):
        self.screen.fill(colours.BG_COLOUR)

    def handle_event(self, event: pygame.event.Event) -> Action:
        pass


def main():

    userNumbers = []
    print(userNumbers)

    def isANumber(userinput):
        if userinput.isnumeric():
            userNumbers.append(int(userinput))
        else:
            userinput = input("ERROR! Please enter a valid number! ")
            isANumber(userinput)

    def firstNum():
        number = input("Please enter the first number: ")
        return number

    def secondNum():
        number = input("Please enter the second number: ")
        return number

    def getHighestCommonDivisor(x,y):

        factors1 = []
        factors2 = []
        commonFactors = []
        for d in range(1, x + 1):
            if (x % d == 0):
                factors1.append(d)

        for d in range(1, y + 1):
            if (y % d == 0):
                factors2.append(d)

        for i in factors2:
            if i == i in factors1:
                commonFactors.append(i)

        userNumbers.append(max(commonFactors))
        return max(commonFactors)

    isANumber(firstNum())
    isANumber(secondNum())
    getHighestCommonDivisor(userNumbers[0], userNumbers[1])

    print("The Highest Common Divisor of {0} and {1} is {2}".format(userNumbers[0], userNumbers[1], userNumbers[2]))
    yesNo = input("would you like to try again y/n?")

    if yesNo ==  "y":
        main()

main()


from service_v1.models import (
    cart_model,
    user_model,
    product_model,
    user_auth_model
)

# import utility modules
from service_v1.utils.price_convert import rupiah_format
from service_v1.utils.token_checker import token_checker
from service_v1.utils.expired_token_checker import expired_checker

# import validation modules
from service_v1.validations.token_validations import token_validations

def show_cart_controller (header_request) :

    # Header Validation
    if token_validations().token_header_validation(
        request = header_request) :

        access_token = header_request.get("Token")

        if not expired_checker(access_token = access_token) :

            if token_checker(access_token = access_token) :

                # """ admin validation by token """

                if not admin_checker (access_token = access_token) :

                    http_status_code, message_response, data_response = show_cart (access_token)

                else :
                    http_status_code : int = 403
                    message_response : str =  "Maaf, kamu bukan user."
                    data_response    : dict = {}

            else :

                http_status_code : int = 403
                message_response : str =  "Token salah atau tidak tersedia."
                data_response    : dict = {}

        else :

            http_status_code : int = 400
            message_response : str =  "Token telah kadaluarsa."
            data_response    : dict = {}

    else :

        http_status_code : int = 403
        message_response : str =  "Header 'Token' tidak tersedia"
        data_response    : dict = {}

    return http_status_code, message_response, data_response

def show_cart (access_token) :

    response_data : dict = {}

    total_price   : int = 0

    # User Cart Contain
    user_cart_contain : list = []

    # User Cart Model
    user_cart_models  : list = list(cart_model.objects.filter(

        user = user_auth_model.objects.get(
            access_token = access_token).user
    ).values())[::-1]

    response_data['total_cart'] = len(user_cart_models)

    # Filtering User Cart Model
    for user_cart_model in user_cart_models :

        get_specific_product = product_model.objects.get(
            id = user_cart_model.get('product_id')
        )

        user_cart_model["product_name"]  = get_specific_product.product_name

        user_cart_model["product_price"] = rupiah_format(
            get_specific_product.product_price, True)

        user_cart_model["total_price"] = rupiah_format(
            get_specific_product.product_price *
            user_cart_model.get('order_quantity'), True)

        total_price += (
            get_specific_product.product_price *
            user_cart_model.get('order_quantity')
        )

        user_cart_model["product_url"]   : str = get_specific_product.product_url
        user_cart_model["product_image"] : str = get_specific_product.product_image

        del user_cart_model["id"]
        del user_cart_model["user_id"]
        del user_cart_model["product_id"]

        user_cart_contain.append(user_cart_model)

    response_data['total_price']  : str  = rupiah_format(total_price, True)
    response_data['detail_cart '] : list = user_cart_contain

    # View Return
    message_response : str  = "berhasil menampilkan data keranjang"
    http_status_code : int  = 200
    data_response    : dict = response_data

    return http_status_code, message_response, data_response

def admin_checker (access_token : str) -> bool :

    get_auth_data = user_auth_model.objects.get(access_token = access_token)

    get_user_data = user_model.objects.get(id = get_auth_data.user_id)

    return get_user_data.is_admin


import pathlib
import zipfile

from pytest import fixture

from wand.color import Color
from wand.image import Image

@fixture
def fx_tmpdir(tmpdir):
    """Make :class:`pathlib.Path` instance of ```tmpdir```."""

    return pathlib.Path(str(tmpdir))

@fixture
def fx_ugoira_body():
    """Ugoira page data."""

    with open('./tests/mock/ugoira.html') as f:
        return f.read().encode('u8')

@fixture
def fx_non_ugoira_body():
    """Non ugoira page data."""

    with open('./tests/mock/non_ugoira.html') as f:
        return f.read().encode('u8')

@fixture
def fx_ugoira_zip(fx_tmpdir):
    """
    Generates a zip file used in testing
    instead of downloading an actual ugoira.
    """

    file = fx_tmpdir / '00000000_ugoira600x600.zip'
    imgs = [
        fx_tmpdir / '000000.jpg',
        fx_tmpdir / '000001.jpg',
        fx_tmpdir / '000002.jpg',
    ]
    colors = [
        Color('red'),
        Color('blue'),
        Color('green'),
    ]
    for path, color in zip(imgs, colors):
        with Image(width=100, height=100, background=color) as img:
            img.save(filename=str(path))

    with zipfile.ZipFile(str(file), 'w') as f:
        for img in imgs:
            f.write(str(img), img.name)

    with file.open('rb') as f:
        return f.read()

@fixture
def fx_ugoira_frames():
    """frames data."""

    return {
        '000000.jpg': 1000,
        '000001.jpg': 2000,
        '000002.jpg': 3000,
    }


import requests
import os
import csv
import json
import utils.tagEx as tagFind

with open('tweets.csv','r') as f:
	reader = csv.reader(f)
	messages = []
	for row in reader:
		messages.append(row[1])

url = 'http://68.183.89.148:9090/trial'

count = 0
all_data = []
for idx,message in enumerate(messages[1:],start=1):
    count += 1
    obj = {}
    obj['s.no'] = count
    obj['old_tags'] = tagFind.tagEx(message)
    obj['msg'] = message

    r = requests.post(url,data={'sentdata[q]':message})
    res_json = json.loads(r.json()['filters'])
    obj['new_tags'] = res_json['parents'] + res_json['children']

    all_data.append(obj)

writeHeader=True
if os.path.exists('devrel_tweets_comaprison.csv') :
	writeHeader=False

headlines = ['s.no','msg','old_tags','new_tags']
with open('devrel_tweets_comaprison.csv', 'w',encoding='utf-8-sig',newline='') as f:
	writer = csv.DictWriter(f,headlines)
	if writeHeader:
		writer.writeheader()
	for data in all_data:
		writer.writerow(data)


import numpy as np

def cal_fan(tensor, mode='fan_in'):
    shape = tensor.shape
    if len(shape) < 2:
        raise ValueError('Dimension of tensor must be greater than 2.')
    if len(shape) == 2:
        fan_in, fan_out = shape[:2]
    else:
        fan_out, fan_in = shape[:2]
    receptive_field_size = 1
    if len(shape) > 2:
        receptive_field_size = np.prod(shape[2:])
    fan_in *= receptive_field_size
    fan_out *= receptive_field_size
    return fan_in if mode=='fan_in' else fan_out

def kaiming_uniform(tensor, a=0, mode='fan_in', nonlinearity='leaky_relu'):
    fan = cal_fan(tensor, mode)

    param = 1
    if nonlinearity == 'relu':
        param = np.sqrt(2.0)
    elif nonlinearity == 'leaky_relu':
        if a == None:
            a = 0.01
        param = np.sqrt(2.0 / (1 + a ** 2))
    elif nonlinearity == 'tanh':
        param = 5.0 / 3
    std = param / np.sqrt(fan)
    bound = np.sqrt(3.0) * std

    return np.random.uniform(-bound, bound, size=tensor.shape)


import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.distributions import Categorical
from torch.utils.data.sampler import BatchSampler, SubsetRandomSampler
import numpy as np
from embedding_learning.opponent_models import *

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

class PolicyNet(torch.nn.Module):
    def __init__(self, state_dim, hidden_dim, latent_dim, action_dim):
        super(PolicyNet, self).__init__()
        self.lstm = torch.nn.LSTM(state_dim, hidden_dim, batch_first=True)
        self.fc1 = torch.nn.Linear(hidden_dim, hidden_dim)
        self.fc2 = torch.nn.Linear(hidden_dim, hidden_dim)
        self.fc3 = torch.nn.Linear(hidden_dim + latent_dim, hidden_dim)
        self.fc4 = torch.nn.Linear(hidden_dim, action_dim)

    def forward(self, obs, action, hidden, latent):
        x = torch.cat((obs, action), dim=-1)
        h, hidden = self.lstm(x, hidden)
        h = h[:,-1,:]
        x = F.relu(self.fc1(h))
        x = F.relu(self.fc2(x))
        x = torch.cat((x, latent), -1)
        x = F.relu(self.fc3(x))
        return F.softmax(self.fc4(x), dim=1)

class ValueNet(torch.nn.Module):
    def __init__(self, state_dim, hidden_dim, latent_dim):
        super(ValueNet, self).__init__()
        self.lstm = torch.nn.LSTM(state_dim, hidden_dim, batch_first=True)
        self.fc1 = torch.nn.Linear(hidden_dim, hidden_dim)
        self.fc2 = torch.nn.Linear(hidden_dim, hidden_dim)
        self.fc3 = torch.nn.Linear(hidden_dim + latent_dim, hidden_dim)
        self.fc4 = torch.nn.Linear(hidden_dim, 1)

    def forward(self, obs, action, hidden, latent):
        x = torch.cat((obs, action), dim=-1)
        h, hidden = self.lstm(x, hidden)
        h = h[:,-1,:]
        x = F.relu(self.fc1(h))
        x = F.relu(self.fc2(x))
        x = torch.cat((x, latent), -1)
        x = F.relu(self.fc3(x))
        return self.fc4(x)

class PPO_VAE():
    clip_param = 0.2
    max_grad_norm = 0.5
    ppo_update_time = 20
    buffer_capacity = 1000
    batch_size = 1000

    def __init__(self, state_dim, hidden_dim, embedding_dim, action_dim, actor_lr, critic_lr, encoder_weight_path, gamma, n_adv_pool=4):
        super(PPO_VAE, self).__init__()

        self.hidden_dim = hidden_dim
        self.actor_net = PolicyNet(state_dim, self.hidden_dim, embedding_dim, action_dim).to(device)
        self.critic_net = ValueNet(state_dim, self.hidden_dim, embedding_dim).to(device)

        # EncoderVAE
        self.encoder = EncoderVAE(n_adv_pool, hidden_dim, embedding_dim).to(device)
        print("encoder weight loaded")
        self.encoder.load_state_dict(torch.load(encoder_weight_path))

        self.buffer = []
        self.counter = 0
        self.training_step = 0

        self.actor_optimizer = optim.Adam(self.actor_net.parameters(), lr=actor_lr)
        self.critic_optimizer = optim.Adam(self.critic_net.parameters(), lr=critic_lr)
        self.gamma = gamma

    def select_action(self, obs, act, hidden, latent, dim_c):
        with torch.no_grad():
            action_prob = self.actor_net(obs, act, hidden, latent)
        c = Categorical(action_prob)
        action = c.sample()
        u = np.zeros(5)
        u[action.item()] += 1
        return np.concatenate([u, np.zeros(dim_c)]), action.item(), action_prob[:,action.item()].item()

    def get_params(self):
        return {'actor': self.actor_net.state_dict(), 'critic': self.critic_net.state_dict()}

    def load_params(self, params):
        self.actor_net.load_state_dict(params['actor'])
        self.critic_net.load_state_dict(params['critic'])

    def save_params(self, ckp):
        save_dict = {'agent_params': self.get_params()}
        torch.save(save_dict, '../model_params/RL/params_' + str(ckp) + '.pt', _use_new_zipfile_serialization=False)

    def save_params_with_path(self, path):
        save_dict = {'agent_params': self.get_params()}
        torch.save(save_dict, path, _use_new_zipfile_serialization=False)

    def init_from_save(self, filename):
        save_dict = torch.load(filename)
        self.load_params(save_dict['agent_params'])

    def store_transition(self, transition):
        self.buffer.append(transition)
        self.counter += 1

    def update(self, i_ep):
        state = torch.tensor([t.state for t in self.buffer], dtype=torch.float).to(device)
        action = torch.tensor([t.action for t in self.buffer], dtype=torch.long).view(-1,1).to(device)
        latent = torch.tensor([t.latent for t in self.buffer], dtype=torch.float).to(device)

        obs_traj = torch.tensor([t.obs_traj for t in self.buffer], dtype=torch.float).to(device)
        act_traj = torch.tensor([t.act_traj for t in self.buffer], dtype=torch.float).to(device)

        reward = [t.reward for t in self.buffer]
        old_action_log_prob = torch.tensor([t.a_log_prob for t in self.buffer], dtype=torch.float).view(-1,1).to(device)

        R = 0
        Gt = []
        ct = 0
        for r in reward[::-1]:
            R = r + self.gamma * R
            ct += 1
            Gt.insert(0, R)
            if ct >= 50:
                R = 0
                ct = 0

        Gt = torch.tensor(Gt, dtype=torch.float).to(device)
        for i in range(self.ppo_update_time):
            for index in BatchSampler(SubsetRandomSampler(range(len(self.buffer))), self.batch_size, False):

                hidden = [torch.zeros((1, len(index), self.hidden_dim)).to(device), torch.zeros((1, len(index), self.hidden_dim)).to(device)]

                Gt_index = Gt[index].view(-1,1)
                V = self.critic_net(obs_traj[index],  act_traj[index], hidden, latent[index])
                delta = Gt_index - V
                advantage = delta.detach()

                action_prob = self.actor_net(obs_traj[index],  act_traj[index], hidden, latent[index]).gather(1, action[index])

                ratio = (action_prob/old_action_log_prob[index])
                surr1 = ratio * advantage
                surr2 = torch.clamp(ratio, 1-self.clip_param, 1+self.clip_param) * advantage

                # update actor network
                action_loss = -torch.min(surr1, surr2).mean() # Max->Min desent
                self.actor_optimizer.zero_grad()
                action_loss.backward()
                nn.utils.clip_grad_norm_(self.actor_net.parameters(), self.max_grad_norm)
                self.actor_optimizer.step()

                # update critic network
                value_loss = F.mse_loss(Gt_index, V)
                self.critic_optimizer.zero_grad()
                value_loss.backward()
                nn.utils.clip_grad_norm_(self.critic_net.parameters(), self.max_grad_norm)
                self.critic_optimizer.step()

                self.training_step += 1

        del self.buffer[:] # clear experience


from .pegasus import Pegasus
from .coqa import CoQA
from .ubuntu import Ubuntu
from .qrecc import QReCC

def get_model(model_name):
    if "pegasus" in model_name.lower():
        return Pegasus
    else:
        print(f"Unrecognized model name: {model_name}")

def get_data(data_name):
    if "coqa" in data_name.lower():
        return CoQA
    elif "ubuntu" in data_name.lower():
        return Ubuntu
    elif "qrecc" in data_name.lower():
        return QReCC
    else:
        print(f"Unrecognized model name: {model_name}")


from argparse import ArgumentParser
from Bio import SeqIO
import gzip

def main():
    args = get_args()
    for record in SeqIO.parse(gzip.open(args.fastq, 'rt'), "fastq"):
        print(record[-args.bases_from_end:].format("fastq"), end="")

def get_args():
    parser = ArgumentParser(description="Filter nanopore data based on time")
    parser.add_argument("fastq", help="input gzip compressed fastq file")
    parser.add_argument("--bases_from_end",
                        help="get a fragment of each read N bp from end",
                        default=100,
                        type=int)
    return parser.parse_args()

if __name__ == '__main__':
    main()


from .IdentifiedObject import IdentifiedObject

class LoadResponseCharacteristic(IdentifiedObject):
	'''
	Models the characteristic response of the load demand due to changes in system conditions such as voltage and frequency. This is not related to demand response.  If LoadResponseCharacteristic.exponentModel is True, the voltage exponents are specified and used as to calculate:  Active power component = Pnominal * (Voltage/cim:BaseVoltage.nominalVoltage) ** cim:LoadResponseCharacteristic.pVoltageExponent  Reactive power component = Qnominal * (Voltage/cim:BaseVoltage.nominalVoltage)** cim:LoadResponseCharacteristic.qVoltageExponent  Where  * means "multiply" and ** is "raised to power of".

	:EnergyConsumer: The set of loads that have the response characteristics. Default: "list"
	:exponentModel: Indicates the exponential voltage dependency model is to be used.   If false, the coefficient model is to be used. The exponential voltage dependency model consist of the attributes - pVoltageExponent - qVoltageExponent. The coefficient model consist of the attributes - pConstantImpedance - pConstantCurrent - pConstantPower - qConstantImpedance - qConstantCurrent - qConstantPower. The sum of pConstantImpedance, pConstantCurrent and pConstantPower shall equal 1. The sum of qConstantImpedance, qConstantCurrent and qConstantPower shall equal 1. Default: False
	:pConstantCurrent: Portion of active power load modeled as constant current. Default: 0.0
	:pConstantImpedance: Portion of active power load modeled as constant impedance. Default: 0.0
	:pConstantPower: Portion of active power load modeled as constant power. Default: 0.0
	:pFrequencyExponent: Exponent of per unit frequency effecting active power. Default: 0.0
	:pVoltageExponent: Exponent of per unit voltage effecting real power. Default: 0.0
	:qConstantCurrent: Portion of reactive power load modeled as constant current. Default: 0.0
	:qConstantImpedance: Portion of reactive power load modeled as constant impedance. Default: 0.0
	:qConstantPower: Portion of reactive power load modeled as constant power. Default: 0.0
	:qFrequencyExponent: Exponent of per unit frequency effecting reactive power. Default: 0.0
	:qVoltageExponent: Exponent of per unit voltage effecting reactive power. Default: 0.0
		'''

	cgmesProfile = IdentifiedObject.cgmesProfile

	possibleProfileList = {'class': [cgmesProfile.EQ.value, ],
						'EnergyConsumer': [cgmesProfile.EQ.value, ],
						'exponentModel': [cgmesProfile.EQ.value, ],
						'pConstantCurrent': [cgmesProfile.EQ.value, ],
						'pConstantImpedance': [cgmesProfile.EQ.value, ],
						'pConstantPower': [cgmesProfile.EQ.value, ],
						'pFrequencyExponent': [cgmesProfile.EQ.value, ],
						'pVoltageExponent': [cgmesProfile.EQ.value, ],
						'qConstantCurrent': [cgmesProfile.EQ.value, ],
						'qConstantImpedance': [cgmesProfile.EQ.value, ],
						'qConstantPower': [cgmesProfile.EQ.value, ],
						'qFrequencyExponent': [cgmesProfile.EQ.value, ],
						'qVoltageExponent': [cgmesProfile.EQ.value, ],
						 }

	serializationProfile = {}

	__doc__ += '\n Documentation of parent class IdentifiedObject: \n' + IdentifiedObject.__doc__

	def __init__(self, EnergyConsumer = "list", exponentModel = False, pConstantCurrent = 0.0, pConstantImpedance = 0.0, pConstantPower = 0.0, pFrequencyExponent = 0.0, pVoltageExponent = 0.0, qConstantCurrent = 0.0, qConstantImpedance = 0.0, qConstantPower = 0.0, qFrequencyExponent = 0.0, qVoltageExponent = 0.0,  *args, **kw_args):
		super().__init__(*args, **kw_args)

		self.EnergyConsumer = EnergyConsumer
		self.exponentModel = exponentModel
		self.pConstantCurrent = pConstantCurrent
		self.pConstantImpedance = pConstantImpedance
		self.pConstantPower = pConstantPower
		self.pFrequencyExponent = pFrequencyExponent
		self.pVoltageExponent = pVoltageExponent
		self.qConstantCurrent = qConstantCurrent
		self.qConstantImpedance = qConstantImpedance
		self.qConstantPower = qConstantPower
		self.qFrequencyExponent = qFrequencyExponent
		self.qVoltageExponent = qVoltageExponent

	def __str__(self):
		str = 'class=LoadResponseCharacteristic\n'
		attributes = self.__dict__
		for key in attributes.keys():
			str = str + key + '={}\n'.format(attributes[key])
		return str


import json
import re
import warnings
# import spaCy
import spacy
# import required scripts
# from DERBI import Tools, Inflectors
import Tools, Inflectors
# Router contains information about
# __init__ of each pos inflector
with open('./Router.json') as r:
    Router = json.load(r)

# wrapper for inflection
'''
In fact, we do not have an unified inflector,
we have an inflector for each POS.
To provide a comfortable usage experience, we must
organize a wrapper that would gather them all together
to be able to call the needed one; so here it is!
Wrapper performance consists of three stages:
    1. Take and process input.
        1.1. Create spacy Doc based on the input text;
        1.2. Make sure each to-be-inflected token has its own target tagset;
        1.3. Process the input features set: normalize, strip;
        merge and update (over the features of the given token);
        check if the tags are valid, make sure each tagset
        is available for the POS of the given token;
    2. Redirect.
        2.1. For each to-be-inflected token define
        which inflector it must be processed with;
        2.2. Call it and obtain the result;
    3. Assemble output.
        3.1. Replace all the to-be-inflected tokens
        with the corresponding results in the input text.
        3.2. Return the result.
'''
class DERBI:

    def __init__(self, model: spacy.lang.de.German):
        # as the model uses spaCy, we require one of the German spaCy models;
        # any is accepted
        if not isinstance(model, spacy.lang.de.German):
            raise TypeError('You should use one of the German spaCy pipelines: https://spacy.io/models/de')
        self.model = model
        # with TagsProcessor we will process the input tags (surprisingly!)
        self.TagsProcessor = Tools.TagsProcessor()
        # create an instance of inflector for each POS
        for pos, args in Router.items():
            inflector_name, fa_path, lexc_path = tuple(args)
            setattr(self, pos.lower() + '_inflector', getattr(Inflectors, inflector_name)(fa_path, lexc_path))

    def inflect(self, token: spacy.tokens.token.Token, target_tags: str) -> str:
        # check if the token consist of german abc letters
        german_abc_ext = re.compile('[^a-zäöüß]')
        if german_abc_ext.search(token.norm_) is not None:
            warnings.warn('Word "' + token.norm_ + '" contains invalid characters. It will not be processed.')
            return token.norm_
        # check if some tags were provided
        if target_tags == '':
            warnings.warn('No tags for word "' + token.norm_ + '" were provided; it will not be inflected.', Warning)
            return token.norm_
        # spaCy considers VERB Verbform=Part as ADJ, so we will catch it and redirect
        if (token.pos_ == 'ADJ') and (self.model(token.lemma_)[0].pos_ == 'VERB'):
            if re.search('nd(e[mnrs]{0,1}){0,1}$', token.text.lower()) is not None:
                return self.verb_inflector(self.model(token.lemma_), re.sub('Degree=\w+\|', '', target_tags) + 'Tense=Pres|Verbform=Part')
            else:
                return self.verb_inflector(self.model(token.lemma_), re.sub('Degree=\w+\|', '', target_tags) + 'Tense=Past|Verbform=Part')
        # define needed inflector and inflect
        inflector = getattr(self, token.pos_.lower() + '_inflector')
        return inflector(token, target_tags)

    @classmethod
    def mask(cls, text):
        mapping = lambda char: 'u' if char.isupper() else 'l'
        mask = [mapping(char) for char in text]
        mask = ''.join(mask)
        return mask

    @classmethod
    def remask(cls, text, mask):
        result = ''
        for i, char in enumerate(text):
            if i >= len(mask): result += char
            else: result += char.upper() if mask[i] == 'u' else char.lower()
        return result

    @classmethod
    def get_delimitors(cls, text, tokens):
        text_ = '' + text
        delimitors = []
        masks = []
        for i in range(len(tokens) - 1):
            pre = tokens[i]
            post = tokens[i + 1]
            text_ = re.sub(pre, '', text_, count=1)
            delimitor = re.findall(f'.*?(?={post})', text_)[0]
            delimitors.append(delimitor)
            text_ = re.sub(delimitor, '', text_, count=1)
            masks.append(cls.mask(pre))
        delimitors.append('')
        return delimitors, masks

    def __call__(self, text: str, target_tags: dict or list=None, indices: int or list=0) -> str:
        # check if the target tagsets and indices of to-be-inflected tokens were provided
        if isinstance(target_tags, dict):
#             if not len(target_tags):
#                 raise ValueError('At list one key-value pair required in target tags.')
            target_tags = [target_tags]
        if target_tags is None:
            warnings.warn('No tags were provided; none of the tokens will be inflected.', Warning)
            return text
        # if no indices were provided, set default as 0
        if isinstance(indices, int):
            indices = [indices]
        # check the correspondance of the tagsets and the indices
        if len(target_tags) != len(indices):
            raise ValueError('Number of indices and number of target tagsets must not differ.')

        # process the input text with the given spaCy model
        self.doc = self.model(text)
        delimitors, masks = self.get_delimitors(text, [token.text for token in self.doc])

        self.to_inflect = {
            str(ind): {
            'token': self.doc[ind],
            'target_tags': '' if not len(tagset) else self.TagsProcessor.sub_tags(self.doc[ind], tagset)
            } for ind, tagset in zip(indices, target_tags)}
        # obtain the results for each token
        for data in self.to_inflect.values():
            # check if anything changed
            if data['target_tags'] == str(data['token'].morph):
                data['result'] = data['token'].text.lower()
            else:
                data['result'] = self.inflect(data['token'], data['target_tags'])
        # assemble the result
        result = ''
        # self.result_text = ' '.join(
        #     [word.text if self.to_inflect.get(str(i)) is None
        #      else self.to_inflect[str(i)]['result']
        #      for i, word in enumerate(self.doc)
        #     ])#.lower()
        for i, word in enumerate(self.doc):
            if self.to_inflect.get(str(i)) is None:
                result += word.text
            else:
                inflected = self.to_inflect[str(i)]['result']
                mask = masks[i]
                remasked = self.remask(inflected, mask)
                result += remasked
            result += delimitors[i]
        return result


import copy
import load_data
import split_test_and_training_data
import numpy as np
import matplotlib.pyplot as plt

def get_sample_cov_matrix(X):
    """
    Returns the sample covariance matrix of data X.

    Args:
    X (numpy array of floats) : Data matrix each column corresponds to a
                                different random variable

    Returns:
    (numpy array of floats)   : Covariance matrix
    """

    X = X - np.mean(X, 0)
    cov_matrix = 1 / X.shape[0] * np.matmul(X.T, X)
    return cov_matrix

def sort_evals_descending(evals, evectors):
    """
    Sorts eigenvalues and eigenvectors in decreasing order. Also aligns first two
    eigenvectors to be in first two quadrants (if 2D).

    Args:
    evals (numpy array of floats)    :   Vector of eigenvalues
    evectors (numpy array of floats) :   Corresponding matrix of eigenvectors
                                         each column corresponds to a different
                                         eigenvalue

    Returns:
    (numpy array of floats)          : Vector of eigenvalues after sorting
    (numpy array of floats)          : Matrix of eigenvectors after sorting
    """

    index = np.flip(np.argsort(evals))
    evals = evals[index]
    evectors = evectors[:, index]
    if evals.shape[0] == 2:
        if np.arccos(np.matmul(evectors[:, 0],
                               1 / np.sqrt(2) * np.array([1, 1]))) > np.pi / 2:
          evectors[:, 0] = -evectors[:, 0]
        if np.arccos(np.matmul(evectors[:, 1],
                               1 / np.sqrt(2)*np.array([-1, 1]))) > np.pi / 2:
          evectors[:, 1] = -evectors[:, 1]

    return evals, evectors

def change_of_basis(X, W):
    """
    Projects data onto a new basis.

    Args:
    X (numpy array of floats) : Data matrix each column corresponding to a
                                different random variable
    W (numpy array of floats) : new orthonormal basis columns correspond to
                                basis vectors

    Returns:
    (numpy array of floats)   : Data matrix expressed in new basis
    """

    Y = np.matmul(X, W)

    return Y

def get_variance_explained(evals):
    """
    Plots eigenvalues.
    Args:
    (numpy array of floats) : Vector of eigenvalues
    Returns:
    Nothing.
    """

    # cumulatively sum the eigenvalues
    csum = np.cumsum(evals)
    # normalize by the sum of eigenvalues
    variance_explained = csum / np.sum(evals)

    return variance_explained

def reconstruct_data(score, evectors, X_mean, K):
    """
    Reconstruct the data based on the top K components.
    Args:
    score (numpy array of floats)    : Score matrix
    evectors (numpy array of floats) : Matrix of eigenvectors
    X_mean (numpy array of floats)   : Vector corresponding to data mean
    K (scalar)                       : Number of components to include
    Returns:
    (numpy array of floats)          : Matrix of reconstructed data
    """

    # Reconstruct the data from the score and eigenvectors
    X_reconstructed = np.matmul(score[:, :K], evectors[:, :K].T) + X_mean

    return X_reconstructed

def pca(X):
    """
    Performs PCA on multivariate data. Eigenvalues are sorted in decreasing order

    Args:
     X (numpy array of floats) :   Data matrix each column corresponds to a
                                   different random variable

    Returns:
    (numpy array of floats)    : Data projected onto the new basis
    (numpy array of floats)    : Vector of eigenvalues
    (numpy array of floats)    : Corresponding matrix of eigenvectors

    """

    X = X - np.mean(X, 0)
    cov_matrix = get_sample_cov_matrix(X)
    evals, evectors = np.linalg.eigh(cov_matrix)
    evals, evectors = sort_evals_descending(evals, evectors)
    score = change_of_basis(X, evectors)

    return score, evectors, evals

def plot_eigenvalues(evals, limit=True):
    """
    Plots eigenvalues.

    Args:
     (numpy array of floats) : Vector of eigenvalues

    Returns:
    Nothing.

    """
    plt.figure()
    plt.plot(np.arange(1, len(evals) + 1), evals, 'o-k')
    plt.xlabel('Component')
    plt.ylabel('Eigenvalue')
    plt.title('Scree plot')
    if limit:
        plt.show()

def plot_variance_explained(variance_explained):
    """
    Plots eigenvalues.

    Args:
    variance_explained (numpy array of floats) : Vector of variance explained
                                                 for each PC

    Returns:
    Nothing.

    """

    plt.figure()
    plt.plot(np.arange(1, len(variance_explained) + 1), variance_explained, '--k')
    plt.xlabel('Number of components')
    plt.ylabel('Variance explained')
    plt.show()

def dimensionality_reduction(data, variance_thresh):
    """
    Adds a column 'reconstructed_data' to each trial with a new spike matrix (time bins x neurons) after dimensionality
    reduction has been performed

    Args:
        data (class) : training or test data
        variance_thresh (float) : the percentage of variance in data to be explained by the components
    Returns:
        data (class), the input data with an additional column
    """
    # plt.figure()
    # loop through sessions
    for session_id in range(len(data)):

        spike_data = data[session_id]['spks']
        print("Session", session_id)

        # reshape 3D neurons x trials x time bins matrix into 2D time bins x neurons matrix
        spike_times_concatenated = np.concatenate(spike_data.T)

        # do pca
        score, evectors, evals = pca(spike_times_concatenated)
        variance_explained = get_variance_explained(evals)

        # make plots
        # ax1 = plt.subplot(5, 8, session_id+1)
        # ax1.plot(np.arange(1, len(variance_explained) + 1), variance_explained, '--k')
        # plot_eigenvalues(evals, limit=True)
        # plot_variance_explained(variance_explained)

        # Reconstruct the data based on components resulting in 90% of the variance explained
        K = np.where(variance_explained >= variance_thresh)[0][0]
        X_reconstructed = reconstruct_data(score, evectors, np.mean(spike_times_concatenated, 0), K)

        # add new column to data with newly reconstructed data
        data[session_id]['reconstructed_data'] = X_reconstructed

    # plt.show()
    return data

def main():
    all_data = load_data.load_mouse_data()
    print("Data loaded")
    # test_data = split_test_and_training_data.get_test_data(all_data)
    # training_data = split_test_and_training_data.get_training_data(all_data)
    train_data, test_data = split_test_and_training_data.train_test_split(train_size=0.8)
    train_data = dimensionality_reduction(train_data, 0.9)

if __name__ == '__main__':
    main()


def Numero_Menu():
    digito = False
    num = 0

    while (not digito):
        try:
            num = int(input("Introduce un numero entero: "))
            digito = True
        except ValueError:
            print('Opcion incorrecta introduce un numero entero')

    return num

import datetime
import time

Id = 0
Cerrar_Programa = False
opcion = 0
count = 0

fecha_hoy = datetime.date.today()

while not Cerrar_Programa:

    print("1 - Registrar una venta")
    print("2 - Consultar una venta")
    print("3 - Reporte de venta por medio de fecha")
    print("4 - Cerrar programa")

    print("Eliga alguna de las siguientes opciones: ")

    opcion = Numero_Menu()

    #Importacion de sqlite3 para generar la base de datos
    import sqlite3

    con = sqlite3.connect('base_datos_cosmeticos.db')
    mi_cursor = con.cursor()
    mi_cursor.execute(
        "CREATE TABLE IF NOT EXISTS ventas(Id INT PRIMARY KEY , fecha, descripcion, cantidad, precio)")

    mi_cursor = con.cursor()
    mi_cursor.execute('SELECT Id FROM ventas')
    rows = mi_cursor.fetchall()
    cont = 0

    for row in rows:
        cont = row[0] + 1
    if opcion == 1:

        descripcion=input("Descripción del artículo: ""\n")
        piezas=int(input("Cantidad de piezas vendidas: ""\n"))
        precio=float(input("Precio de venta: ""\n"))
        total=piezas*precio
        Id = cont
        "import sqlite3"
        "con = sqlite3.connect('base_datos_cosmeticos.db')"
        "def sql_insert(con, entities):"
        mi_cursor = con.cursor()
        mi_cursor.execute("INSERT INTO ventas VALUES('"+str(Id)+"', '"+str(fecha_hoy)+"', '"+descripcion+"', '"+str(piezas)+"', '"+str(precio)+"')")
        con.commit()

        print("Total a Pagar: "+str(total))

    #Consultar una venta
    elif opcion == 2:
        opt=int(input("ID de venta a buscar: ""\n"))
        mi_cursor = con.cursor()
        mi_cursor.execute("SELECT * FROM ventas WHERE Id = '"+str(opt)+"'")
        rows = mi_cursor.fetchall()

        for row in rows:
            print(row)

    #Reporte de venta por medio de fecha
    elif opcion == 3:
        opt=input("Reporte por fechas de venta a buscar utilizando el formato YYYY-MM-DD: ""\n")
        mi_cursor = con.cursor()
        mi_cursor.execute("SELECT * FROM ventas WHERE fecha = '"+str(opt)+"'")
        rows = mi_cursor.fetchall()

        for row in rows:
            print(row)

    #Salida del programa
    elif opcion == 4:
        Cerrar_Programa = True
    else:
        print("Elija una de estas opciones")

print("PROGRAMA CERRADO EXITOSAMENTE")


#!/usr/bin/env python3
# pylos.py
# Author: Quentin Lurkin
# Version: April 28, 2017
# -*- coding: utf-8 -*-

import argparse
import socket
import sys
import json
import copy
import random

from lib import game

class PylosState(game.GameState):
    '''Class representing a state for the Pylos game.'''

    def __init__(self, initialstate=None):

        if initialstate == None:
            # define a layer of the board
            def squareMatrix(size):
                matrix = []
                for i in range(size):
                    matrix.append([None] * size)
                return matrix

            board = []
            for i in range(4):
                board.append(squareMatrix(4 - i))

            initialstate = {
                'board': board,
                'reserve': [15, 15],
                'turn': 0
            }

        super().__init__(initialstate)

    def get(self, layer, row, column):
        '''Permet de savoir si les coord sont bonnes et si la place est libre'''
        if layer < 0 or row < 0 or column < 0:
            raise game.InvalidMoveException('The position ({}) is outside of the board'.format([layer, row, column]))
        try:
            # return None si vide, 1 ou 0 en fonction du joueur
            return self._state['visible']['board'][layer][row][column]
        except:
            raise game.InvalidMoveException('The position ({}) is outside of the board'.format([layer, row, column]))

    def safeGet(self, layer, row, column):
        try:
            return self.get(layer, row, column)
        except game.InvalidMoveException:
            return None

    def validPosition(self, layer, row, column):
        '''permet de savoir si la place est libre et si elle est stable'''
        if self.get(layer, row, column) != None:
            raise game.InvalidMoveException('The position ({}) is not free'.format([layer, row, column]))

        if layer > 0:
            if (
                                    self.get(layer - 1, row, column) == None or
                                    self.get(layer - 1, row + 1, column) == None or
                                self.get(layer - 1, row + 1, column + 1) == None or
                            self.get(layer - 1, row, column + 1) == None
            ):
                raise game.InvalidMoveException('The position ({}) is not stable'.format([layer, row, column]))

    def canMove(self, layer, row, column):
        '''Verifie si la place est vide, et s'il y a une piéce au dessus'''
        if self.get(layer, row, column) == None:
            raise game.InvalidMoveException('The position ({}) is empty'.format([layer, row, column]))

        if layer < 3:
            if (
                                    self.safeGet(layer + 1, row, column) != None or
                                    self.safeGet(layer + 1, row - 1, column) != None or
                                self.safeGet(layer + 1, row - 1, column - 1) != None or
                            self.safeGet(layer + 1, row, column - 1) != None
            ):
                raise game.InvalidMoveException('The position ({}) is not movable'.format([layer, row, column]))

    def createSquare(self, coord):
        '''Regarde si on a créé une carré'''
        layer, row, column = tuple(coord)

        def isSquare(layer, row, column):
            if (
                                    self.safeGet(layer, row, column) != None and
                                    self.safeGet(layer, row + 1, column) == self.safeGet(layer, row, column) and
                                self.safeGet(layer, row + 1, column + 1) == self.safeGet(layer, row, column) and
                            self.safeGet(layer, row, column + 1) == self.safeGet(layer, row, column)
            ):
                return True
            return False

        if (
                            isSquare(layer, row, column) or
                            isSquare(layer, row - 1, column) or
                        isSquare(layer, row - 1, column - 1) or
                    isSquare(layer, row, column - 1)
        ):
            return True
        return False

    def set(self, coord, value):
        layer, row, column = tuple(coord)
        self.validPosition(layer, row, column)
        self._state['visible']['board'][layer][row][column] = value

    def remove(self, coord, player):
        layer, row, column = tuple(coord)
        self.canMove(layer, row, column)
        sphere = self.get(layer, row, column)
        if sphere != player:
            raise game.InvalidMoveException('not your sphere')
        self._state['visible']['board'][layer][row][column] = None

    # update the state with the move
    # raise game.InvalidMoveException
    def update(self, move, player):
        state = self._state['visible']
        if move['move'] == 'place':
            if state['reserve'][player] < 1:
                raise game.InvalidMoveException('no more sphere')
            self.set(move['to'], player)
            state['reserve'][player] -= 1
        elif move['move'] == 'move':
            if move['to'][0] <= move['from'][0]:
                raise game.InvalidMoveException('you can only move to upper layer')
            sphere = self.remove(move['from'], player)
            try:
                self.set(move['to'], player)
            except game.InvalidMoveException as e:
                self.set(move['from'], player)
                raise e
        else:
            raise game.InvalidMoveException('Invalid Move:\n{}'.format(move))

        if 'remove' in move:
            if not self.createSquare(move['to']):
                raise game.InvalidMoveException('You cannot remove spheres')
            if len(move['remove']) > 2:
                raise game.InvalidMoveException('Can\'t remove more than 2 spheres')
            for coord in move['remove']:
                sphere = self.remove(coord, player)
                state['reserve'][player] += 1

        state['turn'] = (state['turn'] + 1) % 2

    # return 0 or 1 if a winner, return None if draw, return -1 if game continue
    def winner(self):
        state = self._state['visible']
        if state['reserve'][0] < 1:
            return 1
        elif state['reserve'][1] < 1:
            return 0
        return -1

    def val2str(self, val):
        return '_' if val == None else '@' if val == 0 else 'O'

    def player2str(self, val):
        return 'Light' if val == 0 else 'Dark'

    def printSquare(self, matrix):
        print(' ' + '_' * (len(matrix) * 2 - 1))
        print('\n'.join(map(lambda row: '|' + '|'.join(map(self.val2str, row)) + '|', matrix)))

    # print the state
    def prettyprint(self):
        state = self._state['visible']
        for layer in range(4):
            self.printSquare(state['board'][layer])
            print()

        for player, reserve in enumerate(state['reserve']):
            print('Reserve of {}:'.format(self.player2str(player)))
            print((self.val2str(player) + ' ') * reserve)
            print()

        print('{} to play !'.format(self.player2str(state['turn'])))
        # print(json.dumps(self._state['visible'], indent=4))

class PylosServer(game.GameServer):
    '''Class representing a server for the Pylos game.'''

    def __init__(self, verbose=False):
        super().__init__('Pylos', 2, PylosState(), verbose=verbose)

    def applymove(self, move):
        try:
            self._state.update(json.loads(move), self.currentplayer)
        except json.JSONDecodeError:
            raise game.InvalidMoveException('move must be valid JSON string: {}'.format(move))

class PylosClient(game.GameClient):
    '''Class representing a client for the Pylos game.'''

    def __init__(self, name, server, verbose=False):
        self.__dontmove = []
        super().__init__(server, PylosState, verbose=verbose)
        self.__name = name

    def _handle(self, message):
        pass

    # return move as string
    def _nextmove(self, state):
        '''
        example of moves
        coordinates are like [layer, row, colums]
        move = {
            'move': 'place',
            'to': [0,1,1]
        }
        move = {
            'move': 'move',
            'from': [0,1,1],
            'to': [1,1,1]
        }
        move = {
            'move': 'move',
            'from': [0,1,1],
            'to': [1,1,1]
            'remove': [
                [1,1,1],
                [1,1,2]
            ]
        }
        return it in JSON
        '''

        iterration = 3
        t = Tree(state, 0, iterration)

        if state._state['visible']['turn'] == 0:
            player = 0
            notplayer = 1

        else:
            player = 1
            notplayer = 0

        save_reserve = -2
        children = 0
        bestmove = {}
        coup = {}

        for gen1 in t:
            children += 1
            etat1 = gen1.state._state['visible']

            # Verifie que si c'est le dernier tour on place juste la bille au seul endroit libre
            if gen1.coup['move'] == 'place':
                if etat1['reserve'][notplayer] == 1 or etat1['reserve'][player] == 1:
                    coup['move'] = gen1.coup['move']
                    coup['to'] = list(gen1.coup['to'])

                    return json.dumps(coup)
            else:
                if etat1['reserve'][notplayer] == 1 or etat1['reserve'][player] == 1:
                    coup['move'] = gen1.coup['move']
                    coup['from'] = list(gen1.coup['from'])
                    coup['to'] = list(gen1.coup['to'])

                    return json.dumps(coup)

            for gen2 in gen1:
                etat2 = gen2.state._state['visible']

                # Fait en sorte de bloquer un carré
                coup_2 = gen2.coup['to']
                layer = coup_2[0]
                row = coup_2[1]
                collumn = coup_2[2]

                try:
                    if state._state['visible']['board'][coup_2[0]][coup_2[1]][coup_2[2]] is None:
                        if gen2.state.createSquare(coup_2):
                            state.validPosition(layer, row, collumn)
                            print("Je bloque le carré")
                            self.__dontmove.append(coup_2)
                            return json.dumps({'move': 'place',
                                               'to': list(coup_2)})
                except:
                    pass

                for gen3 in gen2:
                    etat3 = gen3.state._state['visible']

                    # Creation du delta des reserves pour qu'il soit toujour positif en fonction du joueur
                    deltareserve = 0
                    deltareserve += etat1['reserve'][player] - etat1['reserve'][notplayer]
                    deltareserve += etat2['reserve'][player] - etat2['reserve'][notplayer]
                    deltareserve += etat3['reserve'][player] - etat3['reserve'][notplayer]

                    # Permet de savoir si le mouvement qu'on va faire ne vas pas librer un carré possible
                    if gen1.coup['move'] == 'move':
                        if gen1.coup['from'] in self.__dontmove:
                            pass  # Empeche de faire le mouvement si ça créé un carré pour l'adversaire
                        else:
                            if deltareserve >= save_reserve:
                                save_reserve = deltareserve
                                bestmove = gen1.coup

                    if deltareserve >= save_reserve:
                        save_reserve = deltareserve
                        bestmove = gen1.coup

        if len(bestmove) == 0:
            bestmove = t[random.randint(0, children-1)].coup

        if bestmove['move'] == 'place':
            coup['move'] = bestmove['move']
            coup['to'] = list(bestmove['to'])

            return json.dumps(coup)

        elif bestmove['move'] == 'move':
            coup['move'] = bestmove['move']
            coup['from'] = list(bestmove['from'])
            coup['to'] = list(bestmove['to'])

            return json.dumps(coup)

# for layer in range(4):
#            for row in range(4-layer):
#                for column in range(4-layer):
#                    if state.get(layer, row, column) == None:
#                        return json.dumps({
#                            'move': 'place',
#                            'to': [layer, row, column]
#                        })

class Tree:
    def __init__(self, state, tour, iterration, coup={}, children=[]):
        self.__state = copy.deepcopy(state)
        self.__player = self.__state._state['visible']['turn']
        self.__iterration = iterration
        self.__coup = coup  # Permet de savoir si on place ou si on bouge et où

        self.__children = copy.deepcopy(children)
        self.__tour = tour

        self._coupvalide(self.__state)

    def __str__(self):
        '''Affiche l'arbre et ses enfants'''

        def _str(tree, level):
            result = '{} [from:{} to:{}]\n{}{}\n'.format(tree.coup['move'],
                                                         tree.coup['from'],
                                                         tree.coup['to'],
                                                         '    ' * level,
                                                         tree.state._state['visible'])
            for child in tree.children:
                result += '{}|--{}'.format('    ' * level, _str(child, level + 1))
            return result

        return _str(self, 0)

    def __getitem__(self, item):
        '''Permet de faire des boucle for dans l'arbre'''
        return self.__children[item]

    @property
    def state(self):
        return self.__state

    @property
    def children(self):
        return self.__children

    @property
    def coup(self):
        coup = {}
        if len(self.__coup) == 0:
            coup['move'] = ''
            coup['to'] = ''
            coup['from'] = ''
            return coup
        else:
            return self.__coup

    def _possibleplacement(self, state):
        '''Enregistre toute les places où on peut faire un placement'''
        possibleplacement = []
        for move in self._getplace(state):
            try:
                state.validPosition(move[0], move[1], move[2])
                possibleplacement.append(move)
            except:
                pass

        return possibleplacement

    def _getplace(self, state):
        '''Cherche toute les places vide sur le plateau'''
        statue = state._state['visible']['board']
        move = []
        layer = 0

        while layer <= 3:
            number_line = 0
            indice = 0
            long_layer = len(statue[layer])

            while number_line < long_layer:
                lines = statue[layer][number_line]

                for place in lines:
                    if place is None:
                        move.append((layer, indice // long_layer, indice % long_layer))
                    indice += 1

                number_line += 1
            layer += 1
        return move

    def _possiblemove(self, state):
        '''Enregistre toute les places des billes qu'on peut déplacer'''
        possiblemove = []
        for move in self._getmove(state):
            try:
                state.canMove(move[0], move[1], move[2])
                possiblemove.append(move)
            except:
                pass

        return possiblemove

    def _getmove(self, state):
        '''Cherche toute les places des billes qui sont à nous'''
        move = []
        statue = state._state['visible']['board']
        player = state._state['visible']['turn']
        layer = 0

        while layer < 3:
            long_layer = len(statue[layer])
            indice = 0
            number_line = 0

            while number_line < long_layer:
                lines = statue[layer][number_line]

                for place in lines:
                    if place is not None and place == player:
                        move.append((layer, indice // long_layer, indice % long_layer))
                    indice += 1

                number_line += 1
            layer += 1

        return move

    def _coupvalide(self, state):
        possibleplacement = self._possibleplacement(state)
        possiblemove = self._possiblemove(state)

        # Pour chaque PLACEMENT possible on créé des enfants
        for move in possibleplacement:
            new_state = copy.deepcopy(state)
            new_state._state['visible']['board'][move[0]][move[1]][move[2]] = self.__player
            new_state._state['visible']['reserve'][self.__player] -= 1

            # limitation des ittérations
            if self.__iterration > 0:
                if self.__player == 0:
                    # Permetra de savoir le mouvement et la coord
                    movement = {}
                    movement['move'] = 'place'
                    movement['to'] = move
                    movement['from'] = ''

                    iterration = self.__iterration - 1
                    new_state._state['visible']['turn'] = 1
                    tour = self.__tour + 1
                    self.__children.append(Tree(new_state, tour, iterration, movement))
                else:
                    # Permetra de savoir le mouvement et la coord
                    movement = {}
                    movement['move'] = 'place'
                    movement['to'] = move
                    movement['from'] = ''

                    iterration = self.__iterration - 1
                    new_state._state['visible']['turn'] = 0
                    tour = self.__tour + 1
                    self.__children.append(Tree(new_state, tour, iterration, movement))

        # Pour chaque MOUVEMENT possible on crée des enfants
        # (prendre une boulle du plateau et la poser au layer suivant)
        for move in possiblemove:  # Prend chaque boulle qu'on peut bouger
            for place in possibleplacement:  # Prend chaque postion libre
                new_state = copy.deepcopy(state)

                if place[0] > move[0]:
                    try:
                        # Enleve la boulle, verifie la position final et place la boule
                        new_state._state['visible']['board'][move[0]][move[1]][move[2]] = None
                        new_state.validPosition(place[0], place[1], place[2])
                        new_state._state['visible']['board'][place[0]][place[1]][place[2]] = self.__player

                        # limitation des ittérations
                        if self.__iterration > 0:
                            if self.__player == 0:
                                # Permetra de savoir le mouvement et les coords
                                mouvement = {}
                                movement['move'] = 'move'
                                movement['to'] = place
                                movement['from'] = move

                                iterration = self.__iterration - 1
                                new_state._state['visible']['turn'] = 1
                                tour = self.__tour + 1
                                self.__children.append(Tree(new_state, tour, iterration, movement))
                            else:
                                # Permetra de savoir le mouvement et les coords
                                movement = {}
                                movement['move'] = 'move'
                                movement['to'] = place
                                movement['from'] = move

                                iterration = self.__iterration - 1
                                new_state._state['visible']['turn'] = 0
                                tour = self.__tour + 1
                                self.__children.append(Tree(new_state, tour, iterration, movement))
                    except:
                        pass

if __name__ == '__main__':
    # Create the top-level parser
    parser = argparse.ArgumentParser(description='Pylos game')
    subparsers = parser.add_subparsers(description='server client', help='Pylos game components', dest='component')
    # Create the parser for the 'server' subcommand
    server_parser = subparsers.add_parser('server', help='launch a server')
    server_parser.add_argument('--host', help='hostname (default: localhost)', default='localhost')
    server_parser.add_argument('--port', help='port to listen on (default: 5000)', default=5000)
    server_parser.add_argument('--verbose', action='store_true')
    # Create the parser for the 'client' subcommand
    client_parser = subparsers.add_parser('client', help='launch a client')
    client_parser.add_argument('name', help='name of the player')
    client_parser.add_argument('--host', help='hostname of the server (default: localhost)', default='127.0.0.1')
    client_parser.add_argument('--port', help='port of the server (default: 5000)', default=5000)
    client_parser.add_argument('--verbose', action='store_true')
    # Parse the arguments of sys.args
    args = parser.parse_args()
    if args.component == 'server':
        PylosServer(verbose=args.verbose).run()
    else:
        PylosClient(args.name, (args.host, args.port), verbose=args.verbose)


# -*- coding: utf-8 -*-
"""
Created on Dec 21 2020

Code for Qusetion 7.2 （coordinate to index）

Please refer to the answer sheet to see a complete strategy explanation for
solving this question.

@author: Haolin Zhong
"""

def read_input(filename):
    with open(filename) as input_data:
        coords = input_data.readlines()[1:]
        for i in range(0,len(coords)):
            coords[i] = coords[i].rstrip("\n")
            coords[i] = coords[i].split("\t")
            for j in range(0,len(coords[i])):
                coords[i][j] = int(coords[i][j])
    return coords

def C_2_I(coords, Ls):
    coef = [1]
    cur_coef = 1
    for i in range(0,len(Ls)-1):
        cur_coef = Ls[i]*cur_coef
        coef.append(cur_coef)

    Is = []
    for i in range(0,len(coords)):
        cur_I = 0
        for j in range(0, len(coords[i])):
            cur_I += coords[i][j] * coef[j]
        Is.append(cur_I)
    return Is

def output(Is,filename):
    with open (filename, "w") as output:
        output.write("index\n")
        for I in Is:
            output.write(str(I)+"\n")

if __name__ == "__main__":
    coords = read_input("input_coordinates_7_2.txt")
    Is = C_2_I(coords, [4,8,5,9,6,7])
    output(Is,"output_index_7_2.txt")


# [수학] 덧셈을 모르는 체셔
'''
[문제 접근 방식]

두 수는 10 이하 이기 때문에, 2자리수, 3자리 수, 4자리 수에 따라서 경우의 수가 나뉜다

1. 2자리 수인 경우, a와 b가 각각 1자리 임을 알 수 있다.
2. 3자리 수인 경우,
    1) 10* => 10 + *
    2) *10 => * + 10
3. 4자리 수인 경우 <=> 1010 => 10+10
'''
input = input()
N = str(input)
num = int(input)
if len(N) == 2:
    result = int(N[0]) + int(N[1])
elif len(N) == 3:
    if num <= 109:
        result = int(N[0] + N[1]) + int(N[2])
    else:
        result = int(N[0]) + int(N[1] + N[2])
elif num == 1010:
    result = 10+10

print(result)


#!/usr/bin/env python
# coding: utf-8

# In[1]:

##get_ipython().run_line_magic('matplotlib', 'inline')
import sys
import cv2
import os
import matplotlib.pyplot as plt
import numpy as np
import random
import skimage as sk
from random import randint
import math
from PIL import Image
import pandas as pd
from keras.preprocessing.image import ImageDataGenerator
from pandas import ExcelWriter
from pandas import ExcelFile
from itertools import combinations

# In[2]:

def blur_filter(img_array):
    # blur the image
    ksize = math.floor(random.random()*8)+8
    return cv2.blur(img_array, (ksize, ksize))

def reduce_line_thickness(image):
    randval = math.floor(random.random()*3)+3
    kernel = np.ones((randval,randval), np.uint8)
    return cv2.dilate(image, kernel, iterations=1)

def all_filters(image):
    img = blur_filter(image)
    img = reduce_line_thickness(img)
    return img

def random_stretch(img):
    stretch = (random.random() - 0.5)  # -0.5 .. +0.5
    wStretched = max(int(img.shape[1] * (1 + stretch)), 1)  # random width, but at least 1
    img = cv2.resize(img, (wStretched, img.shape[0]))  # stretch horizontally by factor 0.5 .. 1.5
    print(img.shape)
    return img

def applyAugmentation(img):

    img = img.reshape(1,img.shape[0],img.shape[1],1)
    datagen = ImageDataGenerator(rotation_range=15, fill_mode='nearest')
    aug_iter = datagen.flow(img, batch_size=1)

    image1 = next(aug_iter)[0].astype('uint8')
    image2 = next(aug_iter)[0].astype('uint8')
    image3 = next(aug_iter)[0].astype('uint8')
    #image = blur_filter(image)
    #image = reduce_line_thickness(image)

    return image1,image2,image3

def getGroupNumber(doc_name,temp):
    index = temp[0].index(doc_name)
    return temp[1][index]

def generateAugImages():
    path_dir = './only_text_docs'
    document_name_list = os.listdir(path_dir)
    df = pd.read_excel('./excelFiles/Writers-set.xlsx',engine='openpyxl')
    temp = []
    for column_name, column in df.transpose().iterrows():
        temp.append(column)
    temp[0] = list(temp[0])
    temp[1] = list(temp[1])
    imageName = []
    groupNum = []
    for doc_name in document_name_list:
        print(doc_name)
        try:
            group = getGroupNumber(doc_name,temp)
            new_doc_name1 = doc_name[:len(doc_name)-4] + "_1_Aug.tif"
            new_doc_name2 = doc_name[:len(doc_name)-4] + "_2_Aug.tif"
            new_doc_name3 = doc_name[:len(doc_name)-4] + "_3_Aug.tif"
            imageName.append(new_doc_name1)
            groupNum.append(group)
            imageName.append(new_doc_name2)
            groupNum.append(group)
            imageName.append(new_doc_name3)
            groupNum.append(group)
            img = cv2.imread(path_dir + "/" + doc_name,cv2.IMREAD_GRAYSCALE)
            img1,img2,img3 = applyAugmentation(img)
            cv2.imwrite(path_dir + "/" + new_doc_name1,img1)
            cv2.imwrite(path_dir + "/" + new_doc_name2,img2)
            cv2.imwrite(path_dir + "/" + new_doc_name3,img3)
        except:
            print("error")

    df = pd.DataFrame({"Image Name":temp[0]+imageName,"Group":temp[1]+groupNum})
    writer = ExcelWriter('./excelFiles/writer-set-aug.xlsx')
    df.to_excel(writer,'Sheet1',index=False)
    writer.save()

def calc_angle(points_x, points_y):
    # Calculating the angle of the image rotation.
    # according to the squares parameters.
    if points_x[0] < points_x[1]:
        y = points_y[0]
        points_y[0] = points_y[1]
        points_y[1] = y

    a = abs(points_y[1] - points_y[0])
    b = abs(points_x[1] - points_x[0])
    c = math.sqrt(a * a + b * b)
    angle = math.acos(a / c)
    angle = 90 - math.degrees(angle)

    if points_y[1] > points_y[0]:
        return -angle
    else:
        return angle

def find_squares2(img_bgr):
    location = []
    img = img_bgr
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

    # noise removal
    kernel = np.ones((3, 3), np.uint8)
    opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)

    # sure background area
    sure_bg = cv2.dilate(opening, kernel, iterations=3)
    # Finding sure foreground area
    dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
    ret, sure_fg = cv2.threshold(dist_transform, 0.7 * dist_transform.max(), 255, 0)
    # Finding unknown region
    sure_fg = np.uint8(sure_fg)
    unknown = cv2.subtract(sure_bg, sure_fg)

    # Marker labelling
    marker_count, markers = cv2.connectedComponents(sure_fg)
    # Add one to all labels so that sure background is not 0, but 1
    markers = markers + 1
    # Now, mark the region of unknown with zero
    markers[unknown == 255] = 0

    segmented = cv2.watershed(img, markers)

    # END of original watershed example

    output = np.zeros_like(img)
    output2 = img.copy()
    xmin,xmax,ymax=1000000,0,0

    # Iterate over all non-background labels
    for i in range(2, marker_count + 1):
        mask = np.where(segmented == i, np.uint8(255), np.uint8(0))
        x, y, w, h = cv2.boundingRect(mask)
        area = cv2.countNonZero(mask[y:y + h, x:x + w])
        location.append([x, y])

        if x<xmin:
          xmin = x
        if x>xmax:
          xmax = x
        if y>ymax:
          ymax = y

        # Visualize
        color = randint(0, 255 + 1)
        output[mask != 0] = color
        cv2.rectangle(output2, (x, y), (x + w, y + h), color, 1)
        cv2.putText(output2, '%d' % i, (x + w // 4, y + h // 2), cv2.FONT_HERSHEY_SIMPLEX, 0.4, color, 1,
                    cv2.LINE_AA)

    angle = calc_angle([location[0][0],location[1][0]],[location[0][1],location[1][1]])
    return angle,xmin,xmax,ymax

def rotate_image(img,angle):
    # Rotate a given image.
    (h, w) = img.shape[:2]
    center = (w / 2, h / 2)

    M = cv2.getRotationMatrix2D(center, angle, 1.0)
    rotated = cv2.warpAffine(img, M, (w, h))
    #print("rotate {0}° right".format(angle))
    return rotated

def remove_yellow(img):
    # yellow in BRG mode
    yellow = np.uint8([[[0,255,255]]])
    #yellow in hsv
    hsv_yellow = cv2.cvtColor(yellow,cv2.COLOR_BGR2HSV)

    # Convert BGR image to HSV
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

    # define range of yellow color in HSV
    lower_yellow = np.array([20,10,10])
    upper_yellow = np.array([40,255,255])

    # Threshold the HSV image to get only yellow colors
    mask = cv2.inRange(hsv, lower_yellow, upper_yellow)

    #background to put instead of yellow
    background = np.full(img.shape, 255, dtype=np.uint8)
    # biwise or is performed only in the region of mask, all other values will be set to black in the output
    bk = cv2.bitwise_or(background, background, mask=mask)

    # combine foreground+background
    res = cv2.bitwise_or(img, bk)
    return res

#global virables
h,w= 6843,4816
patch_size = 900
row_size = 240

def checkPatch(img):
    h,w= img.shape[0],img.shape[1]
    threshold = 800000

    orig = img.copy()
    #img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    ret,img = cv2.threshold(img,240,255,cv2.THRESH_BINARY_INV)

    #Split to four quarters
    upLeft = img[0:h//2,0:w//2]
    upRight = img[0:h//2,w//2:]
    downLeft = img[h//2:,0:w//2]
    downRight = img[h//2:,w//2:]

    #claculate the sum of each quarter
    sumUpLeft = np.sum(upLeft)
    sumUpRight = np.sum(upRight)
    sumDownLeft = np.sum(downLeft)
    sumDownRight = np.sum(downRight)

    #check if bigger than the threshold
    boolUpLeft = threshold < sumUpLeft
    boolUpRight = threshold < sumUpRight
    boolDownLeft = threshold < sumDownLeft
    boolDownRight = threshold < sumDownRight

    #check if at least 3 quarters are bigger than thershold
    isValidPatch = checkQuarters(boolUpRight,boolUpLeft,boolDownLeft,boolDownRight)

    return isValidPatch

def checkQuarters(q1,q2,q3,q4):
    return (int(q1) + int(q2) + int(q3) + int(q4)) > 2

def boundText(im):
    gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
    _,thresh=cv2.threshold(gray,210,255,cv2.THRESH_BINARY)
    thresh = 255-thresh

    contours, _  = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    newContours = []
    x1min = 1000
    y1min = 1000
    x2max = 0
    y2max = 0
    for cnt in contours:
        if cv2.contourArea(cnt) > 150:
            [x, y, w, h] = cv2.boundingRect(cnt)
            if x<x1min:
                x1min = x
            if y<y1min:
                y1min = y
            if x+w>x2max:
                x2max = x+w
            if y+h>y2max:
                y2max = y+h
    return im[y1min:y2max,x1min:x2max]

def split_into_patches_random(img,num_of_patches,counter,patches):
    #set borders to the image
    ymax,xmax=img.shape[0],img.shape[1]
    #set the height and width of the patch size
    h,w=patch_size,patch_size
    #keep track of the number of patches created
    #number of rows in the document
    numOfRows = (img.shape[0] // row_size) + 1

    while(counter < num_of_patches):
        #radom start x point of patch
        x_startPatch = random.randrange(0,xmax - 900)

        #radom start y point of patch
        if(numOfRows - 4 > 0):
            randomRowNumber = (random.randrange(0,numOfRows - 3))
        else:
            randomRowNumber = 0

        y_startPatch = randomRowNumber * row_size
        #end x point
        x_endPatch = x_startPatch + patch_size
        #end y point
        y_endPatch = y_startPatch + patch_size

        patch = img[y_startPatch:y_endPatch,x_startPatch:x_endPatch]

        if(checkPatch(patch)):
            counter+= 1
            patches.append(patch)

def split_into_patches(img,num_of_patches):
    #set borders to the image
    ymax,xmax=img.shape[0],img.shape[1]
    #for the patch name
    counter=0
    #set the height and width of the patch size
    h,w=patch_size,patch_size
    #keep track of the patches that created
    x1,x2 = 0,w
    y1,y2 = 0,h
    patches = []
    while(counter < num_of_patches):
        if(x2>xmax):
            x1=0
            x2=w
            y1+=240
            y2+=240
        if(y2>ymax):
            break
        temp = img[y1:y2,x1:x2]
        if( (x2-x1)==900  and (y2-y1) == 900 and  checkPatch(temp)):
            patches.append(temp)
            counter+=1
        x1 += 500
        x2 += 500
    if counter < num_of_patches:
        split_into_patches_random(img,num_of_patches,counter,patches)
    return patches

def extractTextbox(img):
    # img = np.resize(img,(h,w,3))remove_yellow
    # img = np.array(img)
    # angle,xmin,xmax,ymax = find_squares2(img)

    # img = rotate_image(img,angle)

    img = remove_yellow(img)#cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR))
    # img = np.array(img)
    # img = img[1900:ymax-100,xmin:xmax+100]

    img = boundText(img)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    return img

def convert_document_to_patches(img):
        try:
            img = extractTextbox(img)
            return split_into_patches(img,15)
        except AttributeError:
            print('cannot find text box')

def preparePatchesToModel(patches):
    for i in range(len(patches)):
        patches[i] = np.array(patches[i], dtype = np.float32)
        np.expand_dims(patches[i], axis=0)
        patches[i] = cv2.resize(patches[i], (150,150))
        patches[i]/=255
        # if(i==0):
        #     # plt.imshow(patches[i],cmap="gray")
        #     # plt.show()

def saveTextbox():
    document_name_list = os.listdir('./HandwrittenForms_paragraphs/')
    path_dir = './only_text_docs'
    if (os.path.isdir(path_dir)) != True:
        os.mkdir(path_dir)
    for doc_name in document_name_list:
        try:
            print(doc_name)
            img = extractTextbox(doc_name)
            cv2.imwrite(path_dir + "/" + doc_name,img)
        except:
            print('cannot find text box')

# In[3]:

##generateAugImages()

# In[4]:

def createWritersDir(path,dataset):
    if (os.path.isdir(path)) != True:
        os.mkdir(path)
    for group in dataset:
        if (os.path.isdir(path+"/"+str(group))) != True:
            os.mkdir(path+"/"+str(group))

def createDocumentsDir(train_set_groups,val_set_groups,dataset):
    for i in range(len(dataset[1])):
        print(dataset[1][i],dataset[0][i])
        if dataset[1][i] in train_set_groups:
            print("in train")
            path = './train_set/' + str(dataset[1][i]) + "/" + (dataset[0][i])[:len(dataset[0][i])-4]
            if (os.path.isdir(path)) != True:
                os.mkdir(path)
        elif dataset[1][i] in val_set_groups:
            print("in val")
            path = './val_set/' + str(dataset[1][i]) + "/" + (dataset[0][i])[:len(dataset[0][i])-4]
            if (os.path.isdir(path)) != True:
                os.mkdir(path)
        else:
            print("in test")
            path = './test_set/' + str(dataset[1][i]) + "/" + (dataset[0][i])[:len(dataset[0][i])-4]
            if (os.path.isdir(path)) != True:
                os.mkdir(path)
        img = cv2.imread('./only_text_docs/' + dataset[0][i],cv2.IMREAD_GRAYSCALE)
        img_name = (dataset[0][i])[:len(dataset[0][i])-4]
        split_into_patches(path,img,img_name,15)

# In[5]:

def createPairs():
    df = pd.read_excel('./excelFiles/writer-set-aug.xlsx',engine='openpyxl')
    temp = []
    for column_name, column in df.transpose().iterrows():
        temp.append(column)
    groups = list(temp[1])
    groups = set(groups)
    numOfWriters = len(groups)
    groups = list(groups)
    train_set,val_set,test_set = [],[],[]
    random.shuffle(groups)
    train_set = groups[:round(numOfWriters*0.80)]
    val_set = groups[round(numOfWriters*0.80):round(numOfWriters*0.90)]
    test_set = groups[round(numOfWriters*0.90):]
    print(len(train_set),len(val_set),len(test_set))
    createWritersDir('./train_set', train_set)
    createWritersDir('./val_set', val_set)
    createWritersDir('./test_set', test_set)
    temp[0] = list(temp[0])
    temp[1] = list(temp[1])
    createDocumentsDir(train_set,val_set,temp)
##createPairs()

# In[7]:

def createExcelPairs(target,path):
    writers_list = os.listdir(path)
    right, left, label = [],[],[]
    for writer in writers_list:
        documents = os.listdir(path + "/" + writer)
        pairs = combinations(documents,2)
        pairs = list(pairs)
        limit = 30
        if len(pairs) > limit:
            random.shuffle(pairs)
            pairs = pairs[:limit]
        for doc1,doc2 in pairs:

#             doc1,doc2 = random.sample(documents,2)
            right.append(path + writer + "/" + doc1)
            left.append(path + writer + "/" + doc2)
            label.append(1)
    print(len(right))
    for i in range(len(right)):
        writer1,writer2 = random.sample(writers_list,2)
        documents1 = os.listdir(path + "/" + writer1)
        documents2 = os.listdir(path + "/" + writer2)
        doc1 = random.sample(documents1,1)
        doc2 = random.sample(documents2,1)
        right.append(path + writer1 + "/" + doc1[0])
        left.append(path + writer2 + "/" + doc2[0])
        label.append(0)

    df = pd.DataFrame({"Left":left, "Right":right, "Label":label})
    writer = ExcelWriter('./excelFiles/' + target +'_set.xlsx')
    df.to_excel(writer,'Sheet1',index=False)
    writer.save()
##
##createExcelPairs("Train_ext",'./train_set/')
##createExcelPairs("Val_ext",'./val_set/')
##createExcelPairs("Test_ext",'./test_set/')

# In[ ]:


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

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('authentication', '0003_auto_20141223_1334'),
    ]

    operations = [
        migrations.AddField(
            model_name='account',
            name='is_active',
            field=models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active'),
            preserve_default=True,
        ),
    ]


"""
Module that wraps some legacy code to get a set of pod coefficients for
subdomains (domain-decomposed) from a domain decomposed flow past cylinder
problem.

Note this code is meant to be a wrapper for legacy code that is intended to
not be used used very often or in a critical/production setting. Therefore
sustainability  may be lacking.
"""

import vtktools
import numpy as np
from utils import get_grid_end_points
import argparse
import sys

# Backwards compatibility with python 2
if sys.version_info[0] < 3:
    import u2r  # noqa
else:
    import u2rpy3  # noqa
    u2r = u2rpy3

__author__ = " Claire Heaney, Zef Wolffs"
__credits__ = ["Jon Atli Tomasson"]
__license__ = "MIT"
__version__ = "1.0.0"
__maintainer__ = "Zef Wolffs"
__email__ = "zefwolffs@gmail.com"
__status__ = "Development"

def get_pod_coeffs(data_dir='./submodules/DD-GAN/data/FPC_Re3900_2D_CG_old/',
                   data_file_base='fpc_2D_Re3900_CG_',
                   out_dir='./../../data/processed/', nTime=1400,
                   offset=20, field_names=['Velocity'], nGrids=4, xlength=2.2,
                   ylength=0.41, nloc=3, nScalar=2, nDim=2):
    """
    Function that wraps some legacy code to interpolated data from  an
    unstructured mesh to a structured mesh and calculate POD coefficients from
    output.

    Args:
        data_dir (str, optional): Input data folder.
            Defaults to `./submodules/DD-GAN/data/FPC_Re3900_2D_CG_old/`.
        data_file_base (str, optional): Base filename, timesteps will be
            appended. Defaults to `fpc_`.
        out_dir (str, optional): Output data folder. Defaults to
            `./../../data/processed/`.
        nTime (int, optional): Number of timesteps to include in snapshots
            matrix. Defaults to 1400.
        offset (int, optional): At which time level to start taking the
            snapshots. Defaults to 20.
        field_names (list, optional): Names of fields to include from vtu
            data file. Defaults to [`Velocity`].
        nGrids (int, optional): Number of grids of decomposed domain,
            choose 1 or 4. Defaults to 4.
        xlength (float, optional): Length of interpolated domain in x.
            Defaults to 2.2.
        ylength (float, optional): Length of interpolated domain in y.
            Defaults to 0.41.
        nloc (int, optional): Number of local nodes, ie three nodes per
            element (in 2D). Defaults to 3.
        nScalar (int, optional): Dimension of fields. Defaults to 2.
        nDim (int, optional): Dimension of problem. Defaults to 2.
    """

    nFields = len(field_names)

    if nGrids == 4:
        nx = 55
        ny = 42
        nz = 1  # nz = 1 for 2D problems
    elif nGrids == 1:
        nx = 221
        ny = 42
        nz = 1  # nz = 1 for 2D problems
    else:
        print('nx, ny, nz not known for ', nGrids, 'grids')

    grid_origin = [0.0, 0.0]
    grid_width = [xlength/nGrids, 0.0]
    # ddx = np.array((0.01,0.01))
    ddx = np.array((xlength/(nGrids*(nx-1)), ylength/(ny-1)))
    print('ddx', ddx)

    # get a vtu file (any will do as the mesh is not adapted)
    filename = data_dir + data_file_base + '0.vtu'
    representative_vtu = vtktools.vtu(filename)
    coordinates = representative_vtu.GetLocations()

    nNodes = coordinates.shape[0]  # vtu_data.ugrid.GetNumberOfPoints()
    nEl = representative_vtu.ugrid.GetNumberOfCells()
    print('nEl', nEl, type(nEl), 'nNodes', nNodes)
    # nNodes = 3571
    # nEl = 6850

    x_all = np.transpose(coordinates[:, 0:nDim])  # coords n,3  x_all 2,n

    # get global node numbers
    x_ndgln = np.zeros((nEl*nloc), dtype=int)
    for iEl in range(nEl):
        n = representative_vtu.GetCellPoints(iEl) + 1
        x_ndgln[iEl*nloc:(iEl+1)*nloc] = n

    # -------------------------------------------------------------------------------------------------
    # find node duplications when superposing results
    my_field = representative_vtu.GetField(field_names[0])[:, 0]
    my_field = 1
    nScalar_test = 1
    # for one timestep
    # for one field
    value_mesh = np.zeros((nScalar_test, nNodes, 1))  # nTime=1
    value_mesh[:, :, 0] = np.transpose(my_field)
    superposed_grids = np.zeros((nNodes))
    for iGrid in range(nGrids):
        block_x_start = get_grid_end_points(grid_origin, grid_width, iGrid)

        zeros_on_mesh = 0
        value_grid = u2r.simple_interpolate_from_mesh_to_grid(value_mesh,
                                                              x_all, x_ndgln,
                                                              ddx,
                                                              block_x_start,
                                                              nx, ny, nz,
                                                              zeros_on_mesh,
                                                              nEl, nloc,
                                                              nNodes,
                                                              nScalar_test,
                                                              nDim, 1)

        zeros_on_grid = 1
        value_back_on_mesh = u2r.interpolate_from_grid_to_mesh(value_grid,
                                                               block_x_start,
                                                               ddx, x_all,
                                                               zeros_on_grid,
                                                               nScalar_test,
                                                               nx, ny, nz,
                                                               nNodes, nDim, 1)

        superposed_grids = superposed_grids + \
            np.rint(np.squeeze(value_back_on_mesh))

    superposed_grids = np.array(superposed_grids, dtype='int')
    duplicated_nodal_values = []
    for iNode in range(nNodes):
        if superposed_grids[iNode] == 0:
            # this is bad news - the node hasn't appeared in any grid
            print('zero:', iNode)
        elif superposed_grids[iNode] == 2:
            print('two:', iNode)
            # the node appears in two grids - deal with this later
            duplicated_nodal_values.append(iNode)
        elif superposed_grids[iNode] != 1:
            # most of the nodes will appear in one grid
            print('unknown:', iNode, superposed_grids[iNode])

    # -------------------------------------------------------------------------------------------------
    # build up the snapshots matrix from solutions on each of the grids
    snapshots_data = []
    for iField in range(nFields):
        # nDoF = nNodes # could be different value per field
        snapshots_data.append(np.zeros((nx*ny*nz*nDim, nGrids*nTime)))

    # value_mesh = np.zeros((nScalar,nNodes)) # no need to initialise -
    # overwritten
    for iTime in range(nTime):

        # print('')
        # print('time level', iTime)

        filename = data_dir + data_file_base + str(offset+iTime) + '.vtu'
        vtu_data = vtktools.vtu(filename)

        for iField in range(nFields):

            my_field = vtu_data.GetField(field_names[iField])[:, 0:nDim]

            for iGrid in range(nGrids):

                block_x_start = get_grid_end_points(grid_origin, grid_width,
                                                    iGrid)
                if iTime == 0:
                    print('block_x_start', block_x_start)

                # value_mesh = np.zeros((nScalar,nNodes,nTime)) # nTime - this
                # must need initialising here
                # value_mesh[:,:,iTime] = np.transpose(my_field)

                value_mesh = np.transpose(my_field)  # size nScalar,nNodes

                # interpolate field onto structured mesh
                # feed in one result at t time (no need to store in value_mesh
                # in this case)

                # 0 extrapolate solution (for the cylinder in fpc); 1 gives
                # zeros for nodes outside mesh
                zeros_beyond_mesh = 0

                value_grid = \
                    u2r.simple_interpolate_from_mesh_to_grid(value_mesh, x_all,
                                                             x_ndgln, ddx,
                                                             block_x_start, nx,
                                                             ny, nz,
                                                             zeros_beyond_mesh,
                                                             nEl, nloc, nNodes,
                                                             nScalar, nDim, 1)

                snapshots_data[iField][:, iTime*nGrids+iGrid] = \
                    value_grid.reshape(-1)

    # ---------------------------------------------------------------------------------------
    # apply POD to the snapshots
    # some POD truncation settings
    cumulative_tol = 0.99
    nPOD = [nTime]  # len(nPOD) = nFields
    nPOD = [-2]
    nPOD = [10]  # 100 50 10

    bases = []
    singular_values = []

    for iField in range(nFields):

        snapshots_matrix = snapshots_data[iField]
        nrows, ncols = snapshots_matrix.shape

        SSmatrix = np.dot(snapshots_matrix.T, snapshots_matrix)

        print('SSmatrix', SSmatrix.shape)
        eigvalues, v = np.linalg.eigh(SSmatrix)
        eigvalues = eigvalues[::-1]

        # get rid of small negative eigenvalues (there shouldn't be any as the
        # eigenvalues of a real, symmetric matrix are non-negative, but
        # sometimes very small negative values do appear)
        eigvalues[eigvalues < 0] = 0
        s_values = np.sqrt(eigvalues)
        # print('s values', s_values[0:20])

        singular_values.append(s_values)

        cumulative_info = np.zeros(len(eigvalues))
        for j in range(len(eigvalues)):
            if j == 0:
                cumulative_info[j] = eigvalues[j]
            else:
                cumulative_info[j] = cumulative_info[j-1] + eigvalues[j]

        cumulative_info = cumulative_info / cumulative_info[-1]
        nAll = len(eigvalues)

    # if nPOD = -1, use cumulative tolerance
    # if nPOD = -2 use all coefficients (or set nPOD = nTime)
    # if nPOD > 0 use nPOD coefficients as defined by the user

        if nPOD[iField] == -1:
            raise NotImplementedError("Option not yet implemented!")
            # SVD truncation - percentage of information captured or number
            cumulative_tol = nirom_options.compression.cumulative_tol[iField] # noqa
            nPOD_iField = sum(cumulative_info <= cumulative_tol)  # tolerance
            nPOD[iField] = nPOD_iField
        elif nPOD[iField] == -2:
            nPOD_iField = nAll
            nPOD[iField] = nPOD_iField
        else:
            nPOD_iField = nPOD[iField]

        print("retaining", nPOD_iField, "basis functions of a possible",
              len(eigvalues))

        # nDim should be nScalar?
        basis_functions = np.zeros((nx*ny*nz*nDim, nPOD_iField))
        for j in reversed(range(nAll-nPOD_iField, nAll)):
            Av = np.dot(snapshots_matrix, v[:, j])
            basis_functions[:, nAll-j-1] = Av/np.linalg.norm(Av)

        bases.append(basis_functions)

    pod_coeffs = []

    for iField in range(nFields):

        basis = bases[iField]

        snapshots_matrix = snapshots_data[iField]
        print('snapshots_matrix', snapshots_matrix.shape)

        for iGrid in range(nGrids):

            # :,iTime*nGrids+iGrid
            # want solutions in time for a particular grid
            snapshots_per_grid = np.zeros((nx*ny*nz*nDim, nTime))
            for iTime in range(nTime):
                # print('taking snapshots from', iTime*nGrids+iGrid )
                snapshots_per_grid[:, iTime] = snapshots_matrix[:,
                                                                iTime*nGrids
                                                                + iGrid]
            print(snapshots_per_grid)
            pod_coeffs.append(np.dot(basis.T, snapshots_per_grid))
            print(basis.shape)

        np.save(out_dir + "/pod_coeffs_field_{}".format(
            field_names[iField]), np.array(pod_coeffs))
        np.save(out_dir + "/pod_basis_field_{}".format(
            field_names[iField]), np.array(basis))
        np.savetxt(out_dir + "/pod_eigenvalues_field_{}".format(
            field_names[iField]), np.array(eigvalues))

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="Module that wraps some \
legacy code to interpolate data from  an unstructured mesh to a structured \
mesh and calculate POD coefficients from output. \n\n\
Note that output will be saved under the folder specified by out_dir as \
`pod_coeffs_field_<name of field>`. \
The shape of the output matrix will be (num_subgrids, num_pod_coeffs, \
num_time_levels)")
    parser.add_argument('--data_dir', type=str, nargs='?',
                        default="./submodules/DD-GAN/data/\
FPC_Re3900_2D_CG_old/",
                        help='Input data folder')
    parser.add_argument('--data_file_base', type=str, nargs='?',
                        default="fpc_",
                        help='Base filename')
    parser.add_argument('--out_dir', type=str, nargs='?',
                        default="./../../data/processed/",
                        help='Output data folder')
    parser.add_argument('--nTime', type=int, nargs='?', default=2000,
                        help='Number of timesteps to include in snapshots')
    parser.add_argument('--offset', type=int, nargs='?', default=0,
                        help='At which time level to start taking snapshots')
    parser.add_argument('--field_names', type=list, nargs='?',
                        default=['Velocity'],
                        help='Names of fields to include from vtu data file')
    parser.add_argument('--nGrids', type=int, nargs='?', default=4,
                        help='Number of grids of decomposed domain, 1 or 4')
    parser.add_argument('--xlength', type=float, nargs='?', default=2.2,
                        help='Length of interpolated domain in x')
    parser.add_argument('--ylength', type=float, nargs='?', default=0.41,
                        help='Length of interpolated domain in y')
    parser.add_argument('--nloc', type=int, nargs='?', default=3,
                        help='Number of local nodes')
    parser.add_argument('--nScalar', type=int, nargs='?', default=2,
                        help='Dimension of fields')
    parser.add_argument('--nDim', type=int, nargs='?', default=2,
                        help='Dimension of problem.')
    args = parser.parse_args()

    arg_dict = vars(args)

    get_pod_coeffs(**arg_dict)