import copy
import json

import httpretty
from datahub.access.tests.fixture import conftest
from datahub.access.tests.fixture.db import *  # noqa
from datahub.access.tests.mock_api import cc
from datahub.access.tests.modules.collector.conftest import (
    common_inner_error,
    common_param_error,
    common_success,
)
from datahub.access.tests.utils import get, post
from datahub.databus.tests.fixture.channel_fixture import add_channel  # noqa
from datahub.databus.tests.mock_api import config_server, meta
from datahub.databus.tests.mock_api.meta import get_inland_tag_ok
from datahub.storekit.tests.utils.conftest import mock_meta_content_language_configs

from datahub.databus import model_manager

param = {
    "bk_app_secret": "xxx",
    "bkdata_authentication_method": "user",
    "bk_app_code": "bk_dataweb",
    "bk_username": "admin",
    "data_scenario": "db",
    "bk_biz_id": 2,
    "description": "xx",
    "access_raw_data": {
        "raw_data_name": "db_new_01",
        "maintainer": "xxxx",
        "raw_data_alias": "asdfsaf",
        "data_source": "svr",
        "data_encoding": "UTF-8",
        "sensitivity": "private",
        "description": "xxxxx",
    },
    "access_conf_info": {
        "collection_model": {
            "collection_type": "time",
            "start_at": 0,
            "period": 1,
            "time_format": "yyyy-MM-dd HH:mm:ss",
            "increment_field": "create_at",
            "before_time": 100,
        },
        "filters": [
            {
                "op": "=",
                "logic_op": "and",
                "key": "key",
                "value": "val",
            }
        ],
        "resource": {
            "scope": [
                {
                    "db_host": "test.db.com",
                    "db_port": 10000,
                    "db_user": "user",
                    "db_pass": "pwd",
                    "db_name": "db_name",
                    "table_name": "table_name",
                    "db_type_id": 1,
                }
            ]
        },
    },
}

@pytest.mark.usefixtures("init_access_manager_config")
@pytest.mark.usefixtures("init_host_config_type")
@pytest.mark.usefixtures("add_channel")
@pytest.mark.django_db
def test_ok(mocker):
    """
    :return:
    """
    __mock_deploy_obj(mocker)

    res = post("/v3/access/deploy_plan/", param)

    want = {
        "code": "1500200",
        "message": "ok",
        "errors": None,
        "data": {"raw_data_id": 123},
        "result": True,
    }
    assert json.dumps(res, sort_keys=True) == json.dumps(want, sort_keys=True)

@pytest.mark.usefixtures("init_access_manager_config")
@pytest.mark.usefixtures("init_host_config_type")
@pytest.mark.django_db
def test_get_db_type_error():
    """
    :return:
    """
    httpretty.enable()
    httpretty.reset()
    conftest.mock_user_perm("admin")
    conftest.mock_app_perm("bk_dataweb")
    conftest.mock_create_data_id()
    conftest.mock_get_data_id("db")
    conftest.mock_get_mysql_type_error()

    res = post("/v3/access/deploy_plan/", param)

    common_inner_error(res)

@pytest.mark.usefixtures("init_access_manager_config")
@pytest.mark.usefixtures("init_host_config_type")
@pytest.mark.django_db
def test_access_db_type_url_down():
    """
    :return:
    """
    httpretty.enable()
    httpretty.reset()
    conftest.mock_user_perm("admin")
    conftest.mock_app_perm("bk_dataweb")
    conftest.mock_create_data_id()
    conftest.mock_get_data_id("db")

    res = post("/v3/access/deploy_plan/", param)

    assert not res["result"]

@pytest.mark.usefixtures("init_access_manager_config")
@pytest.mark.usefixtures("init_host_config_type")
@pytest.mark.usefixtures("add_channel")
@pytest.mark.django_db
def test_wrong_db_host(mocker):
    """
    :return:
    """
    __mock_deploy_obj(mocker)

    wrong_param = copy.deepcopy(param)
    wrong_param["db_host"] = "127.0.0.1:3306"
    wrong_param["access_conf_info"]["resource"]["scope"][0]["db_host"] = "127.0.0.1:3306"
    res = post("/v3/access/deploy_plan/", wrong_param)

    common_param_error(res, "db_host")

@pytest.mark.usefixtures("init_access_manager_config")
@pytest.mark.usefixtures("init_host_config_type")
@pytest.mark.usefixtures("add_channel")
@pytest.mark.django_db
def test_wrong_poll_type(mocker):
    __mock_deploy_obj(mocker)

    wrong_param = copy.deepcopy(param)
    wrong_param["access_conf_info"]["collection_model"]["collection_type"] = "unknown"
    res = post("/v3/access/deploy_plan/", wrong_param)
    common_param_error(res, "collection_type")

@pytest.mark.usefixtures("init_access_manager_config")
@pytest.mark.usefixtures("init_host_config_type")
@pytest.mark.usefixtures("add_channel")
@pytest.mark.django_db
def test_wrong_poll_type_param(mocker):
    __mock_deploy_obj(mocker)

    wrong_param = copy.deepcopy(param)
    del wrong_param["access_conf_info"]["collection_model"]["increment_field"]
    wrong_param["access_conf_info"]["collection_model"]["collection_type"] = "pri"
    res = post("/v3/access/deploy_plan/", wrong_param)
    common_param_error(res, "increment_field")

    wrong_param["access_conf_info"]["collection_model"]["period"] = 0
    res = post("/v3/access/deploy_plan/", wrong_param)
    common_param_error(res, "period")

    wrong_param = copy.deepcopy(param)
    del wrong_param["access_conf_info"]["collection_model"]["increment_field"]
    res = post("/v3/access/deploy_plan/", wrong_param)
    common_param_error(res, "increment_field")

    wrong_param = copy.deepcopy(param)
    wrong_param["access_conf_info"]["filters"][0]["op"] = "xx"
    res = post("/v3/access/deploy_plan/", wrong_param)
    common_param_error(res, "op")

@pytest.mark.usefixtures("init_access_manager_config")
@pytest.mark.usefixtures("init_host_config_type")
@pytest.mark.usefixtures("add_channel")
@pytest.mark.django_db
def test_wrong_time_format(mocker):
    __mock_deploy_obj(mocker)

    conftest.mock_db_data_get_task_ip_log('[{"create_at": "111:11 111"}]')

    res = post("/v3/access/deploy_plan/", param)

    common_param_error(res, "time_format")

@pytest.mark.usefixtures("init_access_manager_config")
@pytest.mark.usefixtures("init_host_config_type")
@pytest.mark.usefixtures("add_channel")
@pytest.mark.usefixtures("init_access_time_db_resource")
@pytest.mark.django_db
def test_get_resource(mocker):
    """
    :return:
    """
    __mock_deploy_obj(mocker)

    res = get("/v3/access/deploy_plan/123/?bk_username=admin")
    common_success(res)

def __mock_deploy_obj(mocker):
    httpretty.enable()
    httpretty.reset()
    conftest.mock_user_perm("admin")
    conftest.mock_app_perm("bk_dataweb")
    conftest.mock_create_data_id()
    conftest.mock_create_data_auth()
    conftest.mock_get_data_auth()
    conftest.mock_create_alert()
    conftest.mock_get_data_id("db")
    conftest.mock_fast_execute_script()
    conftest.mock_db_get_task_ip_log()
    conftest.mock_get_mysql_type()
    conftest.mock_databus_task_puller()
    cc.get_biz_location_ok()
    cc.get_tag_target_ok()
    get_inland_tag_ok()
    mock_meta_content_language_configs()
    meta.post_sync_hook_ok()
    meta.get_dm_category_ok()
    config_server.post_add_route_ok()

    mocker.patch(
        "datahub.access.collectors.base_collector.BaseAccess.check_perm_by_scenario",
        return_value=True,
    )
    mocker.patch("datahub.access.tags.create_tags", return_value=True)
    mocker.patch("datahub.access.handlers.puller.DatabusPullerHandler.create", return_value=True)
    outer_channel = model_manager.get_channel_by_id(1002)
    assert outer_channel
    mocker.patch(
        "datahub.access.raw_data.rawdata.generate_raw_data_channel_id",
        return_value=(1002, outer_channel),
    )
    mocker.patch(
        "common.auth.check_perm",
        return_value=True,
    )
    mocker.patch(
        "datahub.access.handlers.v3.paas.PaasHandler.get_app_name_by_code",
        return_value=None,
    )
    mocker.patch(
        "datahub.databus.task.puller_task.process_puller_task",
        return_value=None,
    )


import logging
from unittest import TestCase

from tests.st.utils.utils import (get_ip, wipe_etcdv2, wipe_etcdv3,
                                  set_version_etcdv2, set_ready_etcdv2, get_value_etcdv2)

HOST_IPV4 = get_ip()

logging.basicConfig(level=logging.DEBUG, format="%(message)s")
logger = logging.getLogger(__name__)

class TestBase(TestCase):
    """
    Base class for test-wide methods.
    """

    def setUp(self):
        """
        Clean up before every test.
        """
        self.ip = HOST_IPV4
        self.wipe_etcdv2()
        self.wipe_etcdv3()
        minimum_starting_state()

        # Log a newline to ensure that the first log appears on its own line.
        logger.info("")

    def wipe_etcdv2(self):
        wipe_etcdv2(self.ip)

    def wipe_etcdv3(self):
        wipe_etcdv3(self.ip)

def minimum_starting_state():
    logger.debug("INFO: Setting minimum starting state config for calicoctl v1")
    set_version_etcdv2("v2.6.6-2-g0f0e2184")
    set_ready_etcdv2("true")
    ready_output = get_value_etcdv2("/calico/v1/Ready")
    assert ready_output == "true"


from flask import Flask
from flask import render_template, jsonify, request, g, abort, redirect, url_for

import json

#from xinui.rest import Rest
from rest import Rest

app = Flask(__name__)

global_flow_table = {}

# Summary page
@app.route("/")
def summary():
    sw_desc = Rest.get_switch_desc()
    if sw_desc is False:
        abort(404)
    return render_template("summary.html", sw_desc=sw_desc)

# Policy page
@app.route("/policy/")
def policy():
    sw_dpid_list = Rest.get_switch_list()

    if sw_dpid_list is False:
        abort(404)

    return render_template("policy.html", sw_dpid_list=sw_dpid_list)

@app.route("/policy/<dpid>")
def dpid_policy(dpid):
    sw_dpid_list = Rest.get_switch_list()

    if sw_dpid_list is False or int(dpid) not in sw_dpid_list:
        abort(404)

    flow_table = None
    flow_table = Rest.get_flow_table(dpid)
    global global_flow_table
    global_flow_table = flow_table
    port = Rest.get_switch_port(dpid)

    return render_template("policy.html", sw_dpid_list=sw_dpid_list, dpid=dpid, port=port, flow_table=flow_table)

# Topology page
@app.route("/topology")
def topology():
    topo = Rest.get_topology()
    return render_template("topology.html", topo=topo)

@app.route("/_query_flow/")
def query_flow(dpid):
    #dpid = request.args.get("dpid")
    flow_table = Rest.get_flow_table(dpid)

    #print flow_table

    return render_template("policy.html", flow_table=flow_table)
    #return jsonify(flow_table)

@app.route("/_query_port")
def query_port():
    dpid = request.args.get("dpid")
    port = Rest.get_switch_port(dpid)

    return jsonify(port)

