import pprint
import re
from typing import Dict, Optional, Sequence, Union

from monai.apps.utils import download_url, get_logger
from monai.bundle.config_parser import ConfigParser
from monai.config import PathLike
from monai.utils import check_parent_dir, optional_import

validate, _ = optional_import("jsonschema", name="validate")
ValidationError, _ = optional_import("jsonschema.exceptions", name="ValidationError")

logger = get_logger(module_name=__name__)

def _update_args(args: Optional[Union[str, Dict]] = None, ignore_none: bool = True, **kwargs) -> Dict:
    """
    Update the `args` with the input `kwargs`.
    For dict data, recursively update the content based on the keys.

    Args:
        args: source args to update.
        ignore_none: whether to ignore input args with None value, default to `True`.
        kwargs: destination args to update.

    """
    args_: Dict = args if isinstance(args, dict) else {}  # type: ignore
    if isinstance(args, str):
        # args are defined in a structured file
        args_ = ConfigParser.load_config_file(args)

    # recursively update the default args with new args
    for k, v in kwargs.items():
        if ignore_none and v is None:
            continue
        if isinstance(v, dict) and isinstance(args_.get(k), dict):
            args_[k] = _update_args(args_[k], ignore_none, **v)
        else:
            args_[k] = v
    return args_

def _log_input_summary(tag: str, args: Dict):
    logger.info(f"\n--- input summary of monai.bundle.scripts.{tag} ---")
    for name, val in args.items():
        logger.info(f"> {name}: {pprint.pformat(val)}")
    logger.info("---\n\n")

def run(
    runner_id: Optional[str] = None,
    meta_file: Optional[Union[str, Sequence[str]]] = None,
    config_file: Optional[Union[str, Sequence[str]]] = None,
    args_file: Optional[str] = None,
    **override,
):
    """
    Specify `meta_file` and `config_file` to run monai bundle components and workflows.

    Typical usage examples:

    .. code-block:: bash

        # Execute this module as a CLI entry:
        python -m monai.bundle run trainer --meta_file <meta path> --config_file <config path>

        # Override config values at runtime by specifying the component id and its new value:
        python -m monai.bundle run trainer --net#input_chns 1 ...

        # Override config values with another config file `/path/to/another.json`:
        python -m monai.bundle run evaluator --net %/path/to/another.json ...

        # Override config values with part content of another config file:
        python -m monai.bundle run trainer --net %/data/other.json#net_arg ...

        # Set default args of `run` in a JSON / YAML file, help to record and simplify the command line.
        # Other args still can override the default args at runtime:
        python -m monai.bundle run --args_file "/workspace/data/args.json" --config_file <config path>

    Args:
        runner_id: ID name of the runner component or workflow, it must have a `run` method.
        meta_file: filepath of the metadata file, if `None`, must be provided in `args_file`.
            if it is a list of file paths, the content of them will be merged.
        config_file: filepath of the config file, if `None`, must be provided in `args_file`.
            if it is a list of file paths, the content of them will be merged.
        args_file: a JSON or YAML file to provide default values for `meta_file`, `config_file`,
            `runner_id` and override pairs. so that the command line inputs can be simplified.
        override: id-value pairs to override or add the corresponding config content.
            e.g. ``--net#input_chns 42``.

    """

    _args = _update_args(args=args_file, runner_id=runner_id, meta_file=meta_file, config_file=config_file, **override)
    for k in ("meta_file", "config_file"):
        if k not in _args:
            raise ValueError(f"{k} is required for 'monai.bundle run'.\n{run.__doc__}")
    _log_input_summary(tag="run", args=_args)

    parser = ConfigParser()
    parser.read_config(f=_args.pop("config_file"))
    parser.read_meta(f=_args.pop("meta_file"))
    id = _args.pop("runner_id", "")

    # the rest key-values in the _args are to override config content
    for k, v in _args.items():
        parser[k] = v

    workflow = parser.get_parsed_content(id=id)
    if not hasattr(workflow, "run"):
        raise ValueError(f"The parsed workflow {type(workflow)} does not have a `run` method.\n{run.__doc__}")
    workflow.run()

def verify_metadata(
    meta_file: Optional[Union[str, Sequence[str]]] = None,
    filepath: Optional[PathLike] = None,
    create_dir: Optional[bool] = None,
    hash_val: Optional[str] = None,
    args_file: Optional[str] = None,
    **kwargs,
):
    """
    Verify the provided `metadata` file based on the predefined `schema`.
    `metadata` content must contain the `schema` field for the URL of shcema file to download.
    The schema standard follows: http://json-schema.org/.

    Args:
        meta_file: filepath of the metadata file to verify, if `None`, must be provided in `args_file`.
            if it is a list of file paths, the content of them will be merged.
        filepath: file path to store the downloaded schema.
        create_dir: whether to create directories if not existing, default to `True`.
        hash_val: if not None, define the hash value to verify the downloaded schema file.
        args_file: a JSON or YAML file to provide default values for all the args in this function.
            so that the command line inputs can be simplified.
        kwargs: other arguments for `jsonschema.validate()`. for more details:
            https://python-jsonschema.readthedocs.io/en/stable/validate/#jsonschema.validate.

    """

    _args = _update_args(
        args=args_file, meta_file=meta_file, filepath=filepath, create_dir=create_dir, hash_val=hash_val, **kwargs
    )
    _log_input_summary(tag="verify_metadata", args=_args)

    filepath_ = _args.pop("filepath")
    create_dir_ = _args.pop("create_dir", True)
    check_parent_dir(path=filepath_, create_dir=create_dir_)

    metadata = ConfigParser.load_config_files(files=_args.pop("meta_file"))
    url = metadata.get("schema")
    if url is None:
        raise ValueError("must provide the `schema` field in the metadata for the URL of schema file.")
    download_url(url=url, filepath=filepath_, hash_val=_args.pop("hash_val", None), hash_type="md5", progress=True)
    schema = ConfigParser.load_config_file(filepath=filepath_)

    try:
        # the rest key-values in the _args are for `validate` API
        validate(instance=metadata, schema=schema, **_args)
    except ValidationError as e:
        # as the error message is very long, only extract the key information
        logger.info(re.compile(r".*Failed validating", re.S).findall(str(e))[0] + f" against schema `{url}`.")
        return
    logger.info("metadata is verified with no error.")


import numpy as np
from keras.layers import Input, Embedding, Dense, Dropout
from keras.layers import Reshape, Flatten, Lambda
from keras.layers.merge import concatenate, dot, add
from keras.models import Model
from keras import backend as K
from keras.regularizers import l2

def build_cf_model(n_users, n_movies, dim, isBest=False):
    u_input = Input(shape=(1,))
    if isBest:
        u = Embedding(n_users, dim, embeddings_regularizer=l2(1e-5))(u_input)
    else:
        u = Embedding(n_users, dim)(u_input)
    u = Reshape((dim,))(u)
    u = Dropout(0.1)(u)

    m_input = Input(shape=(1,))
    if isBest:
        m = Embedding(n_movies, dim, embeddings_regularizer=l2(1e-5))(m_input)
    else:
        m = Embedding(n_movies, dim)(m_input)
    m = Reshape((dim,))(m)
    m = Dropout(0.1)(m)

    if isBest:
        u_bias = Embedding(n_users, 1, embeddings_regularizer=l2(1e-5))(u_input)
    else:
        u_bias = Embedding(n_users, 1)(u_input)
    u_bias = Reshape((1,))(u_bias)
    if isBest:
        m_bias = Embedding(n_movies, 1, embeddings_regularizer=l2(1e-5))(m_input)
    else:
        m_bias = Embedding(n_movies, 1)(m_input)
    m_bias = Reshape((1,))(m_bias)

    out = dot([u, m], -1)
    out = add([out, u_bias, m_bias])
    if isBest:
        out = Lambda(lambda x: x + K.constant(3.581712))(out)

    model = Model(inputs=[u_input, m_input], outputs=out)
    return model

def build_deep_model(n_users, n_movies, dim, dropout=0.1):
    u_input = Input(shape=(4,))
    u = Embedding(n_users, dim)(u_input)
    # u = Reshape((dim,))(u)
    u = Flatten()(u)

    m_input = Input(shape=(19,))
    m = Embedding(n_movies, dim)(m_input)
    # m = Reshape((dim,))(m)
    m = Flatten()(m)

    out = concatenate([u, m])
    out = Dropout(dropout)(out)
    out = Dense(256, activation='relu')(out)
    out = Dropout(dropout)(out)
    out = Dense(128, activation='relu')(out)
    out = Dropout(dropout)(out)
    out = Dense(64, activation='relu')(out)
    out = Dropout(0.15)(out)
    out = Dense(dim, activation='relu')(out)
    out = Dropout(0.2)(out)
    out = Dense(1, activation='relu')(out)

    model = Model(inputs=[u_input, m_input], outputs=out)
    return model

def rate(model, user_id, item_id):
    return model.predict([np.array([user_id]), np.array([item_id])])[0][0]


from typing import TYPE_CHECKING

import discord
import httpx
from discord import app_commands
from discord.ext import commands

from it2zbot import utils

if TYPE_CHECKING:
    from it2zbot.bot import MyBot

class Issue(discord.ui.Modal, title="Issue"):
    issue_title = discord.ui.TextInput(label="Title", placeholder="help, owls are too cute and awesome", max_length=256)
    issue_body = discord.ui.TextInput(
        label="Description",
        style=discord.TextStyle.long,
        placeholder="owls are too cute, pls fix!?",
        required=False,
        max_length=4000,
    )

    async def on_submit(self, interaction: discord.Interaction):
        res = httpx.post(
            "https://api.github.com/repos/eulentier161/it2zbot/issues",
            headers={"Authorization": f"Bearer {utils.get_access_token()}"},
            json={"title": self.issue_title.value, "body": self.issue_body.value + "\n\n" + interaction.user.name + f" ({interaction.user.id})"},
        ).json()
        await interaction.response.send_message(f"Thanks for your feedback! {res['html_url']}", ephemeral=False)

    async def on_error(self, interaction: discord.Interaction, error: Exception) -> None:
        await interaction.response.send_message("Oops! Something went wrong.", ephemeral=True)

class GithubCog(commands.GroupCog, name="github"):
    def __init__(self, bot: "MyBot") -> None:
        self.bot = bot
        super().__init__()

    @app_commands.command(name="repo")
    async def repo(self, interaction: discord.Interaction):
        """code where?!"""
        await interaction.response.send_message("https://eule.wtf/it2zbot")

    @app_commands.command(name="issue")
    async def issue(self, interaction: discord.Interaction):
        """create an issue for this project on github"""
        await interaction.response.send_modal(Issue())


import torch
import torch.utils.data
from torch import nn, optim
from torch.nn import functional as F
import numpy as np