@app.route("/_add_flow", methods=["POST"])
def add_flow():
    req = json.loads(request.form["flow_cmd"])

    flow_cmd = {}
    match_dict = {}
    action_list = []

    flow_cmd["dpid"] = req["common"]["dpid"]
    flow_cmd["priority"] = req["common"]["priority"]
    flow_cmd["idle_timeout"] = req["common"]["idle"]
    flow_cmd["hard_timeout"] = req["common"]["hard"]

    if req["match"]["input"] != "Any":
        match_dict["in_port"] = int(req["match"]["input"])

    if req["match"]["dl_saddr"] != "None":
        match_dict["dl_src"] = req["match"]["dl_saddr"]

    if req["match"]["dl_daddr"] != "None":
        match_dict["dl_dst"] = req["match"]["dl_daddr"]

    if req["match"]["nw_saddr"] != "None":
        match_dict["nw_src"] = req["match"]["nw_saddr"]

    if req["match"]["nw_daddr"] != "None":
        match_dict["nw_dst"] = req["match"]["nw_daddr"]

    if req["match"]["nw_saddr"] != "None" or req["match"]["nw_daddr"] != "None" or req["match"]["l4_proto"]:
        match_dict["dl_type"] = 2048

    if req["match"]["l4_proto"] != "None":
        if req["match"]["l4_proto"] == "TCP":
            match_dict["nw_proto"] = 6
        elif req["match"]["l4_proto"] == "UDP":
            match_dict["nw_proto"] = 17

    if req["match"]["sport"] != "None":
        match_dict["tp_src"] = int(req["match"]["sport"])

    if req["match"]["dport"] != "None":
        match_dict["tp_dst"] = int(req["match"]["dport"])

    if req["match"]["vlan_id"] != "None":
        match_dict["dl_vlan"] = int(req["match"]["vlan_id"])

    if req["action"]["output"] != "Drop":
        for value in req["action"]["output"].split(" "):
            action_dict = {}
            action_dict["port"] = int(value)
            action_dict["type"] = "OUTPUT"
            action_list.append(action_dict)

    if req["action"]["vlan_action"] != "None":
        if "Strip" in req["action"]["vlan_action"]:
            action_dict = {}
            action_dict["type"] = "POP_VLAN"
            action_list.append(action_dict)
        elif "Swap" in req["action"]["vlan_action"]:
            action_dict = {}
            action_dict["field"] = "vlan_vid"
            action_dict["value"] = req["action"]["vlan_action"].split(" ")[-1]
            action_dict["type"] = "SET_FIELD"
            action_list.append(action_dict)
        elif "New" in req["action"]["vlan_action"]:
            push_vlan_dict = {}
            push_vlan_dict["ethertype"] = 33024
            push_vlan_dict["type"] = "PUSH_VLAN"
            action_list.append(push_vlan_dict)

            action_dict = {}
            action_dict["field"] = "vlan_vid"
            action_dict["value"] = req["action"]["vlan_action"].split(" ")[-1]
            action_dict["type"] = "SET_FIELD"
            action_list.append(action_dict)

    flow_cmd["match"] = match_dict
    flow_cmd["actions"] = action_list

    #print json.dumps(flow_cmd)
    Rest.add_flow(json.dumps(flow_cmd))

    return "foo"

@app.route("/_del_flow", methods=["POST"])
def del_flow():
    index = request.form["index"]

    flow_cmd = {}
    match_dict = {}

    for key, list in global_flow_table.iteritems():
        flow_cmd["dpid"] = key
        match_dict = list[int(index)]["match"]

    flow_cmd["match"] = match_dict
    #print json.dumps(flow_cmd)

    Rest.del_flow(json.dumps(flow_cmd))
    return "foo"

@app.errorhandler(404)
def page_not_found(error):
    return render_template("page_not_found.html"), 404

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5566, debug=False)


# -*- coding: utf-8 -*-
"""Tests of the Scheduling Block Instance List API."""
from .workflow_test_utils import add_test_sbi_workflow_definitions
from .. import ProcessingBlock, ProcessingBlockList, \
    SchedulingBlockInstanceList, Subarray
from ... import ConfigDb
from ...utils.generate_sbi_config import generate_sbi_config

DB = ConfigDb()

def test_sbi_list_create():
    """Test creating a SBI list object."""
    sbi_list = SchedulingBlockInstanceList()
    assert sbi_list is not None

def test_sbi_list_add_sbi():
    """Test adding SBI data to the EC configuration DB."""
    DB.flush_db()
    subarray = Subarray(1)
    subarray.activate()

    sbi_config = generate_sbi_config(num_pbs=1)
    add_test_sbi_workflow_definitions(sbi_config)

    sbi_list = SchedulingBlockInstanceList()
    sbi_events = sbi_list.subscribe('test_sbi_list_subscriber')

    sbi = sbi_list.add(sbi_config)

    assert sbi_list.num_active == 1
    assert sbi_list.active[0] == sbi_config['id']

    assert sbi.id == sbi_config['id']
    assert sbi.num_processing_blocks == 1

    published = sbi_events.get_published_events()
    assert len(published) == 1
    assert published[0].type == 'status_changed'
    assert published[0].data.get('status') == 'created'
    assert published[0].object_id == sbi.id
    assert published[0].object_type == sbi.type
    assert sbi.status == 'created'

def test_sbi_list_abort():
    """Test cancelling SBI data."""
    DB.flush_db()
    # import sip_logging
    # print('')
    # init_logger(log_level='DEBUG')

    sbi_config = generate_sbi_config()
    add_test_sbi_workflow_definitions(sbi_config)

    sbi_list = SchedulingBlockInstanceList()
    pb_list = ProcessingBlockList()

    sbi_events = sbi_list.subscribe('test_sbi_subscriber')
    pb_events = pb_list.subscribe('test_pb_subscriber')

    # Add the SBI to the database
    sbi = sbi_list.add(sbi_config)

    # Abort the SBI
    sbi.abort()

    # Check that the SBI has been aborted.
    sbi_events = sbi_events.get_published_events()
    assert sbi_events[-1].type == 'status_changed'
    assert sbi_events[-1].data['status'] == 'aborted'
    assert sbi.status == 'aborted'
    assert sbi_list.num_aborted == 1
    assert sbi_list.aborted[0] == sbi.id

    # Check that the PBs associated with the SBI have also been aborted
    pb_events = pb_events.get_published_events()
    for i in range(sbi.num_processing_blocks):
        assert pb_events[-1 - i].type == 'status_changed'
        assert pb_events[-1 - i].data['status'] == 'aborted'
    assert sbi.num_processing_blocks == 3
    assert pb_list.num_aborted == 3

    for pb_id in sbi.processing_block_ids:
        assert pb_id in pb_list.aborted
        pb = ProcessingBlock(pb_id)
        assert pb.get_events()[-1].type == 'status_changed'
        assert pb.get_events()[-1].data['status'] == 'aborted'

def test_sbi_list_get_active():
    """Test method to get active SBI"""
    DB.flush_db()
    sbi_list = SchedulingBlockInstanceList()
    pb_list = ProcessingBlockList()
    sbi_list.subscribe('test_add_sbi')
    sbi_config = generate_sbi_config()

    # Register test workflow definitions needed for this SBI.
    add_test_sbi_workflow_definitions(sbi_config)

    sbi = sbi_list.add(sbi_config)
    active_sbi = sbi_list.active
    assert active_sbi[0] == sbi_config['id']

    # Test active PB
    active_pb = pb_list.active
    assert active_pb[0] in sbi.processing_block_ids


#Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import tensorflow as tf
from petastorm import make_batch_reader
import pathlib

import warnings
warnings.filterwarnings("ignore")

from recommendator.input.input import Input
from recommendator.CollaborativeGRUCell.model import CollaborativeRNNModel, CollaborativeRNN2RecConfig

def fit_(model,
         epochs,
         train_path,
         valid_path,
         shuffle,
         steps_per_epoch,
         validation_steps,
         lr,
         verbose):
        """Trains the model for a fixed number of epochs (iterations on a dataset).

        epochs: Integer. Number of epochs to train the model.
            An epoch is an iteration over the entire `x` and `y`
            data provided. Note that in conjunction with `initial_epoch`,
            `epochs` is to be understood as "final epoch".
            The model is not trained for a number of iterations
            given by `epochs`, but merely until the epoch
            of index `epochs` is reached.
        train_path: Path of parquet file of training data for petastorm execution.
        valid_path: Path of parquet file of validation data for petastorm execution.
        shuffle: Randomly shuffles the elements of this dataset.
       steps_per_epoch: Integer or `None`.
            Total number of steps (batches of samples)
            before declaring one epoch finished and starting the
            next epoch. When training with input tensors such as
            TensorFlow data tensors, the default `None` is equal to
            the number of samples in your dataset divided by
            the batch size, or 1 if that cannot be determined. If x is a
            `tf.data` dataset, and 'steps_per_epoch'
            is None, the epoch will run until the input dataset is exhausted.
            This argument is not supported with array inputs.
        validation_steps: Only relevant if `validation_data` is provided and
            is a `tf.data` dataset. Total number of steps (batches of
            samples) to draw before stopping when performing validation
            at the end of every epoch. If validation_data is a `tf.data` dataset
            and 'validation_steps' is None, validation
            will run until the `validation_data` dataset is exhausted.
        lr: learning rate of the given optimizer
        verbose: 0, 1, or 2. Verbosity mode.
            0 = silent, 1 = progress bar, 2 = one line per epoch.
            Note that the progress bar is not particularly useful when
            logged to a file, so verbose=2 is recommended when not running
            interactively (eg, in a production environment).
        """
        model.compile(
            loss=tf.losses.sparse_categorical_crossentropy,
            optimizer=tf.optimizers.RMSprop(lr=lr),
            metrics=['sparse_categorical_accuracy'])

        with make_batch_reader(train_path, num_epochs=None) as reader_train:
            with make_batch_reader(valid_path, num_epochs=None) as reader_validation:

                train_dataset = Input.get_dataset(
                    reader_train,
                    shuffle=shuffle,
                    batch=model.config.batch_size)

                test_dataset = Input.get_dataset(
                    reader_validation,
                    shuffle=shuffle,
                    batch=model.config.batch_size)

                model.fit(
                    train_dataset,
                    epochs=epochs,
                    steps_per_epoch=steps_per_epoch,
                    validation_data=test_dataset,
                    validation_steps=validation_steps,
                    verbose=verbose)

def create_optimizer(
        init_lr,
        num_train_steps,
        num_warmup_steps=None):
    """Creates an optimizer training op."""
    global_step = tf.Variable(1, name="global_step")

    learning_rate = tf.constant(value=init_lr, shape=[], dtype=tf.float32)

    # Implements linear decay of the learning rate.
    learning_rate = tf.compat.v1.train.polynomial_decay(
        learning_rate=learning_rate,
        global_step= global_step,
        decay_steps= num_train_steps,
        end_learning_rate=0.0,
        power=1.0,
        cycle=False)

    # Implements linear warmup. I.e., if global_step < num_warmup_steps, the
    # learning rate will be `global_step/num_warmup_steps * init_lr`.
    if num_warmup_steps:
        global_steps_int = tf.cast(global_step, tf.int32)
        warmup_steps_int = tf.constant(num_warmup_steps, dtype=tf.int32)

        global_steps_float = tf.cast(global_steps_int, tf.float32)
        warmup_steps_float = tf.cast(warmup_steps_int, tf.float32)

        warmup_percent_done = global_steps_float / warmup_steps_float
        warmup_learning_rate = init_lr * warmup_percent_done

        is_warmup = tf.cast(global_steps_int < warmup_steps_int, tf.float32)
        learning_rate = ((1.0 - is_warmup) * learning_rate +
                         is_warmup * warmup_learning_rate)

    # It is recommended that you use this optimizer for fine tuning, since this
    # is how the model was trained (note that the Adam m/v variables are NOT
    # loaded from init_checkpoint.)
    optimizer = tf.compat.v1.train.RMSPropOptimizer(learning_rate=learning_rate)

    new_global_step = global_step + 1
    return optimizer

@tf.function
def train_step(model, optimizer, features, targets):
    # keep track of our gradients

    with tf.GradientTape() as tape:
        # make a prediction using the model and then calculate the
		# loss
        pred = model(features)
        loss = tf.keras.losses.sparse_categorical_crossentropy(targets, pred)

    grads = tape.gradient(loss, model.trainable_variables)
    # calculate the gradients using our tape and then update the
    # model weights
    optimizer.apply_gradients(zip(grads, model.trainable_variables))
    return loss

def training(epochs):
    for epoch in range(epochs):
        epoch_loss_avg = tf.keras.metrics.Mean()
        epoch_accuracy = tf.keras.metrics.SparseCategoricalAccuracy()
        with make_batch_reader(train_path, num_epochs=5) as reader_train:
            train_dataset = Input.get_dataset(
                reader_train,
                shuffle=10,
                batch=model.config.batch_size)

            # Training loop - using batches of 32
            for x, y in train_dataset:
                # Optimize the model
                loss_value = train_step(model, optimizer, x, y)

                # Track progress
                epoch_loss_avg.update_state(loss_value)  # Add current batch loss
                # Compare predicted label to actual label
                # training=True is needed only if there are layers with different
                # behavior during training versus inference (e.g. Dropout).
                epoch_accuracy.update_state(y, model(x, training=True))

            # End epoch
            train_loss_results.append(epoch_loss_avg.result())
            train_accuracy_results.append(epoch_accuracy.result())

            tf.print("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", epoch)

            if epoch % 2 == 0:
                tf.print("Epoch {:03d}: Loss: {:.3f}, Accuracy: {:.3%}".format(epoch,
                                                                            epoch_loss_avg.result(),
                                                                            epoch_accuracy.result()))
optimizer=create_optimizer(
        init_lr=0.035,
        num_train_steps=100)

def training2(epochs, num_of_iters):
    epoch_loss_avg = tf.keras.metrics.Mean()
    epoch_accuracy = tf.keras.metrics.SparseCategoricalAccuracy()
    with make_batch_reader(train_path, num_epochs=None) as reader_train:
        train_dataset = Input.get_dataset(
            reader_train,
            shuffle=10,
            batch=model.config.batch_size)

        epoch_steps = 0

        for epoch in range(epochs):
            for iteration, (input, target) in enumerate(train_dataset):
                # Break if the number of computed batches exceeds the
                # total number of the examples
                if iteration % num_of_iters==0 and iteration >0:
                    epoch_steps+=1
                    train_loss_results.append(epoch_loss_avg.result())
                    train_accuracy_results.append(epoch_accuracy.result())
                    if epoch_steps % 2 == 0:
                        print("Epoch {:03d}: Loss: {:.3f}, Accuracy: {:.3%}".format(epoch_steps,
                                                                                epoch_loss_avg.result(),
                                                                                epoch_accuracy.result()))
                    break
                # HERE WE PERFORM ONE TRAINING STEP

                loss_value = train_step(model, optimizer, input, target)

                # Track progress
                epoch_loss_avg.update_state(loss_value)  # Add current batch loss
                # Compare predicted label to actual label
                # training=True is needed only if there are layers with different
                # behavior during training versus inference (e.g. Dropout).
                epoch_accuracy.update_state(target, model(input, training=True))

config_data = {
    'user_size': 5,
    'item_size': 10,
    'batch_size': 5,
    'chunk_size': 64,
    'num_hidden_layers': 128
}

train_path = 'file:/' + str(pathlib.Path().absolute()) \
          .replace("\\", "/") \
          .replace("C:/", "//") \
          .replace("/home", "//home") \
          .replace("CollaborativeGRUCell", 'input/data/train/train_data.parquet')

valid_path = 'file:/' + str(pathlib.Path().absolute()) \
          .replace("\\", "/") \
          .replace("C:/", "//") \
          .replace("/home", "//home") \
          .replace("CollaborativeGRUCell", 'input/data/train/valid_data.parquet')

train_config_data={
    'epochs' : 100,
    'train_path' : train_path,
    'valid_path' : valid_path,
    'shuffle' : 10,
    'steps_per_epoch' : 40,
    'validation_steps' : 10,
    'lr' : 0.05,
    'verbose' : 2
}

config=CollaborativeRNN2RecConfig.from_dict(config_data)
model=CollaborativeRNNModel(config=config)

# Keep results for plotting
train_loss_results = []
train_accuracy_results = []

training2(tf.constant(100, tf.int64), tf.constant(2, tf.int64))


import os
import sys
import unittest

import numpy as np
import torch

from torch.nn import functional as torch_F
from src.cranet.nn import functional as cranet_F

from src import cranet

from ..utils import teq

class TestDropout(unittest.TestCase):
    def test_dropout_0(self):
        a = np.random.rand(3, 3)
        a_d = cranet.Tensor(a, requires_grad=True)
        b_d = cranet_F.dropout(a_d)
        print(b_d)
        self.assertTrue(b_d.shape == (3, 3))
        g = np.random.rand(3, 3)
        g_d = cranet.Tensor(g)
        b_d.backward(g_d)
        print(a_d.grad)

class TestMaxPool2d(unittest.TestCase):
    def test_max_pool_0(self):
        a = np.random.rand(5, 3, 8, 8)
        a_d = cranet.Tensor(a, requires_grad=True)
        a_t = torch.tensor(a, requires_grad=True)
        b_t = torch_F.max_pool2d(a_t, 2, 2)
        b_d = cranet_F.max_pool2d(a_d, 2, 2)
        self.assertTrue(teq(b_d, b_t))
        g = np.random.rand(5, 3, 4, 4)
        b_t.backward(torch.tensor(g))
        b_d.backward(cranet.Tensor(g))
        self.assertTrue(teq(a_d.grad, a_t.grad))

    def test_max_pool_1(self):
        a = np.random.rand(5, 3, 32, 32)
        a_d = cranet.Tensor(a, requires_grad=True)
        a_t = torch.tensor(a, requires_grad=True)
        b_t = torch_F.max_pool2d(a_t, 2, 2)
        b_d = cranet_F.max_pool2d(a_d, 2, 2)
        self.assertTrue(teq(b_d, b_t))
        g = np.random.rand(5, 3, 16, 16)
        b_t.backward(torch.tensor(g))
        b_d.backward(cranet.Tensor(g))
        self.assertTrue(teq(a_d.grad, a_t.grad))

class TestFlatten(unittest.TestCase):
    def test_0(self):
        a = cranet.zeros((3, 4, 5, 6, 7, 8, 9))
        b = cranet_F.flatten(a)
        self.assertTrue(b.shape == (3, 4 * 5 * 6 * 7 * 8 * 9))

    def test_1(self):
        a = cranet.zeros((1, 2, 3, 4, 5, 6, 7, 8, 9))
        b = cranet_F.flatten(a, 2, -2)
        self.assertTrue(b.shape == (1, 2, 3 * 4 * 5 * 6 * 7 * 8, 9))

if __name__ == '__main__':
    sys.path.append(os.getcwd())
    unittest.main()


'''
https://leetcode.com/problems/count-number-of-homogenous-substrings/
Given a string s, return the number of homogenous substrings of s. Since the answer may be too large, return it modulo 109 + 7.
A string is homogenous if all the characters of the string are the same.
A substring is a contiguous sequence of characters within a string.

Example 1:
Input: s = "abbcccaa"
Output: 13
Explanation: The homogenous substrings are listed as below:
"a"   appears 3 times.
"aa"  appears 1 time.
"b"   appears 2 times.
"bb"  appears 1 time.
"c"   appears 3 times.
"cc"  appears 2 times.
"ccc" appears 1 time.
3 + 1 + 2 + 1 + 3 + 2 + 1 = 13.
'''
class Solution:
    def countHomogenous(self, s: str) -> int:
        if not s:
            return 0
        i, j = 0, 0
        res = 0
        while j<len(s):
            while j<len(s) and s[i]==s[j]:
                j += 1
            length = j-i
            n = 0
            for num in range(1, length+1):
                n += num
            res += n
            i = j
        return mod(res, 10**9+7)

1759. Count Number of Homogenous Substrings.py


import discord
from discord.ext import commands
from mcstatus import MinecraftServer
from lib import configurator
import asyncio

class MCStatus:

    def __init__(self, bot):
        self.bot = bot
        self.servers = configurator.getList('minecraft_servers', ['nerd.nu'])

    @commands.command()
    async def status(self):
        """Checks the status of configured Minecraft servers"""
        response = "```\n"
        for server in self.servers:
            response += await self.ping(server) + "\n"
        response += "```\n"
        await self.bot.say(response)

    async def ping(self, host):
        try:
            server = MinecraftServer(host, 25565)
            status = server.status()
            return "{0} [{1}/{2}]".format(host, status.players.online, status.players.max)
        except Exception as e:
            return "{0} seems to be down".format(host)

def setup(bot):
    bot.add_cog(MCStatus(bot))


from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import render
from django.views.generic import ListView, DetailView

from expenses.forms import NewQuickExpenseForm
from expenses.models import Expense

@login_required
def home_page(request):
    new_quick_expense_form = NewQuickExpenseForm(data=request.POST if request.POST else None,
                                                 initial={'paid_by': request.user, 'added_by': request.user})

    if request.POST and new_quick_expense_form.is_valid():
        new_quick_expense_form.save()
        new_quick_expense_form = NewQuickExpenseForm()

    recent_expenses = Expense.objects.order_by('-last_edited')[:10]
    return render(request, 'home.html', context={'form': new_quick_expense_form, 'recent_expenses': recent_expenses})

class ExpenseListView(LoginRequiredMixin, ListView):
    queryset = Expense.objects.order_by("-date")
    context_object_name = 'expenses'

class ExpenseDetailView(LoginRequiredMixin, DetailView):
    queryset = Expense.objects.all()


from rest_framework import serializers
from users.models import User

from .models import Review

class CriticSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'first_name', 'last_name']

class ReviewSerializer(serializers.ModelSerializer):
    critic = CriticSerializer(read_only=True)

    class Meta:
        model = Review
        fields = ['id', 'stars', 'review', 'spoilers', 'recommendation','critic', 'movie_id']
        read_only_fields = ['id', 'movie_id', 'critic']
        extra_kwargs = {'stars': {'max_value':10, 'min_value':1}}

    def create(self, validated_data):
        review = Review.objects.create(**validated_data)

        return review


import pygame
import Globals

#initializing the pygame font module !REQUIRED FOR FONT TO WORK!

pygame.font.init()

#Universal class for creating buttons
class Button():
    #Initiallizing the button
    def __init__(self, color, x, y, width, height, text='', textColour = Globals.WHITE, font = pygame.font.SysFont('comicsans', 60)):
        self.font = font
        self.color = color
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.text = text
        self.textColour = textColour

    #drawing the button to a screen, I reused this from a few mini python challenges i did over the summer break and am currently working on
    #which is why their are some unused variables and classes.
    def draw(self, win, background=None, outline=None):
        # Call this method to draw the button on the screen
        #if the outline is defined
        if outline:
            pygame.draw.rect(win, outline, (self.x - 2, self.y - 2, self.width + 4, self.height + 4), 0)
        #if the background is not defined
        if background == None:
            pygame.draw.rect(win, self.color, (self.x, self.y, self.width, self.height), 0)
        #if the backgound is defined (Note backgound should be an image)
        else:
            #Scaling the image
            image = pygame.transform.scale(background, (self.width, self.height))
            #turning the image into a rect
            rect = image.get_rect()
            #centering the image
            rect.center = (self.x+self.width/2, self.y+self.height/2)
            #displaying the image
            win.blit(image, rect)

        #if text has been defined
        if self.text != '':
            #setting up the font
            font = self.font
            #creating the text
            text = font.render(self.text, 1, self.textColour)
            #displaying the text to screen
            win.blit(text, (
            self.x + (self.width / 2 - text.get_width() / 2), self.y + (self.height / 2 - text.get_height() / 2)))

    #if a given x and y coord is over the button. This was intended for a mouse, but could also be used as an event trigger box in gain.
    #i.e. if a player moves inside a button
    def isOver(self, pos):
        # Pos is the mouse position or a tuple of (x,y) coordinates
        if pos[0] > self.x and pos[0] < self.x + self.width:
            if pos[1] > self.y and pos[1] < self.y + self.height:
                return True

        return False

#Universal Class For Text
class Text():
    def __init__(self, font, color, pos, surface, text):
        self.Font_Font = font
        self.Font_Color = color
        self.Font_Pos = pos
        self.Surface = surface
        self.Text = text

    #Draws text to display
    def Display(self):
        text = self.Font_Font.render(self.Text, 1, self.Font_Color)
        text_rect = text.get_rect(center = (self.Font_Pos))
        self.Surface.blit(text, text_rect)

class CheckBox():
    def __init__(self, pos, surface, scale, text, font, font_color):
        self.Pos = pos
        self.Scale = scale
        self.Surface = surface
        self.Sprite_Triggered = pygame.image.load("Assetts/UIObjects/Checkbox(Both).png")
        self.Sprite_Not_Triggered = pygame.image.load("Assetts/UIObjects/Checkbox(Background).png")
        self.Triggered = False
        self.Text = text
        self.Text_Font = font
        self.Text_Font_Color = font_color

    def Display(self):
        if self.Triggered:
            image = pygame.transform.scale(self.Sprite_Triggered, self.Scale)
            rect = image.get_rect()
            rect.center = (self.Pos[0] + self.Scale[0] / 2, self.Pos[1] + self.Scale[1] / 2)
            self.Surface.blit(image, rect)
        else:
            image = pygame.transform.scale(self.Sprite_Not_Triggered, self.Scale)
            rect = image.get_rect()
            rect.center = (self.Pos[0] + self.Scale[0] / 2, self.Pos[1] + self.Scale[1] / 2)
            self.Surface.blit(image, rect)
        if self.Text != '':
            text = self.Text_Font.render(self.Text, 1, self.Text_Font_Color)
            self.Surface.blit(text, (self.Pos[0] + (self.Scale[0] / 2 - text.get_width() / 2) - 200, self.Pos[1] + (self.Scale[1] / 2 - text.get_height() / 2)))

    def isOver(self, pos):
        if pos[0] > self.Pos[0] and pos[0] < self.Pos[0] + self.Scale[0]:
            if pos[1] > self.Pos[1] and pos[1] < self.Pos[1] + self.Scale[1]:
                return True
        return False