class SparseAttnBottleneck(nn.Module):
    def __init__(self, voc_size, dim, num_topk):
        super().__init__()
        self.voc_size = voc_size
        self.codebook = nn.Parameter(torch.randn(voc_size, dim))
        import math
        # initialize the codebook just like linear layer
        nn.init.kaiming_uniform_(self.codebook, a=math.sqrt(5))
        self.codebook.cuda()  # just a hack
        self.to_q = nn.Linear(dim, dim)
        self.to_k = nn.Linear(dim, dim)
        self.to_v = nn.Linear(dim, dim)
        self.num_topk = num_topk

    def max_neg_value(self, tensor):
        return -torch.finfo(tensor.dtype).max

    def forward(self, x):
        # x: (batch, *, dim)
        q = self.to_q(x)
        # here I first assume k and v are both comes from the codebook
        k = self.to_k(self.codebook)
        v = self.to_v(self.codebook)
        # attention
        dots = torch.einsum('bd,kd->bk', q, k)

        # top k of attention
        top, _ = dots.topk(self.num_topk, dim=-1)
        vk = top[..., -1].unsqueeze(-1).expand_as(dots)
        mask = dots < vk
        mask_value = self.max_neg_value(dots)
        dots.masked_fill_(mask, mask_value)

        # softmax
        attn = F.softmax(dots, dim=-1)

        # get output by applying attention weight to v
        out = torch.einsum('bk,kd->bd', attn, v)
        return out

from models.wta_utils import ResBlock, weights_init_wta, weights_init_vqvae