# -*- coding:utf-8 -*-
from decimal import Decimal

from model.order.order_goods_cs import OrderGoodsCSList
from model.order.order_price import OrderPrice

class OrderId:
    def __init__(self, value: int):
        self.value = value

class Order:
    def __init__(self,
                 order_id: OrderId,
                 order_goods_cs_list: OrderGoodsCSList,
                 order_price: OrderPrice):
        self.order_id = order_id
        self.order_goods_cs_list = order_goods_cs_list
        self.order_price = order_price

    def subtotal_without_tax(self) -> Decimal:
        return self.order_goods_cs_list.subtotal_without_tax()

    def tax(self) -> Decimal:
        return self.order_price.tax(self.subtotal_without_tax())

    def total(self) -> Decimal:
        return self.order_price.total(self.subtotal_without_tax())

    @staticmethod
    def create(order_dictionary: dict) -> 'Order':
        order_id = order_dictionary["order_id"]
        order_goods_cs_list = OrderGoodsCSList.create(order_dictionary["order_goods_cs_list"])
        order_price = OrderPrice.create(order_dictionary["use_point"])

        return Order(
            order_id,
            order_goods_cs_list,
            order_price
        )


import cv2
import numpy as np
import math
import pyautogui

# open the video file
cap = cv2.VideoCapture(0)

# create a window to display the frames
cv2.namedWindow('Hand Detection')

# create trackbars to adjust the lower and upper thresholds for the skin color detection
def nothing(x):
    pass

cv2.createTrackbar('Hue Lower', 'Hand Detection', 0, 255, nothing)
cv2.createTrackbar('Saturation Lower', 'Hand Detection', 20, 255, nothing)
cv2.createTrackbar('Value Lower', 'Hand Detection', 70, 255, nothing)
cv2.createTrackbar('Hue Upper', 'Hand Detection', 20, 255, nothing)
cv2.createTrackbar('Saturation Upper', 'Hand Detection', 255, 255, nothing)
cv2.createTrackbar('Value Upper', 'Hand Detection', 255, 255, nothing)

# Define constant values
MIN_ANGLE_THRESHOLD = 90
MIN_DISTANCE_THRESHOLD = 30

def detect_fingers(defects, approx, roi):
    """
    Detect fingers in an image of a hand.
    """
    finger_count = 0
    for i in range(defects.shape[0]):
        start_idx, end_idx, far_idx, _ = defects[i, 0]
        start = tuple(approx[start_idx][0])
        end = tuple(approx[end_idx][0])
        far = tuple(approx[far_idx][0])
        point = (100, 180)

        # Calculate lengths of sides of the triangle formed by the three points
        side_a = math.sqrt((end[0] - start[0]) ** 2 + (end[1] - start[1]) ** 2)
        side_b = math.sqrt((far[0] - start[0]) ** 2 + (far[1] - start[1]) ** 2)
        side_c = math.sqrt((end[0] - far[0]) ** 2 + (end[1] - far[1]) ** 2)

        # Calculate semiperimeter and area of triangle
        semiperimeter = (side_a + side_b + side_c) / 2
        area = math.sqrt(semiperimeter * (semiperimeter - side_a) * (semiperimeter - side_b) * (semiperimeter - side_c))

        # Calculate distance between point and convex hull
        distance = (2 * area) / side_a

        # Calculate angle between sides a and c
        cos_angle = (side_b ** 2 + side_c ** 2 - side_a ** 2) / (2 * side_b * side_c)
        angle = math.acos(cos_angle) * 57

        # Ignore angles greater than 90 degrees and points too close to the convex hull
        if angle <= MIN_ANGLE_THRESHOLD and distance > MIN_DISTANCE_THRESHOLD:
            finger_count += 1
            cv2.circle(roi, far, 3, [255, 0, 0], -1)

        # Draw lines around hand
        cv2.line(roi, start, end, [0, 255, 0], 2)

    finger_count= finger_count+1

    return finger_count
def display_finger_count(areacnt, arearatio, finger_count):
    if finger_count==1:
        if areacnt<2000:
            return 'Place hand in box'
        else:
            if arearatio<12:
                pyautogui.press('0 ')
                return '0'
            elif arearatio<17.5:
                pyautogui.press('Best of luck ')
                return 'Best of luck'
            else:
                pyautogui.press('1 ')
                return '1'
    elif finger_count==2:
        pyautogui.press('2 ')
        return '2'
    elif finger_count==3:
        if arearatio<27:
            pyautogui.press('3 ')
            return '3'
        else:
            pyautogui.press('ok ')
            return 'ok'
    elif finger_count==4:
        pyautogui.press('4 ')
        return '4'
    elif finger_count==5:
        pyautogui.press('5 ')
        return '5'
    else :
        return 'reposition'

while(cap.isOpened()):
    try:
    # read the next frame from the video file
        ret, frame = cap.read()
        if ret == False:
            break

    # flip the frame horizontally
        frame = cv2.flip(frame, 1)

    # define region of interest
        roi = frame[100:300, 100:300]

        cv2.rectangle(frame,(100,100),(300,300),(0,255,0),0)

    # get the trackbar values for the lower and upper thresholds
        h_l = cv2.getTrackbarPos('Hue Lower', 'Hand Detection')
        s_l = cv2.getTrackbarPos('Saturation Lower', 'Hand Detection')
        v_l = cv2.getTrackbarPos('Value Lower', 'Hand Detection')
        h_u = cv2.getTrackbarPos('Hue Upper', 'Hand Detection')
        s_u = cv2.getTrackbarPos('Saturation Upper', 'Hand Detection')
        v_u = cv2.getTrackbarPos('Value Upper', 'Hand Detection')

    # define range of skin color in HSV
        lower_skin = np.array([h_l, s_l, v_l], dtype=np.uint8)
        upper_skin = np.array([h_u, s_u, v_u], dtype=np.uint8)

    # extract skin color image
        hsv = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
        mask = cv2.inRange(hsv, lower_skin, upper_skin)

    # extrapolate the hand to fill dark spots within
        kernel = np.ones((3,3), np.uint8)
        dilation = cv2.dilate(mask, kernel, iterations=4)
        erosion = cv2.erode(dilation, kernel, iterations=4)

    # blur the image
        mask = cv2.GaussianBlur(mask, (5,5), 100)

    # find contours
        contours, hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    # find all contours with a significant area
        significant_contours = []
        for cnt in contours:
            area = cv2.contourArea(cnt)
            if area > 500:
                significant_contours.append(cnt)

   #find contour of max area(hand)
        cnt = max(significant_contours, key = lambda x: cv2.contourArea(x))

    #approx the contour a little
        epsilon = 0.0005*cv2.arcLength(cnt,True)
        approx= cv2.approxPolyDP(cnt,epsilon,True)

    #make convex hull around hand
        hull = cv2.convexHull(cnt)

     #define area of hull and area of hand
        areahull = cv2.contourArea(hull)
        areacnt = cv2.contourArea(cnt)

    #find the percentage of area not covered by hand in convex hull
        arearatio=((areahull-areacnt)/areacnt)*100

     #find the defects in convex hull with respect to hand
        hull = cv2.convexHull(approx, returnPoints=False)
        defects = cv2.convexityDefects(approx, hull)

        finger_count=detect_fingers(defects, approx, roi)

        #print corresponding gestures which are in their ranges
        font = cv2.FONT_HERSHEY_SIMPLEX
        result = display_finger_count(areacnt, arearatio, finger_count)
        cv2.putText(frame,result,(10,50), font, 2, (255,0,0), 3, cv2.LINE_AA)

    except:
        pass
    #show the window
    cv2.imshow('frame',frame)

    # Close the camera if 'q' is pressed
    if cv2.waitKey(1) == ord('q'):
        break

cv2.destroyAllWindows()
cap.release()


class Employee:
   no_of_leaves =8

   def __init__(self,aname,asalary,arole,aaddress):
       self.name=aname
       self.salary=asalary
       self.role=arole
       self.address=aaddress
   #def printdetails(self):
        #return f"This Employee name is {self.name},Employee salary is {self.salary},Employee role is {self.role}"
   #change method
   def from_dash(cls, string):
        return cls(*string.split('-'))

harry = Employee("HARRY POTTER",455,"ASSISTANT","MUMBAI")
karan = Employee.from_dash("KARAN-2000000-SELFASSISTANT-PUNE")

#harry.name = "HARRY POTTER"
#harry.salary = 455
#harry.role = "ASSISTANT"

print(harry.__dict__)
print(karan.salary)


# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reorderList(self, head: Optional[ListNode]) -> None:
        """
        Do not return anything, modify head in-place instead.
        """
        slow = head
        fast = head.next

        while fast and fast.next:                   #getting the middle node,as slow will be at middle, if fast goes out
            slow = slow.next
            fast = fast.next.next

        second = slow.next                          #separting the second half
        prev = slow.next = None

        while second:                               #reversing the second half
            temp = second.next
            second.next = prev
            prev = second
            second = temp

        first,second = head,prev
        while second:                               #merging 2nd half into 1st half
            temp1,temp2 = first.next,second.next    #storing next values to iterate forward
            first.next = second
            second.next = temp1
            first = temp1
            second=temp2

        #Time complexity: O(N). There are three steps here. To identify the middle node takes O(N) time. To reverse the         second part of the list, one needs N/2 operations. The final step, to merge two lists, requires N/2operations as         well. In total, that results in O(N) time complexity.

        #Space complexity: O(1), since we do not allocate any additional data structures.


__author__ = 'ANDRE'
#Bublesort recursivo
import random
#procedimento que gera massa de teste
def geramassa(numter):
    lista = []
    for i in range (0,numter):
        lista.append(random.randint(0,numter))
    return lista
#Bublesort forma recursiva
def rec_bublesrt(lista):
    for i in range(0,len(lista)-1):
        if lista[i] > lista [i+1]:
            lista[i],lista[i+1]=lista[i+1],lista[i]
            rec_bublesrt(lista)
    return lista

x = geramassa(20)
print(x)
print(rec_bublesrt(x))

Python2/PycharmProjects/Prova N1(1 PROVA)/PROVA N1(PROVA 1)/Questão 2.py


"""change category.typype from integer to string(64)

Revision ID: 4f55ce7eafdc
Revises: 4dd433b09fa6
Create Date: 2015-11-05 17:44:17.146765

"""

# revision identifiers, used by Alembic.
revision = '4f55ce7eafdc'
down_revision = '4dd433b09fa6'

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql

def upgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.alter_column('category', 'category_type',
               existing_type=mysql.INTEGER(display_width=11),
               type_=sa.String(length=64),
               existing_nullable=True)
    ### end Alembic commands ###

def downgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.alter_column('category', 'category_type',
               existing_type=sa.String(length=64),
               type_=mysql.INTEGER(display_width=11),
               existing_nullable=True)
    ### end Alembic commands ###


"""
forecaster.handler
~~~~~~~~~~~~~~

Handle requests and responses from API
"""

import logging
import time

import requests

import raven
import trading212api
from forecaster import __version__
from forecaster.enums import ACTIONS, EVENTS
from forecaster.exceptions import MissingData
from forecaster.patterns import Chainer, Singleton
from forecaster.utils import get_conf, read_data, read_tokens

LOGGER = logging.getLogger('forecaster.handler')
MOVER_LOGGER = logging.getLogger('mover')

class Client(Chainer, metaclass=Singleton):
    """Adapter for trading212api.Client"""

    def __init__(self, bot=None):
        super().__init__(successor=bot)
        self.mode = self._get_mode()
        self.api = trading212api.Client(self.mode)
        self.results = 0.0  # current net profit
        LOGGER.debug("CLIENT: initied")

    @property
    def positions(self):
        return self.api.positions

    @property
    def account(self):
        return self.api.account

    @property
    def funds(self):
        return self.api.account.funds

    def handle_request(self, event, **kw):
        """chainer function"""
        if event == ACTIONS.CHANGE_MODE:
            mode = kw['mode']
            if self.mode != mode:
                LOGGER.info("CLIENT: switching mode from {} to {}".format(self.mode, mode))
                self.swap()
                LOGGER.info("CLIENT: current mode: {}".format(self.mode))
                return self.mode == mode
        else:
            self.pass_request(event, **kw)

    def start(self):
        """start from credentials in data file"""
        try:
            self.data = self._get_data()
        except MissingData:
            self.handle_request(EVENTS.MISSING_DATA)
        self._auto_login()
        LOGGER.debug("CLIENT: started with data")

    def login(self, username, password):
        """log in trading212"""
        while True:
            try:
                self.api.login(username, password)
                self.username = username
                break
            except trading212api.exceptions.InvalidCredentials as e:
                LOGGER.error("Invalid credentials with {}".format(e.username))
                self.handle_request(EVENTS.MISSING_DATA)
            except trading212api.exceptions.LiveNotConfigured:
                LOGGER.error("{} mode not configured".format(self.mode))
                self.handle_request(EVENTS.MODE_FAILURE)
        LOGGER.debug("CLIENT: logged in")

    def open_pos(self, symbol, mode, quantity):
        """open position and handle exceptions"""
        self.refresh()  # renovate sessions
        while True:  # handle exceptions
            try:
                self.api.open_position(mode, symbol, quantity)
                MOVER_LOGGER.info("opened position of {:d} {} on {}".format(quantity, symbol, mode))
                break
            except trading212api.exceptions.PriceChangedException:
                continue
            except trading212api.exceptions.MinQuantityExceeded:
                LOGGER.warning("Minimum quantity exceeded")
                SentryClient().captureException()
                break
            except trading212api.exceptions.MaxQuantityExceeded:
                LOGGER.warning("Maximum quantity exceeded")
                break
            except trading212api.exceptions.MarketClosed:
                LOGGER.warning("Market closed for {}".format(symbol))
                self.handle_request(EVENTS.MARKET_CLOSED, sym=symbol)
                break
            except trading212api.exceptions.NoPriceException:
                LOGGER.warning("NoPriceException caught")
                time.sleep(1)  # waiting 1 second
            except trading212api.exceptions.ProductNotAvaible:
                LOGGER.warning("Product not avaible")
                SentryClient().debug("{} product not avaible".format(symbol))
                SentryClient().captureException()
                break

    def close_pos(self, pos):
        """close position and update results"""
        self.refresh()  # renovate sessions
        while True:
            try:
                self.api.close_position(pos.id)  # close
                MOVER_LOGGER.info("closed position {}".format(pos.id))
                MOVER_LOGGER.info("gain: {:.2f}".format(pos.result))
                break
            except trading212api.exceptions.NoPriceException:
                LOGGER.warning("NoPriceException caught")
                time.sleep(1)  # waiting 1 second
            except ValueError:
                LOGGER.warning("Position not found")
                break
        self.results += pos.result  # update returns
        self.handle_request(EVENTS.CLOSED_POS, pos=pos)

    def close_all(self):
        """close all positions"""
        self.refresh()
        poss = []
        for pos in self.api.account.positions:
            poss.append(pos)
        for pos in poss:  # avoid continue refresh
            self.close_pos(pos)

    def get_last_candles(self, symbol, num, timeframe):
        """get last candles"""
        self.refresh()  # renovate sessions
        candles = self.api.get_historical_data(symbol, num, timeframe)
        prices = [candle['bid'] for candle in candles]
        return prices

    def get_margin(self, symbol, quantity):
        """get margin"""
        return self.api.get_margin(symbol, quantity)

    def refresh(self):
        """refresh the session"""
        try:
            self.api.refresh()
        except trading212api.exceptions.RequestError:
            LOGGER.warning("API unavaible")
            self._auto_login()
            self.api.refresh()
        except requests.exceptions.ConnectionError:
            LOGGER.error("Connection error")
            SentryClient().captureException()
            self.handle_request(EVENTS.CONNECTION_ERROR)

    def swap(self):
        """swap mode"""
        if self.mode == 'demo':
            self.mode = 'live'
        elif self.mode == 'live':
            self.mode = 'demo'
        self.api = trading212api.Client(self.mode)
        self.results = 0.0
        self._auto_login()

    def _get_mode(self):
        """get mode"""
        try:
            return self._get_data()['mode']
        except (MissingData, KeyError):
            return get_conf()['HANDLER']['mode']

    def _get_data(self):
        """get credentials if exist"""
        try:
            return read_data('data')
        except FileNotFoundError:
            raise MissingData()

    def _auto_login(self):
        """"auto login with credentials"""
        self.login(self.data['username'], self.data['password'])

class SentryClient(raven.Client, metaclass=Singleton):
    """sentry handler to handle exceptions"""

    def __init__(self, *args, **kwargs):
        token = read_tokens()['sentry']
        version = __version__.strip('v')
        env = 'developing'
        super().__init__(dsn=token, release=version, environment=env, *args, **kwargs)
        self.breadcrumbs = raven.breadcrumbs
        LOGGER.debug("SENTRY: initied")

    def record(self, text, *args, **kwargs):
        self.breadcrumbs.record(message=text, *args, **kwargs)

    def debug(self, text):
        self.breadcrumbs.record(text, level='debug')

    def info(self, text):
        self.breadcrumbs.record(text, level='info')

    def warning(self, text):
        self.breadcrumbs.record(text, level='warning')

    def error(self, text):
        self.breadcrumbs.record(text, level='error')


"""
This module contains a main function of a program.
"""
from board import Game, Board

def main():
    """This function start and plays the game."""
    print("Starting the game.")
    initial_board = Board()
    game = Game(initial_board)

    game.play()

if __name__ == "__main__":
    main()


import tkinter as tk
from tkinter import messagebox

# Fonction pour jouer un tour
def play(row, col):
    global current_player
    # Vérifier si la case est vide
    if buttons[row][col]["text"] == "":
        # Marquer la case avec le symbole du joueur courant
        buttons[row][col]["text"] = current_player
        # Vérifier si le joueur courant a gagné
        if check_win():
            messagebox.showinfo("Morpion", f"Le joueur {current_player} a gagné !")
            root.destroy() # Fermer la fenêtre
        # Vérifier si le jeu est un match nul
        elif check_draw():
            messagebox.showinfo("Morpion", "Match nul !")
            root.destroy() # Fermer la fenêtre
        else:
            # Passer le tour au prochain joueur
            if current_player == "X":
                current_player = "O"
            else:
                current_player = "X"

# Fonction pour vérifier si un joueur a gagné
def check_win():
    # Vérifier si un joueur a gagné en parcourant toutes les cases du jeu
    for i in range(3):
        # Vérifier si les trois cases d'une ligne sont occupées par le même joueur
        if buttons[i][0]["text"] == buttons[i][1]["text"] == buttons[i][2]["text"] != "":
            return True
    for j in range(3):
        # Vérifier si les trois cases d'une colonne sont occupées par le même joueur
        if buttons[0][j]["text"] == buttons[1][j]["text"] == buttons[2][j]["text"] != "":
            return True
    # Vérifier si les trois cases de la diagonale en haut à gauche vers la diagonale en bas à droite sont occupées par le même joueur
    if buttons[0][0]["text"] == buttons[1][1]["text"] == buttons[2][2]["text"] != "":
        return True
    # Vérifier si les trois cases de la diagonale en haut à droite vers la diagonale en bas à gauche sont occupées par le même joueur
    if buttons[0][2]["text"] == buttons[1][1]["text"] == buttons[2][0]["text"] != "":
        return True
    # Si aucun joueur n'a gagné, retourner False
    return False

# Fonction pour vérifier si le jeu est un match nul
def check_draw():
    # Vérifier si le jeu est terminé en parcourant toutes les cases du jeu
    for i in range(3):
        for j in range(3):
            # S'il reste au moins une case vide, le jeu n'est pas terminé
            if buttons[i][j]["text"] == "":
                return False
    # Si toutes les cases sont occupées et aucun joueur n'a gagné, le jeu est un match nul
    return True

# Interface graphique
# Création de la fenêtre principale
root = tk.Tk()
# Définition du titre de la fenêtre
root.title("Morpion")

# Création d'un frame pour le placement des boutons
frame = tk.Frame(root)
frame.pack()

# Création de la grille de 3x3 pour les boutons
buttons = []
for i in range(3):
    row = []
    for j in range(3):
        # Création d'un bouton avec le texte vide, une taille et une police spécifiques
        # qui appelle la fonction play avec les arguments row et col lorsqu'il est cliqué
        button = tk.Button(frame, width=10, height=5, font=("Arial", 20, "bold"), command=lambda row=i, col=j: play(row, col))
        # Placement du bouton dans la grille
        button.grid(row=i, column=j)
        row.append(button)
    buttons.append(row)

# Définition du joueur courant
current_player = "X"

# Lancement de la boucle principale de la fenêtre pour l'affichage
root.mainloop()


from collections import deque

import torch

class LossMeter(object):
    """
    Measure loss and report average across iterations.
    """

    def __init__(self, average_over=20):
        self.average_over = average_over
        self.total_loss = 0.
        self.losses = deque(maxlen=self.average_over)

    def update(self, loss):
        self.total_loss += loss
        self.losses.append(loss)

    def __str__(self):
        avg_loss = sum(self.losses) / self.average_over
        return f"{avg_loss:06.1f}"

class SegMeter(object):
    """
    Score semantic segmentation metrics by accumulating histogram
    of outputs and targets.

    - overall pixel accuracy
    - per-class accuracy
    - per-class intersection-over-union (IU)
    - frequency weighted IU

    n.b. mean IU is the standard single number summary of segmentation quality.
    """

    def __init__(self, num_classes):
        self.num_classes = num_classes
        self.hist = None

    def update(self, output, target):
        if self.hist is None:
            # init on first update (to inherit target device)
            self.hist = target.new_zeros((self.num_classes,) * 2).float()
        # metrics require hard assigment, so pick most likely class
        _, hard_seg = output.data[0].max(0)
        self.hist += self.fast_hist(target, hard_seg, self.num_classes)

    def score(self):
        scores = {}
        # overall accuracy
        scores['all_acc'] = torch.diag(self.hist).sum() / self.hist.sum()
        # per-class accuracy
        scores['acc'] = torch.diag(self.hist) / self.hist.sum(1)
        # per-class IU
        scores['iu'] = torch.diag(self.hist) / (self.hist.sum(1)
                                             + self.hist.sum(0)
                                             - torch.diag(self.hist))
        # frequency-weighted IU
        freq = self.hist.sum(1) / self.hist.sum()
        scores['freq_iu'] = (freq[freq > 0] * scores['iu'][freq > 0]).sum()
        return scores

    def fast_hist(self, a, b, n):
        """
        Fast 2D histogram by linearizing.
        """
        a, b = a.view(-1).long(), b.view(-1).long()
        k = (a >= 0) & (a < n)
        return torch.bincount(n * a[k] + b[k],
                              minlength=n**2).view(n, n).float()

    def __str__(self):
        strs = []
        for metric, score in self.score().items():
            score = torch.mean(score[score == score]).item()  # filter out NaN
            strs.append(f"{metric:10s} {score:.3f}")
        return '\n'.join(strs)


import pytest

@pytest.mark.asyncio
async def test_create_call_from_contract(map_contract, account):
    # pylint: disable=import-outside-toplevel
    contract = map_contract

    client = account.client
    res = await map_contract.functions["put"].invoke(
        key=1234, value=9999, auto_estimate=True
    )
    await res.wait_for_acceptance()

    # docs: start
    from starknet_py.net.client_models import Call

    # Prepare a call through Contract
    call = contract.functions["get"].prepare(key=1234)
    assert issubclass(type(call), Call)

    # Use call directly through Client
    result = await client.call_contract(call)
    # docs: end

    assert result[0] == 9999


import pandas as pd

data = pd.read_csv('datasets/SARS.csv')

dataset = list(data.Smiles[:622])

from os import path
import numpy as np
import re

import os
os.environ["TF_FORCE_GPU_ALLOW_GROWTH"]="true"