class SparseAttnAutoencoderFeatureMap(nn.Module):
    # https://github.com/iwyoo/tf_ConvWTA/blob/master/model.py
    def __init__(self, latent_dim=128, hid_channels=64, voc_size=8, num_topk=6, proj_hidden_dim=512,
                 ch=1, image_size=28, sample_num=1024,
                 kernel_size=5, net_type='vqvae',
                 out_act='sigmoid',
                 **kwargs):
        super(SparseAttnAutoencoderFeatureMap, self).__init__()
        sz = hid_channels
        self.sz = sz
        latent_dim = hid_channels
        code_sz = latent_dim
        self.hid_channels = hid_channels
        self.latent_dim = latent_dim
        self.proj_output_dim = latent_dim
        self.code_sz = code_sz
        self.ch = ch
        self.image_size = image_size
        self.sample_z = torch.rand(sample_num, ch, image_size, image_size)

        # use 1x1 conv to reduce the dimension of the feature map to 6 channels
        self.bottleneck_conv = nn.Conv2d(self.code_sz, 6, 1)
        self.bottleneck_fc = nn.Linear((image_size // 4) * (image_size // 4), latent_dim)

        if net_type == 'wta':
            self.enc = nn.Sequential(
                # input is Z, going into a convolution
                nn.Conv2d(ch, sz, kernel_size, 1, 0),
                nn.ReLU(True),
                nn.Conv2d(sz, sz, kernel_size, 1, 0),
                nn.ReLU(True),
                nn.Conv2d(sz, self.code_sz, kernel_size, 1, 0),
                nn.ReLU(True),
            )
            self.dec = nn.Sequential(
                # input is Z, going into a convolution
                nn.ConvTranspose2d(self.code_sz, sz, kernel_size, 1, 0),
                nn.ReLU(True),
                nn.ConvTranspose2d(sz, sz, kernel_size, 1, 0),
                nn.ReLU(True),
                nn.ConvTranspose2d(sz, ch, kernel_size, 1, 0),
            )
        elif net_type == 'vqvae':
            dim = sz
            self.code_sz = sz
            self.enc = nn.Sequential(
                nn.Conv2d(ch, dim, 4, 2, 1),
                nn.BatchNorm2d(dim),
                nn.ReLU(True),
                nn.Conv2d(dim, dim, 4, 2, 1),
                ResBlock(dim),
                ResBlock(dim),
            )

            self.dec = nn.Sequential(
                ResBlock(dim),
                ResBlock(dim),
                nn.ReLU(True),
                nn.ConvTranspose2d(dim, dim, 4, 2, 1),
                nn.BatchNorm2d(dim),
                nn.ReLU(True),
                nn.ConvTranspose2d(dim, ch, 4, 2, 1),
            )
        if out_act == 'sigmoid':
            self.dec = nn.Sequential(self.dec, nn.Sigmoid())
        elif out_act == 'tanh':
            self.dec = nn.Sequential(self.dec, nn.Tanh())
        elif out_act == 'none':
            pass
        else:
            raise ValueError('Unknown output activation function: {}'.format(out_act))
        self.out_act = out_act
        self.embedder = nn.Sequential(
            nn.Linear(self.latent_dim, self.latent_dim, bias=False),
            nn.BatchNorm1d(self.latent_dim)
        )
        self.sparse_attention = SparseAttnBottleneck(voc_size, self.latent_dim, num_topk=num_topk)

        self.projector = nn.Sequential(
            nn.Linear(self.latent_dim, proj_hidden_dim),
            nn.BatchNorm1d(proj_hidden_dim),
            nn.ReLU(),
            nn.Linear(proj_hidden_dim, self.proj_output_dim),
        )
        if net_type == 'wta':
            self.apply(weights_init_wta)
        elif net_type == 'vqvae':
            self.apply(weights_init_vqvae)
        self.net_type = net_type

    def bottleneck(self, latent):
        # latent: (batch, dim， 7，7)
        position_feature = self.bottleneck_conv(latent)  # (batch, num_components, 7, 7)
        b, c, h, w = position_feature.shape
        position_feature_max_pos = torch.argmax(position_feature.reshape(b, c, h * w),
                                                dim=1)  # (batch, num_components)

        feature_vector = self.bottleneck_fc(position_feature.reshape(b*c, -1))  # (batch * num_components, hidden_dim)
        emb = self.embedder(feature_vector)
        emb_after_attn = self.sparse_attention(emb)
        emb_proj = self.projector(emb_after_attn)  # (batch * num_components, hidden_dim)

        feature_map_out = torch.zeros_like(latent).reshape(b, -1, h * w).transpose(1, 2)  # (batch, 7*7, hidden_dim)

        # fill the feature map with the projected embedding according to position_feature_max_pos
        for i in range(c):
            feature_map_out[torch.arange(b), position_feature_max_pos[:, i], :] += emb_proj[i * b: (i + 1) * b, :]

        return feature_map_out.reshape(b, -1, h, w)

    def encode(self, x):
        h = self.enc(x.view(-1, self.ch, self.image_size, self.image_size))
        return h

    def decode(self, z):
        return self.dec(z)

    def forward(self, x, **kwargs):
        z = self.encode(x)
        latent = self.bottleneck(z)
        out = self.decode(latent)
        return out

from torchvision import datasets, transforms
import utils.data_utils

def get_data_config(dataset_name):
    if dataset_name in ['mnist', 'fashion_mnist', 'kuzushiji', 'google_draw']:
        transform = transforms.Compose([
            transforms.ToTensor(),
            transforms.Resize(28),
        ])
        config = {'image_size': 28, 'ch': 1, 'transform': transform, 'out_act': 'sigmoid'}
        return config
    elif dataset_name == 'omniglot':
        transform = transforms.Compose([
            transforms.ToTensor(),
            utils.data_utils.flip_image_value,
            transforms.Resize(28),
        ])
        config = {'image_size': 28, 'ch': 1, 'transform': transform, 'out_act': 'sigmoid'}
        return config
    elif dataset_name in ['cifar10', 'cifar100']:
        transform = transforms.Compose([
            transforms.ToTensor(),
            transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
        ])
        config = {'image_size': 32, 'ch': 3, 'transform': transform, 'out_act': 'tanh'}
        return config
    elif dataset_name in ['wikiart', 'celeba']:
        transform = transforms.Compose([
            transforms.ToTensor(),
            transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
            transforms.Resize((64, 64)),  # TODO: decide image size
        ])
        config = {'image_size': 64, 'ch': 3, 'transform': transform, 'out_act': 'tanh'}
        return config
    elif dataset_name in ['mpi3d', 'dsprite']:
        transform = None
        config = {'image_size': 64, 'ch': 1, 'transform': transform, 'out_act': 'sigmoid'}
        return config
    elif dataset_name == 'bach':
        transform = None
        config = {'image_size': 48, 'ch': 1, 'transform': transform, 'out_act': 'sigmoid'}
        return config
    else:
        raise ValueError('Unknown dataset name: {}'.format(dataset_name))

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

def get_new_model(**kwargs):
    model = SparseAttnAutoencoderFeatureMap(**kwargs).to(device)
    optimizer = optim.Adam(model.parameters(), lr=1e-3)
    return model, optimizer


alphabets='abcdefghijklmnopqrstuvwxyz'
weight=1
weights={}
for x in alphabets:
	weights[x] = weight
	weight+=1

def main():
	s=input()
	stringWeight=0
	for x in s:
		stringWeight += weights[x]
	print(stringWeight)

main()


# KicadModTree is free software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# KicadModTree is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with kicad-footprint-generator. If not, see < http://www.gnu.org/licenses/ >.
#
# (C) 2016 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>

from KicadModTree.Point import *
from KicadModTree.nodes.Node import Node
from KicadModTree.util.kicad_util import lispString

class Pad(Node):
    r"""Add a Pad to the render tree

    :param \**kwargs:
        See below

    :Keyword Arguments:
        * *number* (``int``, ``str``) --
          number/name of the pad (default: \"\")
        * *type* (``Pad.TYPE_THT``, ``Pad.TYPE_SMT``, ``Pad.TYPE_CONNECT``, ``Pad.TYPE_NPTH``) --
          type of the pad
        * *shape* (``Pad.SHAPE_CIRCLE``, ``Pad.SHAPE_OVAL``, ``Pad.SHAPE_RECT``, ``Pad.SHAPE_TRAPEZE``) --
          shape of the pad
        * *at* (``Point``) --
          center position of the pad
        * *rotation* (``float``) --
          rotation of the pad
        * *size* (``float``, ``Point``) --
          size of the pad
        * *offset* (``Point``) --
          offset of the pad
        * *drill* (``float``, ``Point``) --
          drill-size of the pad
        * *solder_paste_margin_ratio* (``float``) --
          solder paste margin ratio of the pad (default: 0)
        * *solder_mask_margin* (``float``) --
          solder mask margin of the pad (default: 0)
        * *layers* (``Pad.LAYERS_SMT``, ``Pad.LAYERS_THT``, ``Pad.LAYERS_NPTH``) --
          layers on which are used for the pad

    :Example:

    >>> from KicadModTree import *
    >>> Pad(number=1, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT,
    ...     at=[0, 0], size=[2, 2], drill=1.2, layers=Pad.LAYERS_THT)
    """

    TYPE_THT = 'thru_hole'
    TYPE_SMT = 'smd'
    TYPE_CONNECT = 'connect'
    TYPE_NPTH = 'np_thru_hole'
    _TYPES = [TYPE_THT, TYPE_SMT, TYPE_CONNECT, TYPE_NPTH]

    SHAPE_CIRCLE = 'circle'
    SHAPE_OVAL = 'oval'
    SHAPE_RECT = 'rect'
    SHAPE_ROUNDED_RECT = 'roundrect'
    SHAPE_TRAPEZE = 'trapezoid'
    _SHAPES = [SHAPE_CIRCLE, SHAPE_OVAL, SHAPE_RECT, SHAPE_ROUNDED_RECT, SHAPE_TRAPEZE]

    LAYERS_SMT = ['F.Cu', 'F.Mask', 'F.Paste']
    LAYERS_THT = ['*.Cu', '*.Mask']
    LAYERS_NPTH = ['*.Cu', '*.Mask']

    def __init__(self, **kwargs):
        Node.__init__(self)

        self._initNumber(**kwargs)
        self._initType(**kwargs)
        self._initShape(**kwargs)
        self._initPosition(**kwargs)
        self._initSize(**kwargs)
        self._initOffset(**kwargs)
        self._initDrill(**kwargs)  # requires pad type and offset
        self._initSolderPasteMargin(**kwargs)
        self._initSolderMaskMargin(**kwargs)
        self._initLayers(**kwargs)

    def _initNumber(self, **kwargs):
        self.number = kwargs.get('number', "")  # default to an un-numbered pad

    def _initType(self, **kwargs):
        if not kwargs.get('type'):
            raise KeyError('type not declared (like "type=Pad.TYPE_THT")')
        self.type = kwargs.get('type')
        if self.type not in Pad._TYPES:
            raise ValueError('{type} is an invalid type for pads'.format(type=self.type))

    def _initShape(self, **kwargs):
        if not kwargs.get('shape'):
            raise KeyError('shape not declared (like "shape=Pad.SHAPE_CIRCLE")')
        self.shape = kwargs.get('shape')
        if self.shape not in Pad._SHAPES:
            raise ValueError('{shape} is an invalid shape for pads'.format(shape=self.shape))

    def _initPosition(self, **kwargs):
        if not kwargs.get('at'):
            raise KeyError('center position not declared (like "at=[0,0]")')
        self.at = Point2D(kwargs.get('at'))

        self.rotation = kwargs.get('rotation', 0)

    def _initSize(self, **kwargs):
        if not kwargs.get('size'):
            raise KeyError('pad size not declared (like "size=[1,1]")')
        if type(kwargs.get('size')) in [int, float]:
            # when the attribute is a simple number, use it for x and y
            self.size = Point2D([kwargs.get('size'), kwargs.get('size')])
        else:
            self.size = Point2D(kwargs.get('size'))

    def _initOffset(self, **kwargs):
        self.offset = Point2D(kwargs.get('offset', [0, 0]))

    def _initDrill(self, **kwargs):
        if self.type in [Pad.TYPE_THT, Pad.TYPE_NPTH]:
            if not kwargs.get('drill'):
                raise KeyError('drill size required (like "drill=1")')
            if type(kwargs.get('drill')) in [int, float]:
                # when the attribute is a simple number, use it for x and y
                self.drill = Point2D([kwargs.get('drill'), kwargs.get('drill')])
            else:
                self.drill = Point2D(kwargs.get('drill'))
            if self.drill.x < 0 or self.drill.y < 0:
                raise ValueError("negative drill size not allowed")
        else:
            self.drill = None
            if kwargs.get('drill'):
                pass  # TODO: throw warning because drill is not supported

    def _initSolderPasteMargin(self, **kwargs):
        self.solder_paste_margin_ratio = kwargs.get('solder_paste_margin_ratio', 0)

    def _initSolderMaskMargin(self, **kwargs):
        self.solder_mask_margin = kwargs.get('solder_mask_margin', 0)

    def _initLayers(self, **kwargs):
        if not kwargs.get('layers'):
            raise KeyError('layers not declared (like "layers=[\'*.Cu\', \'*.Mask\', \'F.SilkS\']")')
        self.layers = kwargs.get('layers')

    # calculate the outline of a pad
    def calculateBoundingBox(self):
        return Node.calculateBoundingBox(self)

    def _getRenderTreeText(self):
        render_strings = ['pad']
        render_strings.append(lispString(self.number))
        render_strings.append(lispString(self.type))
        render_strings.append(lispString(self.shape))
        render_strings.append(self.at.render('(at {x} {y})'))
        render_strings.append(self.size.render('(size {x} {y})'))
        render_strings.append('(drill {})'.format(self.drill))
        render_strings.append('(layers {})'.format(' '.join(self.layers)))

        render_text = Node._getRenderTreeText(self)
        render_text += '({})'.format(' '.join(render_strings))

        return render_text


# https://leetcode.com/problems/kth-largest-sum-in-a-binary-tree/

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Solution:
    def kthLargestLevelSum(self, root: Optional[TreeNode], k: int) -> int:

        q = [root]
        heap = []

        while q:
            level_sum = sum([i.val for i in q])
            heapq.heappush(heap, -level_sum)
            q = [child for p in q for child in [p.left, p.right] if child]

        result = -1
        while k :
            result = -heapq.heappop(heap) if heap else -1
            k-=1

        return result


import random
from itertools import combinations
import math
import matplotlib.pyplot as plt
from tkinter import *
from functools import partial

import os
from shutil import rmtree

class Individuo():
    def __init__(self, X,Y,bino,dec):
        self.X = X
        self.Y = Y
        self.bino = bino
        self.dec = dec

    def __repr__(self):
        rep = 'Individuo(' + str(self.X) +' | '+ str(self.Y) + ' | ' + str(self.bino) +' | ' + str(self.dec) +')'
        return rep

class AlgoritmoGenetico():

    def __init__(self, Xmin,Xmax, intervalo, rango, puntos, poblacionMaxima, poblacionInicial, generaciones,noBits, Pmi,Pmg, Pc):
        self.Xmin = Xmin
        self.intervalo = intervalo
        self.Xmax = Xmax
        self.rango = rango
        self.puntos = puntos
        self.poblacionInicial = poblacionInicial
        self.poblacionMaxima = poblacionMaxima
        self.generaciones = generaciones
        self.noBits = noBits
        self.individuos = []
        self.probabilidadDeCruce = Pc
        self.Pmi = Pmi
        self.Pmg = Pmg

    def generarPoblacionInicial(self):
        individuos = []
        for i in range(0,self.poblacionInicial):
            binary = 0
            decimal = random.uniform(0,self.rango)
            binary = bin(int(decimal))
            binary = binary.removeprefix("0b")
            if(len(binary) < self.noBits):
                binary = binary.zfill(self.noBits)
            x = self.Xmin + (decimal * self.intervalo)
            self.individuos.append(Individuo(x,0,binary,decimal))
        individuos = self.individuos
        return individuos

    def posiblesParejas(self):
        parejas = []
        temp = combinations(self.individuos,2)
        for i in list(temp):
            parejas.append(i)
        return parejas

    def posiblesParejasX(self):
        listCombinaciones = []
        padres = []
        for i in range(len(self.individuos)):
            individuosSeleccionados = random.randint(2, len(self.individuos))
            candidatos = random.sample(self.individuos, individuosSeleccionados)
            ganador = max(candidatos, key = lambda individuo: individuo.Y)
            padres.append(ganador)
        temp = combinations(padres,2)
        for i in list(temp):
            listCombinaciones.append(i)
        return listCombinaciones

    def cruzaX(self, listParejas):
            listNewgen = []
            if(len(listParejas) > 1):
                for i in range(len(listParejas)):
                    for k in range(0,1):
                        MascaraDeCruce = ''
                        child1 = ''
                        for y in range(self.noBits):
                            MascaraDeCruce = MascaraDeCruce + "" + str(random.randint(0,1))
                        var = listParejas[i]
                        if(k == 0):
                            gen1 = var[0].bino
                            gen2 = var[1].bino
                        else:
                            gen1 = var[1].bino
                            gen2 = var[0].bino
                        for j in range(len(gen1)):
                            if MascaraDeCruce[j] == '1':
                                child1 = child1 + gen1[j]
                            else:
                                child1 = child1 + gen2[j]
                        listNewgen.append(child1)
            return listNewgen

    def mutacion(self, listCruza):

        listNewInd = []
        listNewBit = []
        listNewBit2 = []
        listAnalizador= []
        listNoCruza= []
        listNew = []
        listGenMutado= []
        for i in range(len(listCruza)):
            var = listCruza[i]
            pmir=float("{:.4f}".format(random.uniform(0.0,1.0)))
            if pmir < self.Pmi:
                listNewInd.append(listCruza[i])
            if pmir > self.Pmi:
                listGenMutado.append(listCruza[i])
        for i in range(len(listNewInd)):
                var =listNewInd[i]
                for y in range(len(var)):
                    listNew.append(var[y])
                for y in range(len(var)):
                    listAnalizador.append(var[y])
                    pmgr= random.randint(0,len(var)-1)
                    listNew[pmgr]
                    lis2=listNew[pmgr]
                    listNewBit.append(lis2)
                # print(listNewBit)
                bit2 = ''.join(listNewBit)
                listGenMutado.append(bit2)
                listAnalizador.clear()
                listNewBit.clear()
                listNew.clear()
        return listGenMutado

    def ConvertirAObjetos(self,mutados):
        for i in range(0,len(mutados)):
            mutadoBinario = mutados[i]
            posicion = 0
            decimal = 0
            binario = mutadoBinario[::-1]
            for digito in binario:
                # Elevar 2 a la posición actual
                multiplicador = 2**posicion
                decimal += float(digito) * multiplicador
                posicion += 1
            x = self.Xmin + (decimal * self.intervalo)
            self.individuos.append(Individuo(x,0,mutados[i],decimal))

    def limpiar(self):
        auxIndividuos = []
        # i = 0
        for i in range(len(self.individuos)):
            if(self.individuos[i].X <= self.Xmax):
                auxIndividuos.append(self.individuos[i])
        self.individuos.clear()
        self.individuos = auxIndividuos
        # for elemento in self.individuos:
        #     if(elemento.X > self.Xmax):
        #         self.individuos.pop(i)
            # i += 1

    def fx(self):
        dataAux =  []
        for i in range(len(self.individuos)):
            x = self.individuos[i].X
            op = float("{:.4f}".format(math.sin(math.radians(x))))
            op2 = float("{:.4f}".format(math.sqrt(2*(pow(x,2))-x-2)))
            if(op2 > 0):
                resultado = float("{:.4f}".format(op * op2))
                self.individuos[i].Y = resultado
                dataAux.append(self.individuos[i])
        self.individuos.clear()
        self.individuos = dataAux
        # for elemento in self.individuos:

        # print(len(self.individuos))

    def poda(self):
        uniqueData = []
        if(len(self.individuos) > self.poblacionMaxima):
            while(len(self.individuos) > self.poblacionMaxima):
                posicion = random.randint(0, self.poblacionMaxima)
                self.individuos.pop(posicion)
        for individuo in self.individuos:
            if not any(I.bino == individuo.bino for I in uniqueData):
                uniqueData.append(individuo)
        self.individuos.clear()
        self.individuos = uniqueData

def graficasXiteracion(self,x, fx):
    try:
        rmtree("assets\GraficaHistorial\img")
    except:
        pass
    plt.plot(x,fx, label="Mejores individuo", color="green", linestyle="-",marker ='.')
    plt.legend()
    os.makedirs("assets\GraficaHistorial\img", exist_ok=True)
    plt.savefig("assets\GraficaHistorial\img\GraficaGeneral.png")
    plt.close()

def graficasXgeneracion(self, listNuevaPAptitud,listNuevaFx,index):
    print('Entro a graficas x generacion')
    plt.title("Generacion: "+str(index))
    plt.plot(listNuevaPAptitud,listNuevaFx, label="Generacion "+str(index), color="blue", linestyle="none",marker ='.')
    plt.legend()
    os.makedirs("assets\GraficasIndividuales\img", exist_ok=True)
    plt.savefig("assets\GraficasIndividuales\img\GraficaIndividual "+str(index)+".png")
    plt.close()

if __name__ == "__main__":
    def envioDatos(generaciones, poblacionM, rangoMax, rangoMin, intervalo, mutacionInd, mutacionGen, probCruza):
        print("generaciones :", generaciones.get())
        print("poblacionM :", poblacionM.get())
        print("rangoMaximo :", rangoMax.get())
        print("rangoMinimo :", rangoMin.get())
        print("Intervalo :", intervalo.get())
        print("Mutacion individuo :", mutacionInd.get())
        print("Mutacion gen :", mutacionGen.get())
        print("Probabilida de cruza: ", probCruza.get())

        return
    #window
    tkWindow = Tk()
    tkWindow.geometry('400x250')
    tkWindow.title('Obtencion de datos')
    #----
    usernameLabel = Label(tkWindow, text="Generaciones").grid(row=0, column=0)
    generaciones = IntVar()
    generacionesEntry = Entry(tkWindow, textvariable=generaciones).grid(row=0, column=1)
    #-----
    poblacionMLabel = Label(tkWindow,text="Poblacion Maxima").grid(row=1, column=0)
    poblacionM = DoubleVar()
    poblacionMEntry = Entry(tkWindow, textvariable=poblacionM).grid(row=1, column=1)
    #-----
    poblacionMLabel = Label(tkWindow,text="Rango maximo").grid(row=2, column=0)
    rangoMaximo = DoubleVar()
    rangoMaximoEntry = Entry(tkWindow, textvariable=rangoMaximo).grid(row=2, column=1)
    #-----
    poblacionMLabel = Label(tkWindow,text="Rango minimo").grid(row=3, column=0)
    rangoMinimo = DoubleVar()
    rangoMinimoEntry = Entry(tkWindow, textvariable=rangoMinimo).grid(row=3, column=1)
    #-----
    poblacionMLabel = Label(tkWindow,text="Intervalo").grid(row=4, column=0)
    intervalo = DoubleVar()
    intervaloEntry = Entry(tkWindow, textvariable=intervalo).grid(row=4, column=1)
    #-----
    poblacionMLabel = Label(tkWindow,text="Mutacion del individuo").grid(row=5, column=0)
    mutacionIndividuo = DoubleVar()
    mutacionIndividuoEntry = Entry(tkWindow, textvariable=mutacionIndividuo).grid(row=5, column=1)
    #-----
    poblacionMLabel = Label(tkWindow,text="Mutacion del gen").grid(row=6, column=0)
    mutacionGen = DoubleVar()
    mutacionGenEntry = Entry(tkWindow, textvariable=mutacionGen).grid(row=6, column=1)

    probabilidadCruzaLabel = Label(tkWindow,text="Probabilidad de cruza").grid(row=7, column=0)
    probCruza = DoubleVar()
    probCruzaEntry = Entry(tkWindow, textvariable=probCruza).grid(row=7, column=1)

    envioDatos = partial(envioDatos, generaciones, poblacionM, rangoMaximo, rangoMinimo, intervalo, mutacionIndividuo, mutacionGen, probCruza)
    #login button
    btnEnviar = Button(tkWindow, text="Enviar", command=envioDatos).grid(row=8, column=0)

    tkWindow.mainloop()

    print("Generaciones: ")
    generaciones = generaciones.get()
    print("Población maxima")
    poblacionMaxima = poblacionM.get()
    poblacionInicial = random.randint(2,poblacionMaxima)
    print("Rango Maximo")
    xMaximo = rangoMaximo.get()
    print("Rango Minimo")
    xMinimo = rangoMinimo.get()
    print("Intervalo")
    intervalo = intervalo.get()
    rango = xMaximo-xMinimo
    puntos = (rango/intervalo)+1
    bit= bin(int(puntos))
    bit=bit.removeprefix("0b")
    noBits= len(bit)
    print(noBits)
    print("Ingrese la probabilidad de mutación del inidividuo")
    Pmi= mutacionIndividuo.get()
    print("Ingrese la probabilidad de mutacion de gen")
    Pmg= mutacionGen.get()
    print("Ingrese la probabilidad de cruza")
    Pc= probCruza.get()

    ag = AlgoritmoGenetico(xMinimo, xMaximo, intervalo, rango, puntos, poblacionMaxima, poblacionInicial, generaciones, noBits, Pmi,Pmg, Pc)

    ag.generarPoblacionInicial()

    MejoresIndividuos = []
    MediaIndividuos = []
    PeoresIndividuos = []

    for i in range(0,generaciones):
        parejas = ag.posiblesParejasX()
        hijos = ag.cruzaX(parejas)
        mutados = ag.mutacion(hijos)
        ag.ConvertirAObjetos(mutados)
        ag.fx()
        # print("_______________________________ya2_________________")
        ag.limpiar()
        ag.poda()
        MejoresAptitudes = [individuo.Y for individuo in ag.individuos]
        MejoresIndividuos.append(max(MejoresAptitudes))
        aptitudes = [individuo.Y for individuo in ag.individuos]
        promedio = sum(aptitudes)/len(aptitudes)
        MediaIndividuos.append(promedio)
        peoresAptitudes = [individuo.Y for individuo in ag.individuos]
        PeoresIndividuos.append(min(peoresAptitudes))
        print(i)
    # print("_____MEJORES_____\n" , MejoresIndividuos)
    # print("______PROMEDIO_____\n", MediaIndividuos)
    # print("_____PEOR_____\n", PeoresIndividuos)

        try:
            os.rmdir("assets")
        except:
            pass
        os.makedirs("assets\Video", exist_ok=True)

        plt.plot(MejoresIndividuos, label="Mejor individuo", color="red", linestyle="-",)
        plt.plot(MediaIndividuos, label="Promedio", color="blue", linestyle="-",)
        plt.plot(PeoresIndividuos, label="Peor individuo", color="green", linestyle="-")
        plt.legend()
        os.makedirs("assets\Grafica", exist_ok=True)
        plt.savefig("assets\Grafica\GraficaHistorial.png")
        plt.close()

        TodaslasX = [individuo.X for individuo in ag.individuos]
        print(TodaslasX)
        TodaslasY = [individuo.Y for individuo in ag.individuos]
        print(TodaslasY)
        fig, ax = plt.subplots()
        ax.scatter(x = TodaslasX, y = TodaslasY)
        os.makedirs("assets\GraficaxGeneracion", exist_ok=True)
        plt.savefig('assets\GraficaxGeneracion\GraficaHistorial'+str(i)+'.png')
        plt.close()


from __future__ import annotations

from typing import NewType

from htmltools import Tag, TagAttrs, TagAttrValue, TagChild

from ._htmldeps import page_dep
from ._utils import assign_to_slot

SidebarTag = NewType("SidebarTag", Tag)

def sidebar(
    *args: IconSectionTag | TagChild | TagAttrs,
    open_width_px: int = 320,
    **kwargs: TagAttrValue,
) -> SidebarTag:
    """
    Collapsible sidebar for use in dashboards and cards.

    Parameters
    ----------
    *args : Union[TagChild, TagAttrs]
        Child elements to this tag.
    open_width_px : int, optional
        The width of the sidebar when it is open, in pixels, by default 320.
    **kwargs : Dict[str, TagAttrValue]
        Attributes to this tag.

    Returns
    -------
    Tag representing a collapsible sidebar.

    See Also
    --------
    ~shinycomponent.dashboard
    ~shinycomponent.card
    ~htmltools.Tag
    """
    return SidebarTag(
        Tag(
            "shiny-sidebar",
            page_dep(),
            *args,
            _add_ws=False,
            openWidthPx=open_width_px,
            **kwargs,
        )
    )

FooterTag = NewType("DashboardFooterTag", Tag)

def footer(
    *args: TagChild | TagAttrs, _add_ws: bool = True, **kwargs: TagAttrValue
) -> FooterTag:
    """
    A footer for a dashboard. Sticks to bottom of dashboard layouts defined with
    `shinycomponent.page_dashboard()` or `shinycomponent.dashboard()`.

    Parameters
    ----------
    *args
        Child elements to this tag.
    **kwargs
        Attributes passed along to html element.

    Returns
    -------
    Tag element

    See Also
    --------
    ~shinycomponent.dashboard
    ~shinycomponent.page_dashboard
    ~htmltools.Tag
    """
    return FooterTag(Tag("sc-footer", page_dep(), *args, _add_ws=_add_ws, **kwargs))

HeaderTag = NewType("DashboardHeaderTag", Tag)

def header(
    *args: TagChild | TagAttrs, _add_ws: bool = True, **kwargs: TagAttrValue
) -> HeaderTag:
    """
    A header for a dashboard. Sticks to top of dashboard layouts defined with
    `shinycomponent.page_dashboard()` or `shinycomponent.dashboard()`.

    Parameters
    ----------
    *args
        Child elements to this tag.
    **kwargs
        Attributes passed along to html element.

    Returns
    -------
    Tag element

    See Also
    --------
    ~shinycomponent.dashboard
    ~shinycomponent.page_dashboard
    ~htmltools.Tag
    """
    return HeaderTag(Tag("sc-header", page_dep(), *args, _add_ws=_add_ws, **kwargs))

IconSectionTag = NewType("IconSectionTag", Tag)

def icon_section(
    *args: TagChild | TagAttrs,
    icon: str | Tag,
    **kwargs: TagAttrValue,
) -> IconSectionTag:
    """
    A section with a left-side icon. Can be paired with sidebar to create a sidebar that
    will collapse to icons

    Parameters
    ----------
    *args
        The contents of the section. E.g. inputs and text.
    icon
        The icon to display on the left side of the section. Can be a representing an
        icon available from the [iconify icons list](https://icon-sets.iconify.design/)
        or an abritrary tag. (Try and make sure the tag is simple and narrow or else
        overflow will happen)
    **kwargs
        Additional attributes passed to the element

    Returns
    -------
    Section with left-side icon

    See Also
    --------
    ~shinycomponent.sidebar
    ~shinycomponent.icon
    ~shinycomponent.dashboard
    ~htmltools.Tag
    """

    # If icon is a string, we just pass it as the property icon and let the component do
    # the work. If it's a tag, we need to place it as a child with the slot attribute of
    # "icon"
    if isinstance(icon, str):
        kwargs["icon"] = icon
    else:
        args = (assign_to_slot(icon, "icon"), *args)

    return IconSectionTag(
        Tag("shiny-section", page_dep(), *args, _add_ws=True, **kwargs)
    )


# -*- coding: utf-8 -*-

from DateTime import DateTime
from plone import api
from plone.namedfile import NamedBlobFile
from persistent.mapping import PersistentMapping
from Products.PloneMeeting.migrations.migrate_to_4200 import Migrate_To_4200 as PMMigrate_To_4200
from Products.PloneMeeting.migrations.migrate_to_4201 import Migrate_To_4201
from Products.PloneMeeting.migrations.migrate_to_4202 import Migrate_To_4202
from Products.PloneMeeting.migrations.migrate_to_4203 import Migrate_To_4203
from Products.PloneMeeting.migrations.migrate_to_4204 import Migrate_To_4204
from Products.PloneMeeting.migrations.migrate_to_4205 import Migrate_To_4205
from Products.PloneMeeting.migrations.migrate_to_4206 import Migrate_To_4206
from Products.PloneMeeting.migrations.migrate_to_4207 import Migrate_To_4207
from Products.PloneMeeting.migrations.migrate_to_4208 import Migrate_To_4208
from Products.PloneMeeting.migrations.migrate_to_4209 import Migrate_To_4209
from Products.PloneMeeting.migrations.migrate_to_4210 import Migrate_To_4210

import logging

logger = logging.getLogger('MeetingCommunes')

class Migrate_To_4200(PMMigrate_To_4200):

    def _fixUsedMeetingWFs(self):
        """meetingcommunes_workflow/meetingitemcommunes_workflows do not exist anymore,
           we use meeting_workflow/meetingitem_workflow."""
        logger.info("Adapting 'meetingWorkflow/meetingItemWorkflow' for every MeetingConfigs...")
        for cfg in self.tool.objectValues('MeetingConfig'):
            if cfg.getMeetingWorkflow() == 'meetingcommunes_workflow':
                cfg.setMeetingWorkflow('meeting_workflow')
            if cfg.getItemWorkflow() == 'meetingitemcommunes_workflow':
                cfg.setItemWorkflow('meetingitem_workflow')
        # delete old unused workflows, aka every workflows containing 'communes_workflow'
        wfTool = api.portal.get_tool('portal_workflow')
        wfs_to_delete = [wfId for wfId in wfTool.listWorkflows()
                         if 'communes_workflow' in wfId]
        if wfs_to_delete:
            wfTool.manage_delObjects(wfs_to_delete)
        logger.info('Done.')

    def _get_wh_key(self, itemOrMeeting):
        """Get workflow_history key to use, in case there are several keys, we take the one
           having the last event."""
        keys = itemOrMeeting.workflow_history.keys()
        if len(keys) == 1:
            return keys[0]
        else:
            lastEventDate = DateTime('1950/01/01')
            keyToUse = None
            for key in keys:
                if itemOrMeeting.workflow_history[key][-1]['time'] > lastEventDate:
                    lastEventDate = itemOrMeeting.workflow_history[key][-1]['time']
                    keyToUse = key
            return keyToUse

    def _adaptWFDataForItemsAndMeetings(self):
        """We use PM default WFs, no more meetingcommunes(item)_workflow...
           Adapt:
           - workflow_history for items and meetings;
           - takenOverByInfos for items."""
        logger.info('Updating WF history items and meetings to use new WF id...')
        wfTool = api.portal.get_tool('portal_workflow')
        catalog = api.portal.get_tool('portal_catalog')
        for cfg in self.tool.objectValues('MeetingConfig'):
            # this will call especially part where we duplicate WF and apply WFAdaptations
            cfg.registerPortalTypes()
            itemWFId = cfg.getItemWorkflow()
            for brain in catalog(portal_type=(cfg.getItemTypeName(), cfg.getMeetingTypeName())):
                itemOrMeeting = brain.getObject()
                itemOrMeetingWFId = wfTool.getWorkflowsFor(itemOrMeeting)[0].getId()
                if itemOrMeetingWFId not in itemOrMeeting.workflow_history:
                    wf_history_key = self._get_wh_key(itemOrMeeting)
                    itemOrMeeting.workflow_history[itemOrMeetingWFId] = \
                        tuple(itemOrMeeting.workflow_history[wf_history_key])
                    del itemOrMeeting.workflow_history[wf_history_key]
                    # do this so change is persisted
                    itemOrMeeting.workflow_history = itemOrMeeting.workflow_history
                else:
                    # already migrated
                    break
                if itemOrMeeting.__class__.__name__ == 'MeetingItem':
                    takenOverByInfos = itemOrMeeting.takenOverByInfos.copy()
                    newTakenOverByInfos = PersistentMapping()
                    for k, v in takenOverByInfos.items():
                        wf_name, state = k.split('__wfstate__')
                        newTakenOverByInfos['{0}__wfstate__{1}'.format(itemWFId, state)] = v
                    if sorted(newTakenOverByInfos.keys()) != sorted(takenOverByInfos.keys()):
                        itemOrMeeting.takenOverByInfos = newTakenOverByInfos
        logger.info('Done.')

    def _hook_before_meeting_to_dx(self):
        """Adapt WF related stored data if items and meetings before migrating to DX."""
        self._adaptWFDataForItemsAndMeetings()

    def _add_dashboard_pod_template_export_users_groups(self):
        """Add the export users and groups DashboardPODTemplate in the contacts directory."""
        logger.info("Adding 'Export users and groups' to 'contacts' directory...")
        pod_template_id = 'export-users-groups'
        contacts = self.portal.contacts
        if pod_template_id in contacts.objectIds():
            self._already_migrated()
            return

        profile_path = self.ps._getImportContext(self.profile_name)._profile_path
        odt_path = profile_path + '/../examples_fr/templates/users-groups-export.ods'
        odt_file = open(odt_path, 'rb')
        odt_binary = odt_file.read()
        odt_file.close()
        data = {'title': 'Export utilisateurs et groupes',
                'pod_formats': ['ods', 'xls'],
                'dashboard_collections': contacts.get('orgs-searches').all_orgs.UID(),
                'odt_file': NamedBlobFile(
                    data=odt_binary,
                    contentType='application/vnd.oasis.opendocument.text',
                    filename=u'users-groups-export.ods'),
                'use_objects': False,
                }
        pod_template = api.content.create(
            id=pod_template_id,
            type='DashboardPODTemplate',
            container=contacts,
            **data)
        pod_template.reindexObject()
        logger.info('Done.')

    def _mc_fixPODTemplatesInstructions(self):
        '''Make some replace in POD templates to fit changes in code...'''
        # for every POD templates
        replacements = {}
        # specific for Meeting POD Templates
        meeting_replacements = {}
        # specific for MeetingItem POD Templates
        item_replacements = {}

        self.updatePODTemplatesCode(replacements, meeting_replacements, item_replacements)

    def run(self,
            profile_name=u'profile-Products.MeetingCommunes:default',
            extra_omitted=[]):

        if self.is_in_part('a'):  # main step

            # change self.profile_name that is reinstalled at the beginning of the PM migration
            self.profile_name = profile_name

            # fix used WFs before reinstalling
            self._fixUsedMeetingWFs()

            # add a new DashboardPodTemplate in contacts directory
            self._add_dashboard_pod_template_export_users_groups()

            # fix some instructions in POD templates
            self._mc_fixPODTemplatesInstructions()

        # call steps from Products.PloneMeeting
        super(Migrate_To_4200, self).run(extra_omitted=extra_omitted)

        if self.is_in_part('c'):  # last step

            # execute upgrade steps in PM that were added after main upgrade to 4200
            Migrate_To_4201(self.portal).run(from_migration_to_4200=True)
            Migrate_To_4202(self.portal).run(from_migration_to_4200=True)
            Migrate_To_4203(self.portal).run(from_migration_to_4200=True)
            Migrate_To_4204(self.portal).run(from_migration_to_4200=True)
            Migrate_To_4205(self.portal).run(from_migration_to_4200=True)
            Migrate_To_4206(self.portal).run(from_migration_to_4200=True)
            Migrate_To_4207(self.portal).run(from_migration_to_4200=True)
            Migrate_To_4208(self.portal).run(from_migration_to_4200=True)
            Migrate_To_4209(self.portal).run(from_migration_to_4200=True)
            Migrate_To_4210(self.portal).run(from_migration_to_4200=True)

            # now MeetingCommunes specific steps
            logger.info('Migrating to MeetingCommunes 4200...')

            # add new searches (searchitemswithnofinanceadvice)
            self.addNewSearches()

# The migration function -------------------------------------------------------
def migrate(context):
    '''This migration function:

       1) Change MeetingConfig.meetingWorkflow to use meeting_workflow/meetingitem_workflow;
       2) Call PloneMeeting migration to 4200;
       3) Call every PloneMeeting 420x upgrade steps;
       4) In _after_reinstall hook, adapt items and meetings workflow_history
          to reflect new defined workflow done in 1);
       5) Add new searches.
    '''
    migrator = Migrate_To_4200(context)
    migrator.run()
    migrator.finish()


with open("input.txt") as f:
    s = sorted(list(map(int, f.readlines())))
len = len(s)
for i in range(len-3):
    sum = 2020 - s[i]
    j=i+1
    k=len-1
    while(j<k):
        if s[j]+s[k] == sum:
            print('one: {}'.format(s[i]))
            print('two {}'.format(s[j]))
            print('three {}'.format(s[k]))
            print('result: {}'.format(s[i] * s[j] * s[k]))
            exit('--------End------')
        if s[j] + s[k] < sum:
            j=j+1
        if s[j] + s[k] > sum:
            k=k-1
# Time complexity O(n^2)


# my_list = ["dog", "cat", "bird"]

# for (index, value) in my_list:
#     print(index, value)

the_list = [1, 1, 2, 3, 4, 4]

def removeDuplicates(list):
    cleanedList = []
    for num in list:
        if num not in cleanedList:
            cleanedList.append(num)
    print(cleanedList)
    return len(cleanedList)

print(removeDuplicates(the_list))


#!/usr/bin/env python
import operator
import os
import random
import re
import sys
from collections import defaultdict
from datetime import datetime
from subprocess import Popen, PIPE
from tarfile import TarFile

from cluster.common import Cluster
from cluster.config import USER, LOG_PATH, USER_LABEL, PBS_ARCHIVE_PATH, HOME
from cluster.tools import confirm_delete, parse_timearg, truncate_str, cache_cmd, print_table

class TimeDeltaError(Exception):
    """Custom error thrown when parsing time delta"""

class TimeDelta:
    """Makes filtering job list by arbitrary constraints simpler"""

    def __init__(self, arg, newer=True):
        self.compare = operator.ge if newer else operator.le

        if re.match(r'^\d{4}-\d{2}-\d{2}$', arg):
            self.field = 'date'
            self.value = datetime.strptime(arg, '%Y-%m-%d')
        elif re.match(r'^\d+[a-cn-u.]*-*\d*[a-cn-u.]*$', arg):
            self.field = 'job_id'
            if '-' in arg:
                self.value_min = int(arg.split('-')[0].split('.')[0])
                self.value_max = int(arg.split('-')[1].split('.')[0])
            else:
                self.value_min = int(arg.split('.')[0])
        elif ',' in arg:
            self.compare = operator.contains
            self.field = 'job_id_list'
            self.value = [int(j) for j in arg.split(',')]
        elif re.match(r'^\d+[hdw]$', arg):
            self.field = 'date'
            self.value = parse_timearg(arg)
        else:
            raise TimeDeltaError("Unable to parse: %s" % arg)

    def filter(self, jobs):
        for job in jobs:
            if self.field == 'date':
                if job.finished:
                    if self.compare(job.finished, self.value):
                        yield job
                elif not job.qstat and job.start_time:
                    if self.compare(job.start_time, self.value):
                        yield job
            if self.field == 'job_id_list':
                if self.compare(self.value, job.job_id):
                    yield job
            elif self.field == 'job_id':
                if self.compare(job.job_id, self.value_min):
                    if hasattr(self, 'value_max'):
                        if not operator.le(job.job_id, self.value_max):
                            continue
                    yield job

def read_qstat():
    """Parses the brief qstat output for all users and makes 3 separate summaries: users, queues, total

    :return: Job summaries for users, queues and total
    :rtype: tuple[dict, dict, dict]
    """
    qstat = cache_cmd('/usr/bin/qstat')

    user_stats = defaultdict(lambda: defaultdict(lambda: defaultdict(int)))
    queue_stats = defaultdict(lambda: defaultdict(int))
    total_stats = defaultdict(int)

    for line in qstat.split('\n')[2:]:  # skip first two rows of header
        if not line:
            continue

        job_id, name, user, time, status, queue = line.strip().split()

        user = USER_LABEL if user == USER else user
        user_stats[user][queue][status] += 1
        queue_stats[queue][status] += 1
        total_stats[status] += 1

    return user_stats, queue_stats, total_stats

def print_all_jobs():
    """Print a short summary of running/queued jobs. Identical to the old jobstatus script."""
    user_stats, queue_stats, total_stats = read_qstat()

    print("=========================================================")
    print("%-15s %-10s %-10s %-10s %-10s" % ('User', 'Queue', 'Running', 'Queued', 'Exiting'))
    print("---------------------------------------------------------")

    statuses = ('R', 'Q', 'E')

    for user in sorted(user_stats):
        for queue in sorted(user_stats[user]):
            row = tuple([user, queue] + [user_stats[user][queue].get(s, 0) for s in statuses])
            print("%-15s %-10s %-10s %-10s %-10s" % row)

    print("---------------------------------------------------------")

    for queue in sorted(queue_stats):
        row = tuple(['', queue] + [queue_stats[queue].get(s, 0) for s in statuses])
        print("%-15s %-10s %-10s %-10s %-10s" % row)

    print("                -----------------------------------------")

    row = tuple(['', 'totals'] + [total_stats.get(s, 0) for s in statuses])
    print("%-15s %-10s %-10s %-10s %-10s" % row)

def details(args):
    """Print job details for current user. Output format can be fine-tuned with args argument.

    :param args: Arguments from argparse
    :type args: argparse.Namespace
    """
    # Don't cache commands if we're deleting jobs, we need fresh status
    cluster = Cluster(jobs_qstat=True, jobs_log=True, jobs_pbs=True, cached=not args.delete)
    jobs = cluster.jobs_list()

    filtering = True in (args.print_running, args.print_queued, args.print_completed, args.print_failed)

    # We're about to delete some jobs, make sure to sanitize other arguments to make sense with delete action
    if args.delete:
        # Override to table view when deleting jobs, you want to see what'll get killed
        if args.output != 'table':
            sys.stderr.write('Warning: Output format forced from "%s" to "table" for delete action.\n' % args.output)
            args.output = 'table'

        # We can delete only running and queued, make sure they're both included if either is not explicitly enabled
        if not args.print_queued and not args.print_running:
            args.print_queued = True
            args.print_running = True

        filtering = True

        # Get rid of completed and failed if they were explicitly defined
        if args.print_completed or args.print_failed:
            sys.stderr.write('Warning: Ignore completed and failed jobs for delete action.\n')
            args.print_completed = False
            args.print_failed = False

        # Limiting by number of jobs makes no sense for deleting, get rid of it
        if args.limit_output and args.limit_output.isdigit() and int(args.limit_output) < 10000:
            sys.stderr.write('Warning: Filtering by number of jobs (%s) ignored.\n' % args.limit_output)
            args.limit_output = None

    if filtering:
        if not args.print_running:
            jobs = [job for job in jobs if not job.state.startswith('R')]
        if not args.print_queued:
            jobs = [job for job in jobs if not job.state.startswith('Q')]
        if not args.print_completed:
            jobs = [job for job in jobs if not job.state.startswith('C')]
        if not args.print_failed:
            jobs = [job for job in jobs if not (job.state.startswith('F') or job.state == '?')]

    if args.limit_output:
        if args.limit_output.isdigit():
            if int(args.limit_output) < 10000:
                jobs = jobs[:int(args.limit_output)]
            else:
                limit_check = TimeDelta(args.limit_output)
                jobs = limit_check.filter(jobs)
        else:
            try:  # filter by time
                limit_check = TimeDelta(args.limit_output)
                jobs = limit_check.filter(jobs)
            except TimeDeltaError:  # try filtering by name
                jobs = [job for job in jobs if job.name == args.limit_output]

    if args.output == 'jobid':
        jobids = [str(job.job_id) for job in jobs]
        print(' '.join(jobids))
    elif args.output == 'cmd':
        for job in jobs:
            print(job.cmd)
    else:
        data = []
        for job in jobs:
            data.append(
                [str(job.job_id), truncate_str(job.name, 20), job.state, job.exit_status, job.start, job.runtime,
                 job.memory, job.cmd])

        print_table(
            ['Job ID', 'Name', 'Status', 'Exit', 'Start Time', 'Elapsed/Total Time', 'Used Memory', 'Command'],
            data
        )

    if args.delete:
        jobs = list(jobs)
        if not len(jobs):
            print("\n\nNo jobs to delete.")
            return

        print("\n\nDANGER ZONE!")
        if confirm_delete('Are you sure you want to delete %s jobs listed above?' % len(jobs), str(len(jobs))):
            ids = [str(j.job_id) for j in jobs]
            proc = Popen('qdel %s' % ' '.join(ids), shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True,
                         universal_newlines=True)
            qdel, err = proc.communicate()
            if err:
                raise Exception("Can't run qdel: %s" % err)
            print("Deleted %d jobs." % len(ids))
        else:
            print("Wrong answer, not deleting anything.")

def archive(args):
    """Archive old finished jobs, save them in a gzipped file

    :param args: Arguments from argparse
    :type args: argparse.Namespace
    """
    timefilter = TimeDelta(args.age, newer=False)

    cluster = Cluster(jobs_qstat=True, jobs_log=True, jobs_pbs=True)
    jobs = cluster.jobs_list()

    jobs_to_archive = []

    for job in timefilter.filter(jobs):
        if job.qstat:
            # Do not delete running jobs!
            continue

        if job.pbs_output or job.pbs_log:
            jobs_to_archive.append(job)

    if not jobs_to_archive:
        # Bail, nothing to do here
        return

    # Delete files only when we know they are all safely zipped
    delete_list = []
    archived_job_ids = set()

    if not os.path.exists(PBS_ARCHIVE_PATH):
        os.mkdir(PBS_ARCHIVE_PATH)

    tar_file = '%s_%032x.tar.gz' % (datetime.now().strftime('%Y-%m-%d'), random.getrandbits(128))
    tar_path = os.path.join(PBS_ARCHIVE_PATH, tar_file)

    with TarFile.open(tar_path, 'w:gz') as tar:
        for job in jobs_to_archive:
            if job.pbs_output:
                tar.add(job.pbs_output, arcname=job.pbs_output.replace(HOME, '').lstrip('/'))
                delete_list.append(job.pbs_output)

            if job.pbs_log:
                archived_job_ids.add(job.job_id)

            print('Archived job %s' % job.job_id)

    with open(LOG_PATH + '_bkp', 'w') as log:
        for job in jobs[::-1]:
            if job.pbs_log and job.job_id not in archived_job_ids:
                log.write(job.pbs_log)

    for f in delete_list:
        os.remove(f)

    os.rename(LOG_PATH + '_bkp', LOG_PATH)

def subcommand_header(name):
    header = r"""
/-------------{pad}-\
| Subcommand: {name} |
\-------------{pad}-/""".format(pad='-' * len(name), name=name)
    return header

def main():
    if len(sys.argv) == 1:  # Python 2 argparse hack... don't judge me
        print_all_jobs()
        return

    # noinspection PyCompatibility
    import argparse
    timedelta_help = 'Must be either a date (YYYY-MM-DD), Job ID (numeric part) or a time delta (2w, 3h or 1d). ' \
                     'Time delta unit can be one of: h(hours), d(days) or w(weeks)'

    parser = argparse.ArgumentParser(
        description='Check job status. If no subcommand is specified it prints out a summary of all jobs.',
        add_help=False
    )
    parser.add_argument('-h', '--help', action='store_true', dest='help', default=False)

    command_parsers = parser.add_subparsers(title='Available subcommands',
                                            dest='command',
                                            description='For detailed subcommand help run: <subcommand> -h.')

    details_parser = command_parsers.add_parser('details', help='Show details of my jobs.')
    details_parser.add_argument('-r', '--print-running', action='store_true', help='Print running jobs.')
    details_parser.add_argument('-q', '--print-queued', action='store_true', help='Print queued jobs.')
    details_parser.add_argument('-c', '--print-completed', action='store_true', help='Print completed jobs.')
    details_parser.add_argument('-f', '--print-failed', action='store_true', help='Print failed jobs.')
    details_parser.add_argument('-d', '--delete', action='store_true', help='Delete listed jobs.')
    details_parser.add_argument('-l', '--limit-output', default='50',
                                help='Limit output to either: number of lines, Job ID, time delta or name. '
                                     'The default is 50 lines. '
                                     'Job ID can be in a form of range (i.e. 28327149-28327165) or a comma separated '
                                     'list of ids. Time delta unit can be one of: h(hours), d(days) or w(weeks).')
    details_parser.add_argument('-o', '--output', default='table',
                                help='Choose how to display output: table, jobid or cmd (default: table). '
                                     'TABLE dislays all available information about the job. '
                                     'JOBID displays space-separated job IDs which is useful for deleting jobs. '
                                     'CMD displays the commands which is useful for resubmitting jobs.')
    details_parser.set_defaults(func=details)

    archive_parser = command_parsers.add_parser('archive', help='Archive finished jobs.')
    archive_parser.add_argument('age', default='1w', nargs='?',
                                help='Archive finished jobs older than AGE (default: 1 week). ' + timedelta_help)
    archive_parser.set_defaults(func=archive)

    if len(sys.argv) == 2 and sys.argv[1] in ('-h', '--help'):
        # Another py2 hack, for a global help
        parser.print_help()

        for subp in (details_parser, archive_parser):
            print(subcommand_header(subp.prog))
            subp.print_help()

        parser.exit()

    args = parser.parse_args()

    args.func(args)

if __name__ == '__main__':
    main()


import numpy as np
import torch
from torch import nn
from torch.utils.data import DataLoader

from torch.autograd import Variable
from tqdm import tqdm

import matplotlib.pyplot as plt
# mpl.use('Agg')
import matplotlib

def showData(x, y, batchN, sen):
    plt.close()
    plt.plot(x.detach().cpu()[:, batchN, sen])
    plt.plot(y.detach().cpu()[:, batchN, sen])
    plt.show()
    # plt.savefig("mygraph.png")

def showData2(x, y, batchN, sen):
    plt.close()
    plt.plot(x.detach().cpu()[batchN, sen, :])
    plt.plot(y.detach().cpu()[batchN, sen, :])
    plt.show()

class SpeedNETUtilsClass:

    @staticmethod
    def showData(x, y, batchN, sen):
        plt.close()
        plt.plot(x.detach().cpu()[batchN, sen, :])
        plt.plot(y.detach().cpu()[batchN, sen, :])
        plt.show()

    @staticmethod
    def showDataTest(xi, y, batchN, sen):
        a=matplotlib.get_backend()

        x = np.linspace(0, 6.28, 100)

        plt.plot(x, x ** xi, label='square root')
        plt.plot(x, np.sin(x), label='sinc')

        plt.xlabel('x label')
        plt.ylabel('y label')

        plt.title("test plot")

        plt.legend()

        plt.show()

    def filter_step(self, SpeedNetTeacher, SpeedNetStudent, samples, labels, trainW, trainH, optimizer, loss1, train=True):

        samples = samples.transpose(0, 1)
        # labelsV = Variable(labels.type(SpeedNetStudent.dtype), requires_grad=True)
        weightV = Variable(trainW.type(SpeedNetStudent.dtype), requires_grad=True)
        heightV = Variable(trainH.type(SpeedNetStudent.dtype), requires_grad=True)

        if train:
            optimizer.zero_grad()
        # Forward + Backward + Optimize
        samplesV = Variable(samples.type(SpeedNetStudent.dtype), requires_grad=True)

        y, x_decod, latentT, kl_loss, aten = SpeedNetTeacher(samplesV, weightV, heightV)

        y, x_decod, latentS, kl_loss, aten = SpeedNetStudent(samplesV, weightV, heightV)

        loss = loss1(latentS, latentT)

        recon_loss = loss1(samplesV, x_decod)

        loss1res = self.lossMultip * loss

        if train:
            loss1res.backward()
            optimizer.step()

        return loss, recon_loss

    def studenTeacherReduction(self, SpeedNetTeacher, SpeedNetStudent, train_dataset, learning_rate, num_epochs):

        self.lossMultip=1
        # trainable_params = list(filter(
        #     lambda p: p.requires_grad, SpeedNetStudent.parameters()))
        # trainable_params = list(self.fc1.parameters())+list(self.fc2.parameters())+list(self.fc3.parameters())\
        #                       +list(self.fc3_2.parameters())+list(self.fc4.parameters())+list(self.ensamble2.parameters())\
        #                       +list(self.ensamble1_weight.parameters())+list(self.ensamble1_height.parameters())
        trainable_params = list(SpeedNetStudent.encoder.parameters()) + list(SpeedNetStudent.lmbd.parameters())

        optimizer = torch.optim.Adam(trainable_params, lr=learning_rate)

        train_data_loader = DataLoader(dataset=train_dataset, batch_size=SpeedNetStudent.batch_size, shuffle=True,
                                       drop_last=True)

        SpeedNetTeacher.to(SpeedNetTeacher.device)
        SpeedNetStudent.to(SpeedNetStudent.device)

        MAE = nn.L1Loss().to(SpeedNetStudent.device)
        MSE = nn.MSELoss().to(SpeedNetStudent.device)

        self.epoch_stop = 0

        for epoch in range(num_epochs):
            print('Epoch:', epoch)

            SpeedNetStudent.train()
            SpeedNetTeacher.train()

            steps = 0
            loss_x = 0
            loss_rec=0

            torch.cuda.empty_cache()
            # training
            for (samples, labels, weight, height) in tqdm(train_data_loader):
                steps += 1

                loss, loss_r = self.filter_step(SpeedNetTeacher, SpeedNetStudent, samples, labels, weight, height, optimizer, MSE)
                loss_x += loss.item()
                loss_rec += loss_r.item()

            print("Training loss:", loss_x / steps)
            print("Training loss rec:", loss_rec / steps)
            SpeedNetStudent.logger.log_value('{} MSE'.format("train"), loss_x / steps)
            SpeedNetStudent.logger.log_value('{} VRAE'.format("train"), loss_rec / steps)

    def analyzeErrorDistribution(self, SpeedNET, test_dataset, divide):
        test_data_loader = DataLoader(dataset=test_dataset, batch_size=SpeedNET.batch_size, shuffle=True, drop_last=True)

        maxSp = max(test_dataset.tensors[1].numpy().squeeze())
        stepSp = maxSp / (divide - 1)

        SpeedNET.to(SpeedNET.device)
        steps = 0

        data = np.empty(divide, dtype=np.object)
        for i in range(data.shape[0]):
            data[i] = []

        mae=[]

        for i, (samples, labels, weight, height) in enumerate(test_data_loader):
            with torch.no_grad():
                samples = samples.transpose(1, 2)
                labelsV = Variable(labels.type(SpeedNET.dtype), requires_grad=False)
                weightV = Variable(weight.type(SpeedNET.dtype), requires_grad=False)
                heightV = Variable(height.type(SpeedNET.dtype), requires_grad=False)
                samplesV = Variable(samples.type(SpeedNET.dtype), requires_grad=False)

                # heightV = Variable(torch.tensor(np.arange(16)*2 + 70).type(self.dtype), requires_grad=False).view(16,1)
                #weightV = Variable(torch.tensor(np.arange(16) * 2 + 60).type(SpeedNET.dtype), requires_grad=False).view(16, 1)

                y = SpeedNET(samplesV, weightV, heightV)

                err = labelsV - y

                indexes = (labels.numpy().squeeze() / stepSp)
                err = err.detach().cpu().numpy()
                mae.append(np.absolute(err))

                for i in range(SpeedNET.batch_size):
                    ind = int(indexes[i])
                    if ind < 0:
                        ind = 0
                    if ind > divide:
                        ind = divide
                    data[ind].append(err[i][0])
                steps += 1

        x = np.linspace(0, maxSp, divide)

        return data, x, np.mean(mae)


from ast import arg
from asyncio.log import logger
import imp
from traceback import print_tb
import torch
import torch.nn as nn
import torch.nn.functional as F
from parse import parse_args
from pprint import pformat
from thop import profile

import matplotlib.pyplot as plt
import random
from data_loader.build import build_loader
from utils import *
from models import MLP, GNN
import warnings
import numpy as np
import torch.optim as optim
from time import time
warnings.filterwarnings("ignore", category=np.VisibleDeprecationWarning)
warnings.filterwarnings("ignore", category=UserWarning)
from sklearn.metrics import recall_score,precision_score

args_config = parse_args()
# logger = getLogger(*args_config)
csvwriter = CSVWriter(args_config.csv_path)

yy_train_loss = []
yy_val_loss = []
yy_train_acc = []
yy_val_acc = []
yy_test_loss=[]
yy_test_acc = []

xx = []

def train(epoch, gnn, gnn_optimizer, train_loader):
    total, correct, train_acc = 0, 0, 0
    losses = AverageMeter()

    gnn.train()

    progressbar = tqdm(enumerate(train_loader), desc=f'epoch:[{epoch}]', total=len(train_loader))
    for batch_idx, batch in progressbar:
            gnn_optimizer.zero_grad()

            adj, mask, emb, labels = batch

            outputs = gnn(emb.cuda(), adj.cuda(), mask.cuda())
            #Calculate
            # flops, params = profile(gnn, inputs=(emb.cuda(), adj.cuda(), mask.cuda() ))
            # print('FLOPs = ' + str(flops/1000**3) + 'G')
            # print('Params = ' + str(params/1000**2) + 'M')
            bce_loss_batch = gnn.bce_loss(outputs, labels.float().cuda())
            l2_loss_batch = gnn._l2_loss()
            loss_batch = (l2_loss_batch + bce_loss_batch)
            losses.update(loss_batch.item())

            gnn_optimizer.zero_grad()
            loss_batch.backward()
            gnn_optimizer.step()

            preds = gnn.predict(outputs)
            preds = torch.argmax(preds, 1)

            correct += preds.eq(torch.argmax(labels.cuda(), 1)).sum().item()
            total += len(labels)
            train_acc = correct*1.0 / total

            progressbar.set_postfix({
            'batch_loss': "{:.4f}".format(loss_batch.item()),
            'avg_loss': "{:.4f}".format(losses.avg),
            'avg_acc': "{:.4f}".format(train_acc),
        })
    return losses.avg, train_acc

def test(epoch, gnn, test_loader):
    total, correct, acc = 0, 0, 0
    losses = AverageMeter()
    progressbar = tqdm(enumerate(test_loader), desc='test', total=len(test_loader))
    with torch.no_grad():
        for _,batch in progressbar:
            adj, mask, emb, labels = batch
            outputs = gnn(emb.cuda(), adj.cuda(), mask.cuda())
            bce_loss_batch = gnn.bce_loss(outputs, labels.float().cuda())
            l2_loss_batch = gnn._l2_loss()
            loss_batch = (l2_loss_batch + bce_loss_batch)
            losses.update(loss_batch.item())

            preds = gnn.predict(outputs)
            preds = torch.argmax(preds, 1)

            correct += preds.eq(torch.argmax(labels.cuda(), 1)).sum().item()
            total += len(labels)
            test_acc = correct*1.0 / total
            # print(labels,preds)
            recall=recall_score(torch.argmax(labels.cuda(), 1).cpu().numpy(),preds.detach().cpu().numpy(),zero_division=1)
            precision=precision_score(torch.argmax(labels.cuda(), 1).cpu().numpy(),preds.detach().cpu().numpy(),zero_division=1)

            progressbar.set_postfix({
            'batch_loss': "{:.4f}".format(loss_batch.item()),
            'avg_loss': "{:.4f}".format(losses.avg),
            'avg_acc': "{:.4f}".format(test_acc),
            'recall': "{:.4f}".format(recall),
            'precision': "{:.4f}".format(precision)
        })
    return losses.avg, test_acc ,recall,precision

def main():
    SEED = 77

    random.seed(SEED)
    torch.manual_seed(SEED)
    allrecall = []
    allprecision=[]

    """initialize args and dataset"""

    """set gpu id"""
    args_config.gpu = args_config.gpu and torch.cuda.is_available()
    device = torch.device("cuda" if args_config.gpu else "cpu")

    if args_config.gpu:
        print('Using GPU')
        torch.cuda.manual_seed(SEED)
        torch.cuda.set_device(args_config.gpu_id)

    train_adj, train_embed, train_y, val_adj, val_embed, val_y, test_adj, test_embed, test_y = load_data(args_config.dataset)

    # preprocessing
    train_adj, train_mask = preprocess_adj(train_adj)
    train_embed = preprocess_features(train_embed)
    val_adj, val_mask = preprocess_adj(val_adj)
    val_embed = preprocess_features(val_embed)
    test_adj, test_mask = preprocess_adj(test_adj)
    test_embed = preprocess_features(test_embed)
    print("Data Loaded")

    print("Build Data Loader")
    train_loader, test_loader, val_loader = build_loader(args_config=args_config, train_adj=train_adj, train_mask=train_mask, train_emb=train_embed, train_y=train_y,
                                             test_adj=test_adj, test_mask=test_mask, test_emb=test_embed, test_y=test_y,
                                             val_adj=val_adj, val_mask=val_mask, val_emb=val_embed, val_y=val_y)

    gnn = GNN(args_config.input_dim, train_y.shape[1]).cuda()
    gnn_optimizer = torch.optim.Adam(gnn.parameters(), args_config.learning_rate)
    lr_scheduler = optim.lr_scheduler.StepLR(gnn_optimizer, step_size=40, gamma=0.2)

    total_params = sum(p.numel() for p in gnn.parameters() if p.requires_grad)
    logger.info(f"model total trainable parameters: {total_params:,}")
    logger.info(f"current experiment parameters are:")
    logger.info(pformat(args_config)+"\n")
    best_acc = 0.0
    best_acc1 = 0.0
    best_epoch = 0
    brep=0
    logger.info('==>Start training...')

    for epoch in range(0, args_config.epochs):
        xx.append(epoch)
        lr_list = [param_groups['lr'] for param_groups in gnn_optimizer.param_groups]
        logger.info(f"current LR: {lr_list}")

        train_loss, train_acc = train(epoch, gnn, gnn_optimizer, train_loader)
        val_loss, val_acc ,_,_= test(epoch, gnn, val_loader)
        test_loss, test_acc,test_rec,test_pre = test(epoch, gnn, test_loader)

        lr_scheduler.step()
        allrecall.append(test_rec)
        allprecision.append(test_pre)
        kwargs = {'epoch':epoch,'train_loss': train_loss, 'train_acc': train_acc, 'test_loss':test_loss, 'test_acc':test_acc}

        is_best = test_acc > best_acc
        if is_best:
            best_acc = test_acc
            best_epoch = epoch

        logger.info(f"Epoch: {epoch} - train_loss: {train_loss:.4f} - train_acc: {train_acc:.4f} - test_loss:{test_loss:.4f} - test_acc: {val_acc:.4f}, Best acc is {best_acc:.4f} achieved at epoch {best_epoch}\n")
        csvwriter.write(**kwargs)
        if val_acc > best_acc1:
            best_acc1 = val_acc
            es = 0
            torch.save(gnn.state_dict(), 'model_weight.pt')
        else:
            es += 1
            print("Counter {} of 20".format(es))

            if es > args_config.early_stopping:
                print("Early stopping with best_acc: ", best_acc, "and val_acc for this epoch: ", val_acc, "...")
                brep=epoch
                break
        yy_train_loss.append(train_loss)
        yy_train_acc.append(train_acc)

        yy_val_loss.append(val_loss)
        yy_val_acc.append(val_acc)

        yy_test_loss.append(test_loss)
        yy_test_acc.append(test_acc)

    logger.info("==> Training finished!!!")
    a=0
    b=0
    for i in range(len(allrecall)):
        a = a + allrecall[i]
        b = b + allprecision[i]
    a = a / len(allrecall)
    b = b / len(allrecall)
    # print(allrecall)
    print('precision is {:.4f}'.format(b))
    print('recall is {:.4f}'.format(a))
    print('F-SCORE is {:.4f}'.format((2*a*b)/(a+b)))
    if len(allrecall)!=args_config.epochs:
        xx.pop()
    plt.plot(xx, yy_train_loss, "r", label="train_loss")

    plt.legend()
    plt.savefig("loss.png")
    plt.close()
    plt.plot(xx, yy_train_acc, "y", label="train_acc")
    plt.plot(xx, yy_val_acc, "g", label="valid_acc")
    plt.plot(xx, yy_test_acc, "b", label="test_acc")
    plt.legend()
    plt.savefig("acc.png")
    plt.close()

if __name__ == '__main__':
    main()


# -*- coding: utf-8 -*-
# @Time    : 2019/1/3 15:43
# @Author  : zgh
# @Email   : 849080458@qq.com
# @File    : auto_oracle_insert.py
# @Software: PyCharm

import cx_Oracle

# 注：设置环境编码方式，可解决读取数据库乱码问题
import os
os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'

# scott是数据用户名，tiger是登录密码（默认用户名和密码）
connection = cx_Oracle.connect("hg", "123456", '122.112.248.182:1521/CITYDO')

# 操作游标
cursor = connection.cursor()

def JGHG_insert_data(table):
    sql = auto_insert(table)
    #print(sql)

    #批量生成数据进行插入
    for i in range(50000,60000):
        ii=1000+i

        #插入数据格式（修改内容）
        table_data =  [('88T646' + str(ii), '987465004' + str(ii), '648665004' + str(i), 'DKFH0992' + str(ii),'DKeeeFH0992' + str(ii), '抵押','313340' + str(ii), 20180506, 20180506, '解除' ,  '科目1' + str(i), 20180504)]

        cursor.prepare(sql)#sql语句，需要与数据库字段相对应，value值长度与字段对应
        cursor.execute(None,table_data[0])#插入数据集
        print('执行sql:', sql)
        print('插入内容：', table_data[0])

        # 切记一定要执行
        cursor.execute('commit')

    # 关闭连接，释放资源
    cursor.close()
    connection.close()

def auto_insert(table):
    #执行SQL语句
    curs = cursor.execute("select column_name from all_tab_columns where  TABLE_NAME = '" + table + "'order by column_id")
    #查看数据库数据
    data = curs.fetchall()
    data_1=[]
    test=[]
    for i in range(len(data)):
        data_1.append(data[i][0])
        print(data[i][0])
        test.append(':'+str(i+1))#生成value数列

    table_sql="INSERT INTO "+ table + "("+ ','.join(data_1) + ")" + " VALUES " + "("+ ','.join(test) + ")"

    # data_2=[i for i in reversed(data_1)]#反序排列
    # print(','.join(data_1))  # 转为元组
    # print(','.join(test))#转为元组
    # print(data)
    # print(len(data))
    return table_sql

JGHG_insert_data('YJPT_DBGX')


# -*- coding: utf-8 -*-
from django.conf.urls import patterns, url, include
from Project.SecureWitness import views

urlpatterns = patterns('',
    url(r'^$', views.index, name='index'),
    url(r'^about/$', views.about, name='about'),
    url(r'^reports/([0-9]*)\/*$', views.reports, name='reports'),
    #url(r'^list/$', views.list, name='list'),                               #need to get rid of later
    url(r'^add_report/$', views.add_report, name='add_report'),
    url(r'^add_category/$', views.add_category, name='add_category'),
    url(r'^register/$', views.register, name='register'),
    url(r'^category/(?P<category_name_url>\w+)/$', views.category, name='category'),
    url(r'^login/$', views.user_login, name='login'),
    url(r'^restricted/$', views.restricted, name='restricted'),
    url(r'^logout/$', views.user_logout, name='logout'),
    url(r'^auth/$',views.auth, name='auth'),
    url(r'^messages/', include('postman.urls', namespace='postman', app_name='postman')),
    url(r'^search/', views.search, name='search'),
    url(r'^addFolder/$', views.add_folder, name='addFolder'),
    url(r'^disp_report/([0-9]+)/$', views.disp_report, name="disp_report"),
    url(r'^edit_report/([0-9]+)/$', views.edit_report, name="edit_report"),
    url(r'^groups/$', views.groups, name='groups'),
    url(r'^viewFolder/([a-zA-Z0-9" "]*)/$', views.view_folder, name="view_folder"),
    #url(r'^selectable/', include('selectable.urls')),
)


from __future__ import annotations

from typing import List

import numpy as np

from core.predictor import Predictor, PredictionResult
from utilities.interpolate import LinearlyInterpolatedFunction

class LinearRegressionPredictor(Predictor):

    def type(self) -> str:
        return "Constant Predictor"

    def predict(self, times: List[float], old_queues: List[np.ndarray]) -> PredictionResult:
        raise NotImplementedError()

    def predict_from_fcts(self, old_queues: List[LinearlyInterpolatedFunction], phi: float) -> PredictionResult:
        queues_minus_0 = np.array([max(0., queue(phi)) for queue in old_queues])
        queues_minus_1 = np.array([max(0., queue(phi - 1)) for queue in old_queues])
        queues_minus_2 = np.array([max(0., queue(phi - 2)) for queue in old_queues])
        queues_minus_3 = np.array([max(0., queue(phi - 3)) for queue in old_queues])
        queues_minus_4 = np.array([max(0., queue(phi - 4)) for queue in old_queues])

        m = len(old_queues)
        zeros = np.zeros(m)
        mask = (queues_minus_0 == 0) & (queues_minus_1 == 0) & (queues_minus_2 == 0) & (queues_minus_3 == 0) \
               & (queues_minus_4 == 0)
        result = PredictionResult(
            [phi, phi + 1, phi + 2, phi + 3, phi + 4, phi + 5, phi + 6, phi + 7, phi + 8, phi + 9, phi + 10],
            [
                np.where(mask, zeros, queues_minus_0),
                np.where(mask, zeros, queues_minus_0 + 2.68),
                np.where(mask, zeros, 1.01 * queues_minus_0 + 5.36),
                np.where(mask, zeros, 1.01 * queues_minus_0 + 8.47),
                np.where(mask, zeros, 1.02 * queues_minus_0 + 11.67),
                np.where(mask, zeros, 1.02 * queues_minus_4 + 14.67),
                np.where(mask, zeros, 1.02 * queues_minus_3 + 14.67),
                np.where(mask, zeros, 1.02 * queues_minus_2 + 14.67),
                np.where(mask, zeros, 1.02 * queues_minus_1 + 14.67),
                np.where(mask, zeros, 1.02 * queues_minus_0 + 14.67),
                np.where(mask, zeros, 1.02 * queues_minus_0 + 14.67)
            ]
        )

        return result


from flask import Flask, render_template
from predict import summarize
from time import time
from flask import jsonify, request
import os

app = Flask(__name__)

# @app.route('/')
# def home():
#     return render_template('home.html')

@app.route('/', methods=['GET', 'POST'])
def api_exec():
    if request.method == 'POST':
        text = request.values.get('text')
    else:
        text = request.args.get('text')
    if text == None:
        print('Summarizing Sample Description')
        text = "This app is developed by Nam and ZZ for NUS HackNRoll 2020. We are trying to build the most awesome app."

    response = {'status': 'ok'}
    try:
        start_time = time()
        summary = summarize(text)
        infer_time = time() - start_time
    except Exception as e:
        print("Error when predicting", e)
        response = {"status": "fail", "message": "Error when summarizing: {}".format(str(e))}

    if response["status"] == "ok":
        response.update({
            "text": text,
            "summary": summary,
            "infer_time": infer_time
        })

    return jsonify(response)

if __name__ == '__main__':
    app.run(debug=True)


from sqlalchemy.orm import Session
from . import models,schemas
from datetime import  datetime as _dt

def add_in_stock(db:Session, stock_in: schemas.StockIn):

    new_stock = models.Stock(
        currency = stock_in.currency,
        date = _dt.strptime(stock_in.date,'%Y.%m.%d_%H:%M'),
        frame = stock_in.frame,
        open = stock_in.open,
        high = stock_in.high,
        low = stock_in.low,
        close = stock_in.close,
    )
    db.add(new_stock)
    db.commit()
    db.refresh(new_stock)
    return new_stock


import pygame
from Data.settings import HEIGHT
ground = pygame.image.load("Assets/ground.png")

class platforms(pygame.sprite.Sprite):
    def __init__(self, pos, width):
        super().__init__()
        self.image = pygame.transform.scale(ground, (width, 10)).convert()
        self.rect = self.image.get_rect(center = pos)

    def update(self, scroll):
        self.rect.y += scroll
        if self.rect.top > HEIGHT:
            self.kill()