def vocab(smiles):
    regex = '(\[[^\[\]]{1,10}\])'
    characters = set()
    for i, sm in enumerate(smiles):
        sm = sm.replace('Br', 'R').replace('Cl', 'L')
        sm_chars = re.split(regex, sm)
        for section in sm_chars:
            if section.startswith('['):
                characters.add(section)
            else:
                for char in section:
                    characters.add(char)

    characters.add('G')
    characters.add('A')
    unique_character = sorted(characters)
    print('Number of unique characters in the vocabulary: {} '.format(len(unique_character)))
    print(unique_character)
    vocabs = sorted(list(unique_character))

    char_to_int = dict()
    for i, char in enumerate(vocabs):
        char_to_int[char] = i

    int_to_char = dict()
    for i, char in enumerate(vocabs):
        int_to_char[i] = char

    vocab_size = len(vocabs)
    return vocabs,char_to_int,int_to_char

def tokenize(data):
    list_tok_smiles = []
    for smile in data:
        regex = '(\[[^\[\]]{1,10}\])'
        smile = smile.replace('Br', 'R').replace('Cl', 'L')
        smile_chars = re.split(regex, smile)
        smile_tok = []
        smile_tok.append('G')
        for section in smile_chars:
            if section.startswith('['):
                smile_tok.append(section)
            else:
                for char in section:
                    smile_tok.append(char)

        smile_tok.append('A')
        if len(smile_tok)>max_len:
            continue
        if len(smile_tok) <max_len:
              dif = max_len - len(smile_tok)
              [smile_tok.append('A') for _ in range(dif)]

        assert len(smile_tok) == max_len
        list_tok_smiles.append(smile_tok)
    return(list_tok_smiles)

def encode(smile_data):
    encode_smiles = []
    for smile in smile_data:
        smile_idx = []
        for char in smile:
            smile_idx.append(char_to_int[char])
        encode_smiles.append(smile_idx)
    return encode_smiles

def decode(encode_smiles):
    decode_smiles = []
    for smile in encode_smiles:
        smile_chars = []
        for i in smile:
            if (int_to_char[i] == 'G'):
                continue
            if (int_to_char[i] == 'A'):
                break
            smile_chars.append(int_to_char[i])
        smile_str = ''.join(smile_chars)
        smile_str = smile_str.replace('R', 'Br').replace('L', 'Cl')
        decode_smiles.append(smile_str)
    return decode_smiles

def creat_label(data):
    dataY = [line[1:] for line in data]
    for i in range(len(dataY)):
        dataY[i].append(char_to_int['A'])
    return dataY

import tensorflow as tf
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Embedding, LSTM, Dropout, Dense, Input,GRU
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping
from tensorflow.keras.models import load_model
from tensorflow import keras

import matplotlib.pyplot as plt
from tqdm import tqdm
from tensorflow.keras.layers import concatenate
from nested_lstm import NestedLSTM

optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)

def gelu(x):
    return 0.5*x*(1+tf.keras.activations.tanh(np.sqrt(2/np.pi)*(x+0.044715*pow(x,3))))

def generator_model():
    z = Input(x_shape)
    x1 = Embedding(vocab_size, emb_dim, input_length = max_len)(z)
    x2 = Embedding(vocab_size, emb_dim, input_length = max_len)(z)
    x1 = NestedLSTM(512, depth=2, dropout=0.5, recurrent_dropout=0.2)(x1)
    x2 = NestedLSTM(512, depth=2, dropout=0.5, recurrent_dropout=0.2)(x2)

    x = concatenate([x1,x2])
    x = Dropout(0.5)(x)
    x = Dense(vocab_size, activation = 'softmax')(x)

    return keras.Model(inputs=z, outputs=x, name="Generator")

def generate_sample(start_idx, num, end_idx):
    seq_list = []
    for j in tqdm(range(num)):
        seq = [start_idx]
        for i in range(max_len-1):
            x = np.reshape(seq, (1, len(seq),1))
            preds = model.predict(x, verbose=1)    #(1,1,33)
            index = sample(preds[0][-1],sample_temperature)
            seq.append(index)
            if (index) == end_idx:
                break
        seq_list.append(seq)
    return seq_list

def sample(preds,sample_temperature):
    preds_ = np.log(preds).astype('float64')/sample_temperature
    probs= np.exp(preds_)/np.sum(np.exp(preds_))
    out=np.argmax(np.random.multinomial(1,probs,1))
    return out

def save_model():
    model.save_weights(path)

def load_model():
    model.load_weights(path)

#起始数据
nr_smiles = [100000]
for n in nr_smiles:
    f_string = ''
    with open('./datasets/ChEMBL_filtered') as f:
        i = 0
        for line in f:
            if len(line)<98:
                f_string = f_string+line
                i+=1
            if(i>=n):
              break
    smiles = f_string.split('\n')[:-1]

emb_dim = 256
max_len = 100
sample_temperature = 0.75
vocabs,char_to_int,int_to_char = vocab(smiles)
vocab_size = len(vocabs)

#transfer learning
n = 622
from rdkit import Chem

Smiles = []
for i in dataset:
    smi = Chem.MolFromSmiles(i)
    mol = Chem.MolToSmiles(smi, isomericSmiles=False)
    Smiles.append(mol)

smiles_tok = tokenize(Smiles)

dataX =  encode(smiles_tok)
dataY = creat_label(dataX)

data_X = np.reshape(dataX, (n,max_len))
data_Y = np.reshape(dataY, (n,max_len))
x_shape = data_X[0].shape

model = generator_model()
model.summary()

model.compile(optimizer = optimizer, loss = 'sparse_categorical_crossentropy')

model.load_weights('RNN1')

early_stop = EarlyStopping(monitor = "loss", patience=5)
checkpoint = ModelCheckpoint('detecting_parameter', monitor = 'loss', verbose = 1, mode = 'auto')
callbacks_list = [checkpoint, early_stop]
results = model.fit(dataX, dataY, epochs = 100, batch_size =8, callbacks = callbacks_list)

fig, ax = plt.subplots()
ax.plot(results.history['loss'])
ax.set(xlabel='epochs', ylabel = 'loss')
figure_path = 'detecting_parameter' + "Loss_plot.png"
fig.savefig(figure_path)
plt.show()
last_epoch = early_stop.stopped_epoch

# model.save_weights('RNN1')

# model.load_weights('RNN1')

nums = 1000
generate_seq = generate_sample(char_to_int['G'], nums, char_to_int['A'])
generate_smiles = decode(generate_seq)

from Measure import check_validity,check_novelty,check_uniqueness,draw_molecule

valid_molecules, valid_score = check_validity(generate_smiles)
novel_score = check_novelty(valid_molecules,smiles)
unique_score = check_uniqueness(valid_molecules)
img=draw_molecule(valid_molecules)

print(valid_score)
print(novel_score)
print(unique_score)
img

unique_molecules = list(set(valid_molecules))

smi =pd.DataFrame(data=unique_molecules,index=None, columns=['smiles'])
smi.to_csv('generate_smiles.csv')


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

# In[31]:

get_ipython().run_line_magic('matplotlib', 'inline')
#Importing dependencies
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

#Reading PyBer CSV file
pyberDf = pd.read_csv('Resources/PyBer_ride_data.csv')
pyberDf

# In[32]:

pyberDF.plot(x='Month',y='Avg. Fare ($USD)')
plt.show()

# In[33]:

#Setting xAxis and tick locations
xAxis = np.arange(len(pyberDf))
tickLocations = [value for value in xAxis]
#Plotting the Data
pyberDf.plot(x='Month',y='Avg. Fare ($USD)')
plt.xticks(tickLocations, pyberDf['Month'])

# In[54]:

x = 'Month'
y = 'Avg. Fare ($USD)'
import statistics
stdev = statistics.stdev(pyberDf['Avg. Fare ($USD)'])
#Creating a bar chart
pyberDf.plot.bar(x=x,y=y,label='Avg. Fare ($USD)',color='xkcd:sky blue',rot=0,yerr=stdev,capsize=3,yticks = np.arange(0,60, step=5.0))

# In[ ]:


from django.conf import settings
from django.apps import apps
from django.core.exceptions import ImproperlyConfigured

def get_notifications_model():
    try:
        model_name = settings.NOTIFICATION_MODEL
    except:
        raise ImproperlyConfigured(
            'Could not load the Notifications model'
        )
    else:
        return apps.get_model(model_name, require_ready=False)


import RobotApi
import time
RobotApi.ubtRobotInitialize()
ret=RobotApi.ubtRobotConnect("SDK","1","127.0.0.1")
if(0!=ret):
        print("return value:%d" % ret)
        exit(1)

servoAngle=RobotApi.UBTEDU_ROBOTSERVO_T()

servoAngle.SERVO1_ANGLE= 90
servoAngle.SERVO2_ANGLE= 140
servoAngle.SERVO3_ANGLE= 160

# Action : keep right arm straight
servoAngle.SERVO4_ANGLE= 90
servoAngle.SERVO5_ANGLE= 40
servoAngle.SERVO6_ANGLE= 20
servoAngle.SERVO7_ANGLE= 90
servoAngle.SERVO8_ANGLE= 60
servoAngle.SERVO9_ANGLE= 75
servoAngle.SERVO10_ANGLE= 110
servoAngle.SERVO11_ANGLE= 90
servoAngle.SERVO12_ANGLE= 90
servoAngle.SERVO13_ANGLE= 120
servoAngle.SERVO14_ANGLE= 105
servoAngle.SERVO15_ANGLE= 70
servoAngle.SERVO16_ANGLE= 90
RobotApi.ubtSetRobotServo(servoAngle,200)
print("done")
RobotApi.ubtRobotDisconnect("SDK","1","127.0.0.1")
RobotApi.ubtRobotDeinitialize()


'''Message Board Built From Scrtatch'''

from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import parse_qs

memory = []

form = '''<!DOCTYPE html>
  <title>Message Board</title>
  <form method="POST">
    <textarea name="message"></textarea>

    <button type="submit">Post it!</button>
  </form>

{}

'''

class MessageHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        # Message Length
        length = int(self.headers.get('Content-length', 0))

        # Read the correct amount of data from the request.
        data = self.rfile.read(length).decode()

        # Extract the "message" field from the request data.
        message = parse_qs(data)["message"][0]

        # Escape HTML tags in the message so users can't break world+dog.
        message = message.replace("<", "<")

        # Store it in memory.
        memory.append(message)

        # Send a 303 redirect back to the root page.
        self.send_response(303) # Redirect Via Get
        self.send_header('Location', '/')
        self.end_headers()

    def do_GET(self):
        # First, send a 200 OK response.
        self.send_response(200)

        # Then send headers.
        self.send_header('Content-type', 'text/html; charset=utf-8')
        self.end_headers()

        # Put the response together out of the form and the stored messages.
        mesg = form.format("\n".join(memory))

        # Send the response.
        self.wfile.write(mesg.encode())

if __name__ == '__main__':
    server_address = ('', 8000)
    httpd = HTTPServer(server_address, MessageHandler)
    httpd.serve_forever()


# !/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Author:  Qingchun Wang @ NJU
# E-Mail:  qingchun720@foxmail.com
#

from sympy import *
from scipy import optimize

o1,o2 = 0.5*pi,1.5*pi
e1,e2,e3 = 0.0169,3.34,81.5

n = Symbol('n', real=True)

A = Matrix([
[   cos(n*o1),     sin(n*o1),    -cos(n*o1),    -sin(n*o1),           0,                  0],
[e1*sin(n*o1), -e1*cos(n*o1), -e2*sin(n*o1),  e2*cos(n*o1),           0,                  0],
[           0,             0,     cos(n*o2),     sin(n*o2),     -cos(n*o2),      -sin(n*o2)],
[           0,             0,  e2*sin(n*o2), -e2*cos(n*o2),  -e3*sin(n*o2),    e3*cos(n*o2)],
[          -1,             0,             0,             0,    cos(2*n*pi),     sin(2*n*pi)],
[           0,            e1,             0,             0, e3*sin(2*n*pi), -e3*cos(2*n*pi)]])

fn = A.det()
# fn = -8*e1*e2*e3 \
#      +(e1+e2)*(e2+e3)*(e3+e1)*cos(2*n*pi) \
#      -(e1+e2)*(e2-e3)*(e3-e1)*cos(2*n*o1) \
#      +(e1-e2)*(e2+e3)*(e3-e1)*cos(2*n*o1) \
#      +(e1-e2)*(e2-e3)*(e3+e1)

plotting.plot(fn, (n, -pi, pi))
# fn.evalf(subs={n: 0})

def bisect(f, x, x0, x1):
    '''
    bisect for solve equation

    :param f:
    :param x:
    :param x0:
    :param x1:
    :return:
    '''

    while True:
        x3 = (x0+x1)/2
        f3 = f.evalf(subs={x: x3})
        if abs(f3) < 1.0e-12: break
        else:
            f0 = f.evalf(subs={x: x0})
            f1 = f.evalf(subs={x: x1})
            if f0*f3<0: x0,x1 = x0,x3
            elif f1*f3: x0,x1 = x3,x1
            else:
                raise RuntimeError(F'f({x0}), f({x3}), f({x1}) are same sign')

    return x3

x = Symbol('x')
fx = 2*x**2-1
plotting.plot(fx, (x, -1, 1))
# x,*_ = solve(fx, x)
# x = bisect(fx, x, 0.5, 1)
fxpy = lambdify(x, fx)
# x = optimize.brentq(fxpy, 0.5, 1)
# x = optimize.newton(fxpy, 0.6)
x,*_ = optimize.fsolve(fxpy, 0.6)
print(F'x = {x}')

# n,*_ = solve(fn,n)
# n = bisect(fn, n, 0.6, 1.0)
fnpy = lambdify(n, fn)
# n = optimize.brentq(fnpy, 0.5, 1)
# n = optimize.newton(fnpy, 0.7)
n,*_ = optimize.fsolve(fnpy, 0.7)
print(F'n = {n}')


"""
@File:   ex02.py
@Author: Ana Lívia Ruegger Saldanha (N.USP 8586691)
@Date:   2022-05-27

@Brief:  SCC0216 - Modelagem Computacional em Grafos
         Trabalho 02: Busca em largura (Breadth First Search)

         A distância d_ij entre qualquer par de vértices V_i e V_j de um
         grafo não dirigido pode ser determinada por meio de uma busca em
         largura. Faça um programa que receba um grafo (arquivo padrão em
         formato pajek), realize uma busca em largura e apresente como saída
         a matriz M, tal que M_ij = d_ij.
"""

import sys

def BFS(G, n, start_v, colors):
    ''' Algoritmo de busca em largura '''
    dist = [-1] * n # A distância inicial é infinita (será representada por -1)

    v = start_v
    colors[v] = "grey"
    dist[v] = 0
    queue = [v]

    while len(queue) > 0:
        v = queue[0]
        queue.pop(0)

        if colors[v] != "black":
            colors[v] = "black"

        for w in G[v]:
            if colors[w] == "white":
                colors[w] == "grey"
                dist[w] = dist[v] + 1
                queue.append(w)

    return dist

''' Ler n '''
first_line = input()
first_line = first_line.split()
n = int(first_line[1])
input() # Ignora segunda linha

''' Ler arestas '''
edges = []
for line in sys.stdin:
    vertice = []
    for var in line.split():
        vertice.append(int(var) - 1)
    edges.append(vertice)

''' Criar o grafo vazio'''
G = []
for i in range(n):
    G.append([])

''' Construir o grafo '''
for edge in edges:
    G[edge[0]].append(edge[1])
    G[edge[1]].append(edge[0])

''' Imprimir matriz de distâncias '''
for i in range(n):
    for dist in BFS(G, n, i, ["white"] * n):
        print(dist, end=" ")
    print()


from django.shortcuts import render_to_response, get_object_or_404
from django.template import RequestContext
from django.views.generic import ListView
from django.http import HttpResponseRedirect, HttpResponse
from syspolls.nixpolls.models import Quest, UserAnswer, Group, Version
from django.contrib.auth.decorators import login_required

import logging

@login_required
def groups(request):
    groups_v = Group.objects.all()
    version_v = Version.objects.all()
    ctx = {
        'groups_v':groups_v, 'version_v':version_v,
    }
    return render_to_response('groups.html', RequestContext(request, ctx))

@login_required
def quests(request, title):
    group_s = get_object_or_404(Group, title__iexact=title)
    quests_v = Quest.objects.filter(groups=group_s).order_by('groups')
    if request.method == 'POST':
        for q in quests_v:
            t = 'qust_%s' % q.id
            t2 = 'ans_%s' % q.id
            qst_db = request.POST.get(t, '')
            qst_db_an = request.POST.get(t2, '')
            answer_obj = UserAnswer(user_name=request.user, group=group_s, quest=qst_db, answer=qst_db_an)
            answer_obj.save()
    ctx = {
        'quests_v':quests_v,
    }
    return render_to_response('polls.html', RequestContext(request, ctx))


from SPDSiamese.model import ST_TS_SPDC, Net
from SPDSiamese.Dataloader import Dataset_learning, Dataset_classification
from SPDSiamese.trainer import train, test
from SPDSiamese.Siamese import *
from SPDSiamese.optimizer import *
from SPDSiamese.download_dataset import *
from SPDSiamese.set_dataset import set_dataset, makedir_path
from torch.utils.data import Dataset, DataLoader
import argparse
import pickle
import shutil, os
import torch
from torch import nn
import numpy as np
import warnings
warnings.filterwarnings("ignore")

parser = argparse.ArgumentParser(description = "Online recognition parameters and datasets")
parser.add_argument(
    "--path",
    type = str,
    default = "",
    help = "Path to either the folder containing the skeletal data", )

parser.add_argument(
    "--dataset",
    type = str,
    default = "OAD",
    choices = ["ODHG", "OAD", "UOW", "InHard"],
    help = "the proposed skeletal datasets",
)

parser.add_argument(
    "--execution",
    type = str,
    default = "Classifier",
    choices = ["Classifier", "Detector"],
    help = "type of the execution",
)

parser.add_argument(
    "--interpolation",
    type = int,
    default = 500,
    help = "The skeletal sequences will be normalized to the proposed number of frames",
)

parser.add_argument(
    "--batch_size",
    type = int,
    default = 30,
    help = "batch size in DataLoader",
)

parser.add_argument(
    "--t0",
    type = int,
    default = 1,
    help = "t0: time interval of the window in spatial - temporal studies",
)

parser.add_argument(
    "--NS",
    type = int,
    default = 15,
    help = "NS: number of secondary subsequences in each primary subsequnece during the temporal - spatial studies",
)

parser.add_argument(
    "--eps",
    type = float,
    default = 10 ** ( - 4),
    help = "eps: threshold of the ReEig layer",
)

parser.add_argument(
    "--outs_trans",
    type = int,
    default = 200,
    help = "outs_trans: parameter of the transformation of the SPD matrix size in SPD Aggregation layer",
)

parser.add_argument(
    "--lr_learning",
    type = float,
    default = 10 ** ( - 5),
    help = "lr: optimizer learning rate of the learning model",
)

parser.add_argument(
    "--lr_classification",
    type = float,
    default = 7 * (10 ** ( - 4)),
    help = "lr: optimizer learning rate of the classification model",
)

parser.add_argument(
    "--margin",
    type = float,
    default = 7.0,
    help = "margin of the contrastive loss function of the Siamese network",
)

parser.add_argument(
    "--m",
    type = int,
    help = "m : refresh rate of the detector",
)

parser.add_argument(
    "--ws",
    type = int,
    help = "ws : window size of the detector",
)

parser.add_argument(
    "--learning_epochs",
    type = int,
    default = 10,
    help = "number of epoch needed for SPD learning",
)

parser.add_argument(
    "--classification_epochs",
    type = int,
    default = 100,
    help = "number of epoch needed for SPD classification",
)

parser.set_defaults(feature = False)
args = parser.parse_args()

if not os.path.isdir(args.path + args.dataset):
    download_dataset(args.dataset, args.path)
path = args.path + "/" + args.dataset + "/" + args.execution
type_detector = {"ODHG" : "Binary", "OAD" : "Binary", "InHard" : "Binary", "UOW" : "General"}
###         Checking the dataset            ###
if not os.path.isdir(path):
    makedir_path(path)
    makedir_path(path + "/models")
    primary_path = args.path + "/" + args.dataset + "/Online/"
    set_dataset(args.dataset, args.execution, path, primary_path, args.ws, args.m, type_detector)

ori_classes = [int(i) for i in os.listdir(path + "/train/")]
ori_classes.sort()
for i in range(len(ori_classes)):
    os.rename(path + "/train/" + str(ori_classes[i]), path + "/train/" + str(i))
    os.rename(path + "/test/" + str(ori_classes[i]), path + "/test/" + str(i))
N = len(ori_classes) # Number of classes

###       Loading dataset      ###
print("Loading dataset ...\n")
transformed_dataset = Dataset_learning(path, args.interpolation, train = True)
dataloader = DataLoader(transformed_dataset, batch_size = args.batch_size, shuffle = True, num_workers = 0)
transformed_dataset_test = Dataset_learning(path, args.interpolation, train = False)
dataloader_test = DataLoader(transformed_dataset_test, batch_size = args.batch_size, shuffle = False, num_workers = 0)

#Partitioning
parts = dict()
parts["InHard"] = [[12, 11, 10, 0, 1, 2, 3], [12, 11, 10, 0, 4, 5, 6], [12, 11, 10, 13, 14, 15, 16], [12, 11, 10, 17, 18, 19, 20]]
parts["ODHG"] = [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15], [16, 17, 18, 19]]
parts["OAD"] = [[3, 2, 20, 4, 5, 6, 7, 21, 22], [3, 2, 20, 1, 0, 12, 13, 14, 15], [3, 2, 20, 1, 0, 16, 17, 18, 19], [3, 2, 20, 8, 9, 10, 11, 23, 24]]
parts["UOW"] = [[3, 2, 20, 4, 5, 6, 7, 21, 22], [3, 2, 20, 1, 0, 12, 13, 14, 15], [3, 2, 20, 1, 0, 16, 17, 18, 19], [3, 2, 20, 8, 9, 10, 11, 23, 24]]

model = ST_TS_SPDC(N, parts[args.dataset], t0 = args.t0, NS = args.NS, eps = args.eps, vect = True, outs = args.outs_trans)
use_cuda = False
if use_cuda:
    model = model.cuda()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr = args.lr_learning)
optimizer = StiefelMetaOptimizer(optimizer)

print("---------------------------------- - \nSPD Matrices learning...\n---------------------------------- - ")
start_epoch = 1
for epoch in range(start_epoch, start_epoch + args.learning_epochs):
    train_loss, train_acc = train(epoch, model, optimizer, criterion, dataloader, use_cuda)
    test_loss, test_acc = test(epoch, model, optimizer, criterion, dataloader_test, use_cuda)
torch.save(model.state_dict(), path + "/models/spd_learning.pth")
makedir_path(path + "/learnt_spd_matrices/")
print("Loading SPD matrices...")
y = torch.empty(0, args.outs_trans, args.outs_trans)
l = torch.empty(0)
for i, r in enumerate(dataloader):
    y = torch.cat((y, model(torch.tensor(r['data'], requires_grad=True))[1]))
    l = torch.cat((l, r['label'].type(torch.LongTensor)))
torch.save({"data": y, "label" : l}, path + "/learnt_spd_matrices/train.pth")

y = torch.empty(0, args.outs_trans, args.outs_trans)
l = torch.empty(0)
for i, r in enumerate(dataloader_test):
    y = torch.cat((y, model(torch.tensor(r['data'], requires_grad=True))[1]))
    l = torch.cat((l, r['label'].type(torch.LongTensor)))
torch.save({"data": y, "label" : l}, path + "/learnt_spd_matrices/test.pth")

print("Loading Siamese dataset...")
transformed_dataset = Dataset_classification(path + "/learnt_spd_matrices")
train_loader = DataLoader(transformed_dataset, batch_size = args.batch_size, shuffle = True, num_workers = 0)

transformed_dataset_val = Dataset_classification(path + "/learnt_spd_matrices", train = False)
test_loader = DataLoader(transformed_dataset_val, batch_size = args.batch_size, shuffle = False, num_workers = 0)

siamese_transformed_dataset = SiameseDataset(Dataset_classification(path + "/learnt_spd_matrices"), N)
siamese_train_loader = DataLoader(siamese_transformed_dataset, batch_size = args.batch_size, shuffle = True, num_workers = 0)

siamese_transformed_dataset_val = SiameseDataset(Dataset_classification(path + "/learnt_spd_matrices", train = False), N)
siamese_test_loader = DataLoader(siamese_transformed_dataset_val, batch_size = args.batch_size, shuffle = False, num_workers = 0)

tu = [train_loader.dataset[i]['data'].unsqueeze(0) for i in range(len(train_loader.dataset))]
tot = torch.cat(tuple(tu), 0)
tu = [train_loader.dataset[i]['label'].unsqueeze(0) for i in range(len(train_loader.dataset))]
tot_label = torch.cat(tuple(tu), 0)
tu = [test_loader.dataset[i]['data'].unsqueeze(0) for i in range(len(test_loader.dataset))]
tot_test = torch.cat(tuple(tu), 0)
tu = [test_loader.dataset[i]['label'].unsqueeze(0) for i in range(len(test_loader.dataset))]
tot_label_test = torch.cat(tuple(tu), 0)

rep = torch.zeros(N, args.outs_trans, args.outs_trans)
for j in range(N):
    i = 0
    while int(train_loader.dataset[i]['label'].item())!= j:
        i +=1
    rep[j] = train_loader.dataset[i]['data']

margin = args.margin
embedding_net = Net(N, args.outs_trans)
model = SiameseNet(embedding_net)
cuda = False
if cuda:
    model.cuda()
loss_fn = ContrastiveLoss(margin)
lr = args.lr_classification
optimizer = torch.optim.Adam(model.parameters(), lr = lr)

start_epoch = 1
loss_train, loss_test, acc_train, acc_test = {}, {}, {}, {}
print("---------------------------------- - \nSiamese network :training...\n---------------------------------- - ")
for epoch in range(start_epoch, start_epoch + args.classification_epochs):
    print("\nEpoch ", epoch, ":")
    train_loss, train_acc = train_siamese(epoch, siamese_train_loader, model, loss_fn, optimizer, cuda, N, tot, tot_label, rep, margin)
    test_loss, test_acc = test_siamese(epoch, siamese_test_loader, model, loss_fn, cuda, N, tot_test, tot_label_test, rep, margin)
    loss_train[epoch], loss_test[epoch], acc_train[epoch], acc_test[epoch] = train_loss, test_loss, train_acc, test_acc
    L = [loss_train, loss_test, acc_train, acc_test]
    if test_acc >= max(acc_test.values()):
        torch.save(model.state_dict(), path + "/models/siamese_best.pth")

print("Choosing best representers ...")
model.load_state_dict(torch.load(path + "/models/siamese_best.pth"))
if len(tot_test) < 2000:
    x_test = model.get_embedding(tot_test)
else:
    x_test = torch.empty(len(tot_test), N)
    for i in range(len(tot_test) // 2000 - 2):
        x_test[2000 * i: 2000 * (i + 1)] = model.get_embedding(tot_test[2000 * i: 2000 * (i + 1)])
    x_test[2000 * (i + 1):] = model.get_embedding(tot_test[2000 * (i + 1):])

repp = rep.clone()
rep_best = repp
acc = {}
acc_best = {}
for i in range(N):
    acc[i] = {}
    acc_best[i] = []
    c = torch.where(tot_label == i)[0]
    for j in range(len(c)):
        rep_best[i] = tot[c[j]]
        x_rep = model.get_embedding(rep_best)
        dist_matrix = dis(x_test.unsqueeze(1).expand(x_test.size(0), N, N), x_rep.expand(x_test.size(0), N, N))
        d = dist_matrix.min(1)[1] - tot_label_test
        Acc = d[d == 0].size(0)
        acc[i][int(c[j].item())] = Acc / len(tot_label_test)
        l = []
    l = list(acc[i].values())
    l.sort()
    cc = l[-1]
    for k in acc[i]:
        if acc[i][k] == cc:
            acc_best[i].append(k)
    rep_best[i] = tot[acc_best[i][0]]

torch.save({"state":model.state_dict(), "rep":rep_best, "acc": cc}, path + "/models/siamese_best.pth")
parameters = {"path": args.path, "dataset": args.dataset, "execution": args.execution,
             "interpolation": args.interpolation, "batch_size": args.batch_size, "t0": args.t0,
             "NS": args.NS, "eps": args.eps, "outs_trans": args.outs_trans, "lr_learning": args.lr_learning,
             "args.lr_classification": args.lr_classification, "margin": args.margin, "m": args.m,
             "ws": args.ws, "learning_epochs": args.learning_epochs, "classification_epochs": args.classification_epochs,
             "ori_classes": ori_classes}
torch.save(parameters, path + "/models/parameters.pth")

print("The exectution is finished. The resulting accuracy is about " + str(np.round(cc * 10000)/100) +
    "%. You can check the models weights and the parameters in the directory " +  path + "/models/.")


from discopy import Word, Diagram, Id, Ty, Cup, Cap
from discopro.grammar import words_and_cups, is_pregroup

def _surround_cup(diag, cup):
    """
    Given a general diagram, surround `diag` with the given `cup`
    while making the neccessary swaps to apply the cup.
    """
    ids = Diagram(diag.cod, diag.cod, [], [])
    cups = _insert_cup(ids, 0, len(diag.cod) - 1, cup)
    new_diag = Id(cup.dom[:1]) @ diag @ Id(cup.dom[1:])
    new_diag >>= cups
    return new_diag

def _insert_cup(diag, left, right, cup):
    """
    Given a diagram of only cups, insert a cup such that the left input
    of the cup is between [left-1, left] and the right input of the cup is
    between [right, right+1].
    """
    swaps = diag.swap(cup.dom[0:1], diag.dom[left:right+1])
    new_diag = Id(diag.dom[:left]) @ swaps @ Id(cup.dom[1:] @ diag.dom[right+1:])
    new_diag >>= Id(diag.dom[:right+1]) @ cup @ Id(diag.dom[right+1:])
    new_diag >>= diag
    return new_diag

def _insert_cup_min_swaps(diag, left, right, cup):
    """
    Given a diagram of only cups, insert a cup such that the left input
    of the cup is between [left-1, left] and the right input of the cup is
    between [right, right+1].
    The cups that are local to [left, right] will be applied before the
    added cup. This is done so to introduce the minimal number of swaps.

    TODO
    ----
    Currently this function only works for `diag` that contains only cups.
    Make this also works for `diag` that contains also swaps, which will
    allow for recursive application of insert_cup.
    """
    n_diag_dom = len(diag.dom)
    wires = list(range(len(diag.dom)))

    local_boxes_idx = list()
    for i, (box, offset) in enumerate(zip(diag.boxes, diag.offsets)):
        box_left = wires[offset]
        box_right = wires[offset+len(box.dom)-1]
        if left <= box_left and box_right <= right:
            local_boxes_idx.append(i)
        if len(box.cod) == 0: # cup
            # Remove the wires eaten up by the cap
            wires = wires[:offset] + wires[offset+2:]
        elif len(box.dom) == len(box.cod): # swap
            # Do nothing here
            pass
        else:
            raise NotImplementedError("Only cups and swaps allowed")
    # Move the local cups to the top
    n_local_boxes = len(local_boxes_idx)
    for target_idx, local_box_idx in enumerate(local_boxes_idx):
        diag = diag.interchange(local_box_idx, target_idx)

    # Split the diagram into top (only local boxes) and down (the other boxes)
    local_boxes = diag[:n_local_boxes]
    other_boxes = diag[n_local_boxes:]

    # Peel off the Ids on the left and on the right
    local_boxes = Diagram(local_boxes.dom[left:right+1], local_boxes.cod[left:-(n_diag_dom-right)+1],
                          local_boxes.boxes, list(map(lambda x: x-left, local_boxes.offsets)))
    # Surround the local cups diagram with the input cup
    local_boxes = _surround_cup(local_boxes, cup)

    # put back the peeled of Ids
    local_boxes = Id(diag.dom[:left]) @ local_boxes @ Id(diag.dom[right+1:])

    return local_boxes >> other_boxes

def connect_anaphora(diag, pro_box_idx, ref_box_idx, min_swaps=False):
    """
    Return a pregroup diagram with the pronoun word and the referent word connected
    with a Cup.

    Parameters
    ----------
    diag: discopy.rigid.Diagram
        Any pregroup diagram.
    pro_box_idx: int
        Index of the pronoun word box.
    ref_box_idx: int
        Index of the referent word box.
    min_swaps: bool
        Whether to try to minimise the number swaps.
    """
    if not is_pregroup(diag):
        raise ValueError(f"The given diagram is not a pregroup one")
    if not 0 <= pro_box_idx < len(diag):
        raise ValueError(f"Invalid pronoun box index: {pro_box_idx}")
    if not 0 <= ref_box_idx < len(diag):
        raise ValueError(f"Invalid referent box index: {ref_box_idx}")
    pro_box = diag.boxes[pro_box_idx]
    ref_box = diag.boxes[ref_box_idx]

    last_word_box_idx = max(i for i, box in enumerate(diag.boxes) if isinstance(box, Word))
    words_diag = diag[:last_word_box_idx+1]
    cups_diag = diag[last_word_box_idx+1:]

    # the index of the left most type srrounded by the added Cup
    left = sum(len(box.cod) for box in words_diag.boxes[:ref_box_idx+1])
    # the index of the right most type srrounded by the added Cup
    right = sum(len(box.cod) for box in words_diag.boxes[:pro_box_idx]) - 1

    N = Ty('n')
    # insert a cup to existing cups
    if min_swaps:
        cups_diag = _insert_cup_min_swaps(cups_diag, left, right, Cup(N, N.r))
    else:
        cups_diag = _insert_cup(cups_diag, left, right, Cup(N, N.r))

    # Create a new word diagrams with the pronoun box and referent box upgraded
    # to each has an extra output to allow connection via the cup
    new_boxes = words_diag.boxes

    new_boxes[pro_box_idx] = Word(pro_box.name, N.r @ pro_box.cod)
    new_boxes[ref_box_idx] = Word(ref_box.name, ref_box.cod @ N)

    new_words_diag = Id(Ty()).tensor(*new_boxes)

    return new_words_diag >> cups_diag

def connect_anaphora_on_top(diag, pro_box_idx, ref_box_idx, use_cap=False):
    """
    Return a non-pregroup diagram with the pronoun word box and
    the referent word box connected via a Cup on the top of the
    diagram.
    This method of connecting anaphora introduces no swaps but
    outputs a non-pregroup diagram. That means this can only be done
    once and therefore not recursively.

    Parameters
    ----------
    diag: discopy.rigid.Diagram
        Any pregroup diagram.
    pro_box_idx: int
        Index of the pronoun word box.
    ref_box_idx: int
        Index of the referent word box.
    use_cap: bool
        Whether to use a cap to connect or not.
    """
    if not is_pregroup(diag):
        raise ValueError(f"The given diagram is not a pregroup one")

    pro_box = diag.boxes[pro_box_idx]
    ref_box = diag.boxes[ref_box_idx]

    words, cups = words_and_cups(diag)

    left_words_boxes = words.boxes[:ref_box_idx]
    mid_words_boxes = words.boxes[ref_box_idx+1:pro_box_idx]
    right_words_boxes = words.boxes[pro_box_idx+1:]

    left_words = Id(Ty()).tensor(*left_words_boxes)
    mid_words = Id(Ty()).tensor(*mid_words_boxes)
    right_words = Id(Ty()).tensor(*right_words_boxes)

    N = Ty('n')

    if not use_cap:
        new_diag = left_words @ Word(ref_box.name, ref_box.cod @ N) @ Word(pro_box.name, N.r @ pro_box.cod) @ right_words
        new_diag >>= Id(left_words.cod @ ref_box.cod) @ Cup(N, N.r) @ Id(pro_box.cod @ right_words.cod)
        new_diag >>= Id(left_words.cod @ ref_box.cod) @ mid_words @ Id(pro_box.cod @ right_words.cod)
    else:
        new_diag = Cap(N.r, N)
        new_diag >>= left_words @ Word(ref_box.name, ref_box.cod @ N) @ Id(N.r) @ mid_words @ Id(N) @ Word(pro_box.name, N.r @ pro_box.cod) @ right_words

        new_diag >>= Id(left_words.cod @ ref_box.cod) @ Cup(N, N.r) @ Id(mid_words.cod) @ Cup(N, N.r) @ Id(pro_box.cod @ right_words.cod)

    return new_diag >> cups