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

import os

HERE = os.path.dirname(os.path.abspath(__file__))

# We setup the cache for Chameleon templates
template_cache = os.path.join(HERE, 'cache')
if not os.path.exists(template_cache):
    os.makedirs(template_cache)
os.environ["CHAMELEON_CACHE"] = template_cache

# Bootstrapping the Crom registry
from crom import monkey, implicit
monkey.incompat()
implicit.initialize()

# Read the ZCML
# This is not a mandatory stage.
# Actually, what the ZCML loading does is grok the packages
# This can be done manually, using `crom.configure`
from cromlech.configuration.utils import load_zcml
load_zcml(os.path.join(HERE, 'app.zcml'))

# Load translation
# This is needed only if we want internationalization
from cromlech.i18n import load_translations_directories
load_translations_directories()

# Adding the event dispatcher
# Use only if you have event handlers or plan to have some.
from cromlech.events import setup_dispatcher
setup_dispatcher()

def populate_db(db):
    """We create two leaves here.. We get the DB connection object.
    We need to open and to close it. It doesn't need to return anything.
    Make sure to use a transaction manager to have it correctly persisted.
    """
    import transaction
    from cromdemo.models import RootCategory, Category, Item
    from cromlech.zodb import Connection

    with Connection(db, transaction_manager=transaction.manager) as conn:
        conn = db.open()
        root = conn.root()
        if not hasattr(root,'appRoot'):
            appRoot=RootCategory()
            appRoot.__name__='root'
            root.appRoot=appRoot
            category = Category(title='Tree Leaves',
                        body='Tree Leaves go in this category')
            appRoot['Leaves'] =category
            category['greenLeaf'] = Item(title='Green Leaf',
                                        body='A summer leaf')
            category['redLeaf'] = Item(title='Red leaf',
                                      body='A fall leaf')

            category = Category(title='Cars',
                        body='Cars go in this category')
            appRoot['Cars'] =category
            category['Ford'] = Item(title='Ford Escort',
                                        body='A boring Ford')
            category['Ferrari'] = Item(title='Ferrari',
                                      body='An Exciting Ferari')
            transaction.manager.commit()

# We read the zodb conf and initialize it
from cromlech.zodb import init_db
with open('zodb.conf', 'r') as fd:
        zodb_config = fd.read()
        db = init_db(zodb_config)
        populate_db(db)

# Getting the crypto key and creating the JWT service
# We chose the JWT signed cookie for the demo
# `cromlech.sessions` proposed different backends.
# Or you can use the WSGI session middleware of your choice.
from cromlech.sessions.jwt import key_from_file
from cromlech.sessions.jwt import JWTCookieSession

key = key_from_file(os.path.join(HERE, 'jwt.key'))
session_wrapper = JWTCookieSession(key, 300)

# Create the application, including the middlewares.
from cromdemo.wsgi import demo_application
from cromlech.zodb.middleware import ZODBApp
from fanstatic import Fanstatic
zodb_application = ZODBApp(demo_application, db, key="zodb.connection")
fanstatic_app = Fanstatic(zodb_application)
application = session_wrapper(fanstatic_app)


import random
# Ejercicio 8 #
'''
Definir una estructura de datos con listas que permita guardar
la temperatura mínima y máxima de 5 días.
---
Realiza un programa que de la siguiente información:
     - La temperatura media de cada día
     - Los días con menos temperatura
     - Que permita leer una temperatura por teclado y muestre
       los días cuya temperatura máxima coincida con ella,
       en caso contrario mostrar un mensaje diciendo
       que no existe ningún día

'''
# Esto es una función que genera aleatoriamente una de lista de listas con temperaturas minimas y maximas
def listaTemperatura(n):
    lst = []
    for i in range(0,n):
        min_ = random.randint(-30, 10)
        max_ = random.randint(10, 40)
        lst.append([min_, max_])
    return lst

# Función que calcula la temperatura media de cada día
def temperaturaMedia(lista):
    lst_media_temp= []
    for i in lista:
        media = (i[0] + i[1]) /2
        lst_media_temp.append(media)

    return lst_media_temp

# Función que calcula los días con menos temperatura
def menosTemperatura(lista):
    lista_minimos= []
    temperatura_minima = lista[0][0]
    for i in lista:
        if(i[0] <= temperatura_minima):
            temperatura_minima = i[0]
    print(temperatura_minima)

    for i in range(0,len(lista)):
        if(temperatura_minima == lista[i][0]):

            lista_minimos.append(i+1)

    return lista_minimos
''' - Que permita leer una temperatura por teclado
y muestre los días cuya temperatura máxima coincida con ella,
en caso contrario mostrar un mensaje diciendo que no existe
ningún día '''
def buscarTemperaturaMaxima(lista1):
    temp = float(input("Dime la temperatura:"))

    lista_dias_max = []
    lista_max = []

    for i in lista1:
        #Se agregan todas las temperaturas máximas a una lista vacia
        lista_max.append(i[1])

    for i in range(0, len(lista_max)):
        if(lista_max[i] == temp):
            lista_dias_max.append(i+1)
            return lista_dias_max
    else:
        print("No existe ningun día con esa temperatura")

lista1= listaTemperatura(5)
lista2= listaTemperatura(10)
lista3= listaTemperatura(0)


import pathlib
import os
from setuptools import setup, find_packages

UPSTREAM_URLLIB3_FLAG = "--with-upstream-urllib3"

def get_requirements(raw=False):
    """Build the requirements list for this project"""
    requirements_list = []

    with open("requirements.txt") as reqs:
        for install in reqs:
            if install.startswith("# only telegram.ext:"):
                if raw:
                    break
                continue
            requirements_list.append(install.strip())

    return requirements_list

def get_packages_requirements(raw=False):
    """Build the package & requirements list for this project"""
    reqs = get_requirements(raw=raw)
    exclude = ["tests*"]
    packs = find_packages(exclude=exclude)
    return packs, reqs

packages, requirements = get_packages_requirements()
# The directory containing this file
HERE = pathlib.Path(__file__).parent

# The text of the README file
README = (HERE / "README.md").read_text()

def read(rel_path: str) -> str:
    here = os.path.abspath(os.path.dirname(__file__))
    # intentionally *not* adding an encoding option to open, See:
    #   https://github.com/pypa/virtualenv/issues/201#issuecomment-3145690
    with open(os.path.join(here, rel_path)) as fp:
        return fp.read()

def get_version(rel_path):
    for line in read(rel_path).splitlines():
        if line.startswith("__version__"):
            delim = '"' if '"' in line else "'"
            return line.split(delim)[1]
    else:
        raise RuntimeError("Unable to find version string.")

# This call to setup() does all the work
# circle bracket and format in the download_url parameter to resolve linting issue
# of line too long
setup(
    name="polly-python",
    version=get_version("polly/__init__.py"),
    description="Polly SDK",
    long_description=README,
    long_description_content_type="text/markdown",
    packages=packages,
    include_package_data=True,
    setup_requires=["wheel"],
    install_requires=requirements,
    url="https://github.com/ElucidataInc/polly-python",
    download_url=(
        "https://elucidatainc.github.io/PublicAssets/builds/polly-python/"
        "polly_python-{a}-none-any.whl".format(a=get_version("polly/__init__.py"))
    ),
)


def set_crease_interactive(self):
    """
    Set the crease for the edges which are in the unique_edges array by picking vertices forming an edge in an
    interactive PyVista widget.
    When called the first time creates np.array with zeros of length unique_edges.

    Returns
    --------
        edges_crease: (n,1) float
            np.array with creases for corresponding edge in the unique_edges array
    """

    crease_arr = visualize.set_creases_visualize(self)
    self.data['creases'] = crease_arr
    self.set_crease()
    return self.data['creases']

def recalculate_face_normals(self):
        """
        Trying to recalibrate face normals by sending out rays. If ray hits a points on another face, the normal is
        pointing inside. The face normal is flagged to be flipped.

        Parameters
        --------------
        self : PySubdiv mesh object
            mesh on which the face normals should be calculated
        Returns
        -------
        face_normals : (n,3)
        """

        # array to store the flag state of the normal which will be multiplied with the face normal array;
        # 1 stay -1 flip
        normals_to_flip = np.zeros(len(self.faces))
        # loop over each face and cast a ray for each face from the centroids position in normal direction
        for face_idx in range(len(self.faces)):
            # return of the function, often also start of ray cast is registered as hit
            points = calculation.ray_cast(self.face_centroids[face_idx], self.face_normals[face_idx], self.model())[0]
            # if two or more points are hit flag to flip normal; probably first hit is start point second hit should be
            # on the opposite face
            if len(points) >= 2:
                normals_to_flip[face_idx] = -1
            else:
                # if zero or one points is reverse start and end point of the ray
                points_reversed = calculation.ray_cast(self.face_centroids[face_idx], self.face_normals[face_idx],
                                                       self.model(), back_cast=True)[0]
                # if no point is hit on the first ray cast, face normal is probably oriented outwards, flag normal as
                # correct
                if len(points) == 0 or len(points_reversed) == 0:
                    normals_to_flip[face_idx] = 1
                else:
                    # if length of point hit array is one we will check the hit point against the startpoint of the ray
                    points_tuple = tuple(points[0])
                    points_reversed_tuple = tuple(points_reversed[0])
                    face_centroid_tuple = tuple(self.face_centroids[face_idx])
                    boolean_mask = []
                    # loop over the x, y, z coordinate of the hit point and check against the start point
                    # if coordinates are equal continue otherwise flag normals to be flipped
                    for i, coordinate in enumerate(points_tuple):
                        if np.allclose(coordinate, face_centroid_tuple[i]):
                            boolean_mask.append(True)
                        else:
                            boolean_mask.append(False)
                    if all(boolean_mask):
                        # start is equal to hit -> check if start is equal to hit of reverse ray cast if not equal
                        # flag to flip the normal
                        if {points_tuple} != {points_reversed_tuple}:
                            normals_to_flip[face_idx] = -1
                        else:
                            # first hit is equal to reverse hit-> face normal probably pointing outwards
                            # no flip necessary
                            normals_to_flip[face_idx] = 1
                    else:
                        # start is not equal to hit -> flip the normal
                        normals_to_flip[face_idx] = -1
        self.face_normals = self.face_normals * normals_to_flip.reshape((-1, 1))
        self.define_vertex_normals()
        self.data['face_normals'] = self.face_normals
        return self.face_normals


import sys
sys.path.append("../common/tests")
from test_utils import *
import test_common
sys.path.insert(0, '../../../../build/debug/config/schema-transformer/')

from vnc_api.vnc_api import *
import uuid

class STTestCase(test_common.TestCase):
    def setUp(self):
        super(STTestCase, self).setUp()
        self._svc_mon_greenlet = gevent.spawn(test_common.launch_svc_monitor,
            self._api_server_ip, self._api_server_port)
        self._st_greenlet = gevent.spawn(test_common.launch_schema_transformer,
            self._api_server_ip, self._api_server_port)

    def tearDown(self):
        self._svc_mon_greenlet.kill()
        self._st_greenlet.kill()
        super(STTestCase, self).tearDown()

    def create_virtual_network(self, vn_name, vn_subnet):
        vn_obj = VirtualNetwork(name=vn_name)
        ipam_fq_name = [
            'default-domain', 'default-project', 'default-network-ipam']
        ipam_obj = self._vnc_lib.network_ipam_read(fq_name=ipam_fq_name)
        cidr = vn_subnet.split('/')
        pfx = cidr[0]
        pfx_len = int(cidr[1])
        subnet_info = IpamSubnetType(subnet=SubnetType(pfx, pfx_len))
        subnet_data = VnSubnetsType([subnet_info])
        vn_obj.add_network_ipam(ipam_obj, subnet_data)
        self._vnc_lib.virtual_network_create(vn_obj)
        vn_obj.clear_pending_updates()
        return vn_obj
    # end create_virtual_network

    def create_network_policy(self, vn1, vn2, service_list=None, service_mode=None):
        addr1 = AddressType(virtual_network=vn1.get_fq_name_str())
        addr2 = AddressType(virtual_network=vn2.get_fq_name_str())
        port = PortType(-1, 0)
        action = "pass"
        action_list = ActionListType(simple_action=action)
        if service_list:
            service_name_list = []
            for service in service_list:
                sti = [ServiceTemplateInterfaceType(
                    'left'), ServiceTemplateInterfaceType('right')]
                st_prop = ServiceTemplateType(
                    image_name='junk',
                    service_mode=service_mode, interface_type=sti)
                service_template = ServiceTemplate(
                    name=service + 'template',
                    service_template_properties=st_prop)
                self._vnc_lib.service_template_create(service_template)
                scale_out = ServiceScaleOutType()
                if service_mode == 'in-network':
                    si_props = ServiceInstanceType(
                        auto_policy=True, left_virtual_network=vn1.get_fq_name_str(),
                        right_virtual_network=vn2.get_fq_name_str(), scale_out=scale_out)
                else:
                    si_props = ServiceInstanceType(scale_out=scale_out)
                service_instance = ServiceInstance(
                    name=service, service_instance_properties=si_props)
                self._vnc_lib.service_instance_create(service_instance)
                service_instance.add_service_template(service_template)
                self._vnc_lib.service_instance_update(service_instance)
                service_name_list.append(service_instance.get_fq_name_str())

            action_list = ActionListType(apply_service=service_name_list)
            action = None
        prule = PolicyRuleType(direction="<>", protocol="any",
                               src_addresses=[addr1], dst_addresses=[addr2],
                               src_ports=[port], dst_ports=[port],
                               action_list=action_list)
        pentry = PolicyEntriesType([prule])
        np = NetworkPolicy(str(uuid.uuid4()), network_policy_entries=pentry)
        if service_mode == 'in-network':
            return np
        self._vnc_lib.network_policy_create(np)
        return np
    # end create_network_policy

    def delete_network_policy(self, policy, auto_policy=False):
        action_list = policy.network_policy_entries.policy_rule[0].action_list
        if action_list:
            for service in action_list.apply_service or []:
                si = self._vnc_lib.service_instance_read(fq_name_str=service)
                st_ref = si.get_service_template_refs()
                st = self._vnc_lib.service_template_read(id=st_ref[0]['uuid'])
                self._vnc_lib.service_instance_delete(id=si.uuid)
                self._vnc_lib.service_template_delete(id=st.uuid)
            # end for service
        # if action_list
        if not auto_policy:
            self._vnc_lib.network_policy_delete(id=policy.uuid)
    # end delete_network_policy(policy)


import torch
import torchreid
import tensorrt as trt

# Load pre-trained OSNet model with x0.25 width multiplier
model_name = 'osnet_x0_25'
model = torchreid.models.build_model(
    name=model_name,
    num_classes=1000,
    pretrained=True
)

# Create example input tensor
data_shape = (3, 256, 128)
input_tensor = torch.randn(1, *data_shape)

# Build TensorRT engine
engine_file_path = f'{model_name}.engine'
with trt.Logger(trt.Logger.INFO) as logger:
    with trt.Builder(logger) as builder, builder.create_network() as network:
        # Configure builder
        config = builder.create_builder_config()
        config.max_workspace_size = 1 << 30  # 1 GB
        builder.max_batch_size = 1

        # Create input tensor
        input_tensor_trt = network.add_input(
            name='input',
            dtype=trt.float32,
            shape=(3, 256, 128)
        )

        # Convert PyTorch model to TensorRT engine
        model_trt = torchreid.engine.build_engine(
            model=model,
            data_shape=data_shape,
            fp16_mode=True,
            engine_file_path=engine_file_path,
            builder=builder,
            config=config
        )

        # Create output tensor
        output_tensor_trt = model_trt(input_tensor_trt)

        # Add output tensor to network
        network.mark_output(
            name='output',
            tensor=output_tensor_trt
        )

        # Build engine
        engine = builder.build_cuda_engine(network)

        # Save engine
        with open(engine_file_path, 'wb') as f:
            f.write(engine.serialize())


import os
import pandas as pd
import bifacial_radiance

os.chdir('C:/Users/ferdl/Documents/bifacial_radiance/TFG_Final/Seguimiento/Anual/Sudafrica_Diciembre')
path = os.getcwd()
print("Cambio de directorio de trabajo a:", path)

resultfolder = os.path.join(path, 'results')
writefiletitle = "Mismatch_Results_Diciembre_Estandar.csv"

portraitorlandscape='portrait'
bififactor=0
numcells= 96
downsamplingmethod = 'byCenter'
bifacial_radiance.mismatch.analysisIrradianceandPowerMismatch(testfolder=resultfolder,
                                                      writefiletitle=writefiletitle,
                                              portraitorlandscape=portraitorlandscape,
                                                              bififactor=bififactor,
                                                              numcells=numcells)
read_file = pd.read_csv(r'Mismatch_Results_Diciembre_Estandar.csv')
read_file.to_excel('Mismatch_Results_Diciembre_Estandar.xlsx')


from copy import deepcopy
import logging
from typing import Any, Dict, List, Optional, Type

from braces.views import (
    FormInvalidMessageMixin,
    FormValidMessageMixin,
    LoginRequiredMixin,
    MessageMixin
)
from django.forms import BaseModelForm, Form
from django.http.response import HttpResponse
from django.shortcuts import redirect
from django.views.generic import (
    CreateView as DjangoCreateView,
    TemplateView,
    UpdateView as DjangoUpdateView,
    View
)
from django.views.generic.edit import (
    BaseDeleteView,
    BaseUpdateView,
)

from ..forms import AbstractRelatedFieldForm, ToggleableManyToManyFieldForm
from ..models import (
    ViewSetMixin,
    model_logger_name,
    model_name,
    model_verbose_name,
    model_verbose_name_plural,
)
from ..views import WidgetInitKwargsMixin, TableActionFormView
from ..widgets import (
    BaseDataTable,
    Block,
    BreadcrumbBlock,
    CardWidget,
    CrispyFormWidget,
    LookupModelTable,
    NavbarMixin,
    RowDeleteButton,
    RowEditButton,
    TwoColumnLayout,
    Widget,
    WidgetListLayoutHeader
)

from .mixins import StandardWidgetMixin
from .permission import PermissionRequiredMixin

logger = logging.getLogger(__name__)

# --------------------------------------------
# Abastract Widgets
# --------------------------------------------

class AbstractFormPageLayout(Block):
    """
    This is a abstact class for making whole page layouts for a form page:
    creating or updating a model.

    It defines a page title, a page subtitle and a block to contain our
    main page content (typically just our model form).

    Subclass this and override :py:meth:`get_form` to render your main
    page content.

    Note:
        This class will try to supply a reasonable :py:attr:`title` and
        :py:attr:`subtitle`, by inferring reasonable values based on what base
        classes are in the ``view`` class hierarchy.  So you only need to set
        those if you don't get a title/subtitle that you like.

    Args:
        view: the view instance that will render this layout

    Keyword Args:
        title: use this as our page title
        subitle: Use this as our page subtitle.  This will appear directly
            below the page title.  Typically set this to a string naming the
            object we're updating
    """

    block: str = 'form-layout'

    #: Use this as our page ittle
    title: Optional[str] = None
    #: Use this as our page subtitle.  This will appear directly below
    #: the page title.  Typically set this to a string naming the object
    #: we're updating
    subtitle: Optional[str] = None

    def __init__(
        self,
        view: "GenericViewMixin",
        title: str = None,
        subtitle: str = None,
        **kwargs
    ):
        self.view = view
        self.title = title if title else self.title
        self.subtitle = subtitle if subtitle else self.subtitle
        if not self.title:
            if isinstance(self.view, DjangoCreateView):
                self.title = f'Create {self.view.model_verbose_name}'
            elif isinstance(self.view, DjangoUpdateView):
                self.title = f'Update {self.view.model_verbose_name}'
            else:
                self.title = f'Manage {self.view.model_verbose_name}'
        if not self.subtitle and view.object is not None:
            self.subtitle = str(view.object)
        super().__init__(**kwargs)
        self.add_block(self.get_title())
        if self.subtitle:
            self.add_block(self.get_subtitle())
        self.add_block(self.get_form())

    def get_title(self) -> Block:
        title = Block(
            self.title,
            name=f'{self.block}__title',
            tag='h1',
        )
        if not self.subtitle:
            title.add_class('mb-5')
        return title

    def get_subtitle(self) -> Optional[Block]:
        return Block(
            self.subtitle,
            name=f'{self.block}__subtitle',
            css_class='text-muted fs-6 text-uppercase mb-5'
        )

    def get_form(self) -> Block:
        raise NotImplementedError

# --------------------------------------------
# Widgets
# --------------------------------------------

class IndexTableWidget(Block):
    """
    This is the block that we use to render the listing table on the
    :py:class:`IndexView`.  It adds a header above the table.
    """

    def __init__(
        self,
        instance: ViewSetMixin,
        table: BaseDataTable,
        show_create_button: bool = True,
        **kwargs
    ):
        self.instance = instance
        self.show_create_button = show_create_button
        super().__init__(**kwargs)
        self.add_block(self.get_title())
        self.add_block(CardWidget(widget=table))

    def get_title(self) -> WidgetListLayoutHeader:
        header = WidgetListLayoutHeader(
            header_text=self.instance._meta.verbose_name_plural.capitalize(),
            badge_text=self.instance.objects.count(),
        )
        if self.show_create_button:
            header.add_link_button(
                text=f"New {self.instance._meta.verbose_name.capitalize()}",
                color="primary",
                url=self.instance.get_create_url()
            )
        return header

class FormPageLayout(AbstractFormPageLayout):

    left_column_width: int = 9

    def get_form(self) -> Block:
        layout = TwoColumnLayout(left_column_width=9)
        form_widget = CrispyFormWidget(
            form=self.view.get_form(),
            css_class='shadow bg-white p-4'
        )
        layout.add_to_left(form_widget)
        return layout

# --------------------------------------------
# View mixins
# --------------------------------------------

class GenericViewMixin:
    """
    This class based view mixin adds some methods and attributes that our
    other generic views use.
    """

    #: Set this to the model permissions the user must have in order
    #: to be authorized for this view:
    required_model_permissions: List[str] = []
    #: Set this to the logger of your choice
    logger: Any = logger
    #: Set this to your :py:class:`wildewidgets.widgets.navigation.BreadcrumbBlock`
    #: to manage breadcrumbs automatically.
    breadcrumbs: Optional[BreadcrumbBlock] = None

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if self.breadcrumbs is not None:
            self.breadcrumbs = deepcopy(self.breadcrumbs)

    @property
    def model_name(self) -> str:
        """
        Return our model name.
        """
        if hasattr(self.model, 'model_name'):
            return self.model.model_name()
        return model_name(self.model)

    @property
    def model_logger_name(self) -> str:
        """
        Return a string we can use to identify this model in a log message.
        """
        if hasattr(self.model, 'model_logger_name'):
            return self.model.model_logger_name()
        return model_logger_name(self.model)

    @property
    def model_verbose_name(self) -> str:
        """
        Return a string we can use to identify this model in a log message.
        """
        if hasattr(self.model, 'model_verbose_name'):
            return self.model.model_verbose_name()
        return model_verbose_name(self.model)

    @property
    def model_verbose_name_plural(self) -> str:
        if hasattr(self.model, 'model_verbose_name_plural'):
            return self.model.model_verbose_name_plural()
        return model_verbose_name_plural(self.model)

    def get_client_ip(self) -> str:
        """
        Return our user's IP address.  This will either be the leftmost
        IP address in our ``X-Forwarded-For`` header, or the ``REMOTE_ADDR``
        header.

        Returns:
            Our user's IP address
        """
        x_forwarded_for = self.request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            return x_forwarded_for.split(',')[0]
        return self.request.META.get('REMOTE_ADDR')

    @property
    def logging_extra(self) -> str:
        """
        Build some extra stuff to append to our logging statements:

        * add the user's remote_ip
        * add the user's username
        * add the pk of the object, if any

        Returns:
            A string to append to our log message
        """
        data = {}
        data['remote_ip'] = self.get_client_ip()
        data['username'] = self.request.user.username
        if hasattr(self, 'object'):
            data['pk'] = self.object.pk
        return ' '.join([f'{key}={value}' for key, value in data.items()])

    def get_menu_item(self) -> Optional[str]:
        """
        Return the name of the main menu item to set active, which is the
        the appropriately capitalized ``verbose_name_plural`` for our model.

        Returns:
            The name of the main menu item to set active.
        """
        return self.model_verbose_name_plural

    def get_permissions_required(self) -> List[str]:
        """
        Overrides :py:meth:`wildewidgets.views.permission.PermissionRequiredMixin.get_permissions_required`.

        Expand the permissions listed in :py:attr:`required_model_permissions`
        into full Django permission strings (e.g. ``appname.add_modelname`` and
        add them to the list of permissions already defined by our superclass.

        Returns:
            The list of Django user permission strings
        """
        required_perms = set(super().get_permissions_required())
        required_perms.update(
            self.get_model_permissions(self.model, self.required_model_permissions)
        )
        return list(required_perms)

    def get_breadcrumbs(self) -> "Optional[BreadcrumbBlock]":
        """
        Add our title to the breadcrumbs and return the updated block.

        Returns:
            The breadcrumb block to use
        """
        if self.breadcrumbs:
            self.breadcrumbs.add_breadcrumb(title=self.get_title())
        return self.breadcrumbs

class GenericDatatableMixin:

    model: Optional[Type[ViewSetMixin]]

    #: The :py:class:`wildewidgets.widgets.tables.base.BaseDataTable` subclass
    #: to use for the listing table
    table_class: Type[BaseDataTable] = LookupModelTable
    #: A dictionary that we will use as the ``**kwargs`` for the constructor of
    #: :py:attr:`table_class`
    table_kwargs: Dict[str, Any] = {
        'striped': True,
        'page_length': 25,
        'buttons': True,
    }

    def get_table_kwargs(self) -> Dict[str, Any]:
        """
        Return a dict that will be used as the ``**kwargs`` for constructing our
        :py:attr:`table_class` instance.

        If there are no bulk_action form actions defined, define one for bulk
        deleting rows.

        Returns:
            Constructor kwargs for :py:class:`table_class`
        """
        table_kwargs = self.table_kwargs
        if 'form_actions' not in table_kwargs and self.bulk_action_url_name:
            table_kwargs['form_actions'] = [
                ('delete', f'Delete {self.model_verbose_name}')
            ]

        return table_kwargs

    def get_table(self, *args, **kwargs) -> BaseDataTable:
        kwargs.update(self.get_table_kwargs())
        kwargs['model'] = self.model
        actions = []
        if self.user_can_update():
            actions.append(RowEditButton())
        if self.user_can_delete():
            actions.append(RowDeleteButton())
        if actions:
            kwargs['actions'] = actions
        return self.table_class(*args, **kwargs)

# --------------------------------------------
# Views
# --------------------------------------------

class IndexView(
    LoginRequiredMixin,
    PermissionRequiredMixin,
    GenericViewMixin,
    GenericDatatableMixin,
    NavbarMixin,
    StandardWidgetMixin,
    TemplateView
):

    #: The model we're describing in this view. It must have
    #: :py:class:`wildewidgets.models.ViewSetMixin` in its class heirarchy
    model: Optional[Type[ViewSetMixin]] = None

    required_model_permissions: List[str] = ['view', 'add', 'change', 'delete']

    def get_title(self) -> str:
        """
        Return our page title.

        Returns:
            The string to use as our page title.
        """
        return self.model_verbose_name_plural

    def get_content(self) -> Widget:
        return IndexTableWidget(
            self.model,
            self.get_table(),
            show_create_button=self.user_can_create()
        )

class TableAJAXView(
    LoginRequiredMixin,
    PermissionRequiredMixin,
    WidgetInitKwargsMixin,
    GenericDatatableMixin,
    View
):
    #: The model we're describing in this view. It must have
    #: :py:class:`wildewidgets.models.ViewSetMixin` in its class heirarchy
    model: Optional[Type[ViewSetMixin]] = None

    required_model_permissions: List[str] = ['view', 'add', 'change', 'delete']

    def dispatch(self, request, *args, **kwargs):
        csrf_token = request.GET.get('csrf_token', '')
        extra_data = self.get_decoded_extra_data(request)
        initargs = extra_data.get('args', [])
        initkwargs = extra_data.get('kwargs', {})
        table = self.get_table(*initargs, **initkwargs)
        table.request = request
        table.csrf_token = csrf_token
        table.args = initargs
        table.kwargs = initkwargs
        return table.dispatch(request, *args, **kwargs)

class TableBulkActionView(
    LoginRequiredMixin,
    PermissionRequiredMixin,
    GenericViewMixin,
    GenericDatatableMixin,
    MessageMixin,
    TableActionFormView
):
    #: The model we're describing in this view. It must have
    #: :py:class:`wildewidgets.models.ViewSetMixin` in its class heirarchy
    model: Optional[Type[ViewSetMixin]] = None

    #: Set this to the logger of your choice
    logger: Any = logger

    required_model_permissions: List[str] = ['delete']

    def process_delete_action(self, items: List[str]) -> None:
        qs = self.model.objects.filter(id__in=items)
        count = qs.count()
        qs.delete()
        self.logger.info(
            '%s.bulk.delete ids=%s %s',
            self.model_logger_name,
            ','.join(items),
            self.logging_extra
        )
        self.messages.success(f'Deleted {count} {self.model.model_verbose_name_plural()}.')

class CreateView(
    LoginRequiredMixin,
    PermissionRequiredMixin,
    FormInvalidMessageMixin,
    FormValidMessageMixin,
    GenericViewMixin,
    NavbarMixin,
    StandardWidgetMixin,
    DjangoCreateView
):

    required_model_permissions: List[str] = ['add']

    #: Use this :py:class:`AbstractFormPageLayout` subclass to render our page
    layout_widget: Type[AbstractFormPageLayout] = FormPageLayout

    def get_form_invalid_message(self):
        self.logger.warning(
            '%s.create.failed.validation %s',
            self.model_logger_name,
            self.logging.extra
        )
        return f"Couldn't create this {self.model_verbose_name} due to validation errors; see below."

    def get_form_valid_message(self):
        self.logger.info('%s.create.success %s', self.model_logger_name, self.logging_extra)
        return f'Created {self.model_verbose_name} "{str(self.object)}"!'

    def get_form_class(self) -> Type[BaseModelForm]:
        # FIXME: this is probably not the right way to do this.  I'd like it
        # that if there is a form_class defined on us, use that otherwise ask
        # the model
        if hasattr(self.model, 'get_create_form_class'):
            return self.model.get_create_form_class()
        return super().get_form_class()

    def get_title(self) -> str:
        """
        Return our page title.

        Returns:
            The string to use as our page title.
        """
        return f'Create {self.model_verbose_name}'

    def get_content(self) -> Widget:
        return self.layout_widget(self, modifier='create')

class UpdateView(
    LoginRequiredMixin,
    PermissionRequiredMixin,
    FormInvalidMessageMixin,
    FormValidMessageMixin,
    GenericViewMixin,
    NavbarMixin,
    StandardWidgetMixin,
    DjangoUpdateView
):

    required_model_permissions: List[str] = ['change']

    #: Use this :py:class:`AbstractFormPageLayout` subclass to render our page
    layout_widget: Type[AbstractFormPageLayout] = FormPageLayout

    def get_form_invalid_message(self):
        self.logger.warning(
            '%s.update.failed.validation %s',
            self.model_logger_name,
            self.logging.extra
        )
        return f"Couldn't update this {self.model_verbose_name} due to validation errors; see below."

    def get_form_valid_message(self):
        self.logger.info('%s.update.success %s', self.model_logger_name, self.logging_extra)
        return f'Updated {self.model_verbose_name} "{str(self.object)}"!'

    def get_form_class(self) -> Type[BaseModelForm]:
        # FIXME: this is probably not the right way to do this.  I'd like it
        # that if there is a form_class defined on us, use that otherwise ask
        # the model
        if hasattr(self.object, 'get_update_form_class'):
            return self.object.get_update_form_class()
        return super().get_form_class()

    def get_title(self) -> str:
        """
        Return our page title.

        Returns:
            The string to use as our page title.
        """
        return f'Update {self.model_verbose_name} "{str(self.object)}"'

    def get_content(self) -> Widget:
        return self.layout_widget(self, modifier='update')

class DeleteView(
    LoginRequiredMixin,
    PermissionRequiredMixin,
    GenericViewMixin,
    FormInvalidMessageMixin,
    FormValidMessageMixin,
    BaseDeleteView
):

    model: Optional[Type[ViewSetMixin]] = None

    http_method_names: List[str] = ['post']

    required_model_permissions: List[str] = ['delete']

    def get_form_invalid_message(self):
        self.logger.warning('%s.delete.failed.validation', self.model_logger_name)
        return f'Couldn\'t delete {self.model_verbose_name} "{str(self.object)}"'

    def get_form_valid_message(self):
        self.logger.info('%s.delete.success %s', self.model_logger_name, self.logging_extra)
        return f'Deleted {self.model_verbose_name} "{str(self.object)}"!'

    def form_invalid(self, form: BaseModelForm) -> HttpResponse:
        return redirect(self.get_success_url())

    def get_form_class(self) -> Type[BaseModelForm]:
        # FIXME: this is probably not the right way to do this.  I'd like it
        # that if there is a form_class defined on us, use that otherwise ask
        # the model
        if hasattr(self.object, 'get_delete_form_class'):
            return self.object.get_delete_form_class()
        return super().get_form_class()

class ManyToManyRelatedFieldView(
    LoginRequiredMixin,
    PermissionRequiredMixin,
    FormValidMessageMixin,
    MessageMixin,
    GenericViewMixin,
    BaseUpdateView
):

    field_name: Optional[str] = None
    form_class: Type[AbstractRelatedFieldForm] = ToggleableManyToManyFieldForm

    required_model_permissions: List[str] = ['change']

    @property
    def model_logger_name(self) -> str:
        return f'{super().model_logger_name}.{self.field_name}'

    @property
    def field_verbose_name(self) -> str:
        return self.model._meta.get_field(self.field_name).verbose_name.capitalize()

    def get_form_kwargs(self) -> Dict[str, Any]:
        kwargs = super().get_form_kwargs()
        kwargs['field_name'] = self.field_name
        return kwargs

    def form_invalid(self, form: Form) -> HttpResponse:
        self.logger.warning(
            '%s.update.failed.validation %s',
            self.model_logger_name,
            self.logging.extra
        )
        self.messages.error(
            f'Couldn\'t update {self.field_verbose_name} on {self.model_verbose_name} "{str(self.object)}"'
        )
        for k, errors in form.errors.as_data().items():
            for error in errors:
                self.messages.error(f"{k}: {error.message}")
        return redirect(self.get_success_url())

    def get_form_valid_message(self):
        self.logger.info('%s.update.success %s', self.model_logger_name, self.logging_extra)
        return f'Updated {self.field_verbose_name} on {self.model_verbose_name} "{str(self.object)}"!'

    def get_success_url(self) -> str:
        success_url = super().get_success_url()
        if not success_url:
            if hasattr(object, 'get_update_url'):
                return self.object.get_update_url()
            return self.object.get_absolute_url()
        return success_url

class HTMXView(TemplateView):
    """
    Simple view to display only a widget as a response. This is useful for
    HTMX requests. The widget is rendered with the context data from the
    request, such that anything sent via GET or POST is passed as kwargs to
    the widget's constructor.

    Example:

        class MyWidgetHTMXView(HTMXView):
            widget_class = MyWidget
    """
    template_name = 'wildewidgets/htmx_base.html'
    widget_class = None
    include_request = False

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.data = None

    # pylint: disable=not-callable
    def get_content(self, **kwargs):
        if self.widget_class:
            if self.include_request:
                self.data['request'] = self.request
            return self.widget_class(**self.data)
        raise NotImplementedError

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['content'] = self.get_content(**self.data)
        return context

    def set_data(self, request_data):
        self.data = request_data.dict()
        del self.data['submit']

    def get(self, request, *args, **kwargs):
        self.set_data(request.GET)
        return super().get(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        self.set_data(request.POST)
        return super().get(request, *args, **kwargs)


# -*- coding: utf-8 -*-
"""
Methods to compute the centroid from a dataset.

@author: alex-merge
@version: 0.8
"""
import numpy as np
from random import randrange

class centroid():
    """
    Set of methods to compute the centroid for OAT.
    """

    def compute_distance_sum(point, arr):
        """
        Return the sum of the distance between all spots and the point.

        Parameters
        ----------
        point : np.ndarray
            Point to compute the distance from.
        arr : np.ndarray
            Array containing all the spots coordinates.
            Each row contains the spot coordinates.
            Each column contains the coordinates on a given axis.

        Returns
        -------
        float
            Sum of the distances.

        """
        return sum([np.linalg.norm( arr[k, :]-point ) for k in range(arr.shape[0])])

    def compute_gradient_centroid(df, coord_column, searching_spd = 1,
                                  threshold = 0.05, iteration = 100):
        """
        Compute the centroid of the given coordinates using a gradient slope.

        First we take a random point, compute its distance from all spots.
        Then we compute the variation of this distance on each axis and go
        where the distance decrease.

        This is reiterated several times to make sure we get the global minima.

        Parameters
        ----------
        df : pandas.DataFrame
            Dataframe which contain the coordinates of the spots.
        coord_column : str
            Name of the column which contains the coordinates.
        searching_spd : int, optional
            Speed at which the coordinates goes down the gradient.
            The default is 1.
        threshold : float, optional
            Stop the search if the distance decrease if less than the threshold.
            The default is 0.05.
        iteration : int, optional
            Number of iterations. The default is 100.

        Returns
        -------
        cent_coord : numpy.ndarray
            Coordinates of the centroid.

        """
        ## Creating a list to store results as follow :
        ##  [ [sum of the distance, coordinates array of the point], ... ]
        computed_coords = []

        ## delta on each axis
        h = [np.array([0.001, 0, 0]), np.array([0, 0.001, 0]),
                     np.array([0, 0, 0.001])]

        arr = np.array(df[coord_column].dropna().tolist())

        ## Looping over the number of iteration wanted
        for step in range(iteration):

            ## Randomly selecting a point within the min/max on each axis
            point = np.array([randrange(int(arr[:, 0].min()), int(arr[:, 0].max())),
                              randrange(int(arr[:, 1].min()), int(arr[:, 1].max())),
                              randrange(int(arr[:, 2].min()), int(arr[:, 2].max()))])

            """
            Looping while the distance between 2 computed distances is less
            than the threshold or if the last computed sum is equal to one of the
            already computed sums.
            """
            while (len(computed_coords) >= 3 and
                abs(computed_coords[-1][0] - computed_coords[-2][0]) >= threshold \
                and computed_coords[-1][0] != computed_coords[-3][0]) \
                or len(computed_coords) < 3:

                distance = centroid.compute_distance_sum(point, arr)
                computed_coords.append([distance, point])

                ## Getting variation of the distance by slightly varying coordinates
                delta_dist = [distance - centroid.compute_distance_sum(point+h[axis],
                                                                       arr)
                              for axis in range(3)]

                point += np.array([searching_spd*int(round((k/abs(k)), 0))
                                   for k in delta_dist])

        ## Getting the minimum then the coordinates where this minimum is achieved.
        minimum = min([value[0] for value in computed_coords])
        cent_coord = [value[1] for value in computed_coords if value[0] == minimum][0]

        return cent_coord

    def compute_mean_centroid(df, coord_column):
        """
        Simply compute the mean value on each axis and return the coordinates.

        Parameters
        ----------
        df : pandas.DataFrame
            Dataframe where coordinates are stored as array in the
            coord_column.
        coord_column : str
            Name of the column containing the coordinates.

        Returns
        -------
        cent_coord : numpy.ndarray
            Coordinates of the centroid as an array.

        """
        ## Converting the coordinates in a big array where rows are points
        ## coordinates and columns are the coordinates on a given axis.
        arr = np.array(df[coord_column].dropna().tolist())

        ## Computing the mean by columns.
        cent_coord = np.array([arr[:, ax].mean() for ax in range(arr.shape[1])])

        return cent_coord

    def compute_sampled_centroid(df, coord_column, n_sample = 10, iteration = 100,
                                 method = "median"):
        """
        Compute the mean centroid for a random sample of the dataframe, several
        times depending on the number of wanted iteration..
        The size of the random sample (i.e. the number of rows) is set by
        n_sample.

        Parameters
        ----------
        df : pandas.DataFrame
            Dataframe where coordinates are stored as array in the
            coord_column.
        coord_column : str
            Name of the column containing the coordinates.
        n_sample : int
            Number of sample by random sampling.
        iteration : int
            Number of subsampled centroid to compute.
        method : str
            Method to get the final centroid :
                median : median of the coordinates
                mean : mean of the coordinates

        Returns
        -------
        numpy.ndarray
            Coordinates of the centroid as an array.

        """
        centroids = [centroid.compute_mean_centroid(df.sample(n_sample, axis = 0),
                                                    coord_column)
                     for i in range(iteration)]
        centroids_arr = np.array(centroids)

        if method == "median":
            return np.array([np.median(centroids_arr[:, k])
                             for k in range(centroids_arr.shape[1])])
        else :
            return np.array([np.mean(centroids_arr[:, k])
                             for k in range(centroids_arr.shape[1])])


import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import queue as q
import os
from os.path import isfile, join
import seaborn as sns
import matplotlib.pylab as pylab
import sys

sys.path.append('/Users/aabir/anaconda/envs/pca/simulations')

sns.set_style('whitegrid')

params = {'legend.fontsize': 'x-large',
          'figure.figsize': (10,10),
         'axes.labelsize': '24',
         'axes.titlesize':'24',
         'figure.titlesize': '24',
         'xtick.labelsize':'22',
         'ytick.labelsize':'22',
         'text.color':'k',
         'axes.formatter.useoffset':False,
         'grid.color' : 'k',
		 'grid.linestyle' : ':',
		 'grid.linewidth' : 0.5,
		 'legend.fancybox' : True,
		 'legend.framealpha' : 0.5,
         'axes.labelcolor' : 'k'}

pylab.rcParams.update(params)

from invmgmt.invsim import *
from invmgmt.simanalytics import *
from invmgmt.runsim import *

def MKBformatter(num, round=True):
    if any([int(np.abs(num))%(10**i) for i in range(len(str(int(np.abs(num)))))]) and not round:
        raise ValueError('Cannot round and num {} is not a power multiple of 10'.format(num))
    Kval = int(num/1000)
    if np.abs(Kval) <= 1:
        return num
    elif np.abs(Kval) < 1000:
        return str(Kval)+'K'
    else:
        Mval = int(num/10**6)
        if Mval < 1000:
            return str(Mval)+'M'
        else:
            Bval = int(num/10**9)
            return str(Bval)+'B'


from odoo import http
from odoo.http import request

class WebsiteOrganizationRegistration(http.Controller):
    _ORGANIZATION_REGISTRATION_FIELDS = [
        "company_name",
        "business_name",
        "website_description",
        "street",
        "street2",
        "city",
        "zipcode",
        "country_id",
        # "team_id",  # TODO: issue occuring when this field is added. INVESTIGATION NEEDED
        "phone",
        "company_email",
        "website_url",
        "industry_id",
        "detailed_activity",
        "reasons_choosing_mlc",
        "opening_time",
        "discount",
        "contact_name",
        "function",
        "email_pro",
        "phone_pro",
        "message_from_candidate",
    ]

    # Variable to update to add other fields in child classes
    _EXTRA_FIELDS = []

    def get_organization_membership_product(self):
        product_obj = request.env["product.template"]
        product = product_obj.sudo().get_organization_membership_product(
            request.website.company_id.id
        )
        return product

    def _get_selected_team_id(self):
        if len(request.env['res.company'].sudo().search([])) > 1:
            return request.env["crm.team"].sudo().search([("local_group", "=", True), ("company_id", "=", request.website.company_id.id)])
        else:
            return request.env["crm.team"].sudo().search([("local_group", "=", True)])

    @http.route(
        ["/web/organization_registration"],
        type="http",
        auth="public",
        website=True,
    )
    def portal_organization_registration(self, access_token=None, redirect=None, **kw):

        product = self.get_organization_membership_product()
        titles = request.env["res.partner.title"].sudo().search([])
        countries = request.env["res.country"].sudo().search([])
        teams = self._get_selected_team_id()
        industries = request.env["res.partner.industry"].sudo().search([])
        error = dict()
        error_message = []

        values = {
            "product": product,
            "total_membership": product.list_price,
            "dynamic_price": product.dynamic_price,
            "titles": titles,
            "countries": countries,
            "industries": industries,
            "teams": teams,
            "error": error,
            "error_message": error_message,
        }

        return request.render(
            "lcc_members_portal.website_organization_registration", values
        )

    def _compute_web_form_data(self, data):
        values = {
            "partner_id": 2,  # OdooBot-s ID
            "company_id": request.website.company_id.id,
            "type": "opportunity",
            "lead_type": "membership_web_application",
            "accept_coupons": data.get("accept_coupons", "off") == "on",
            "accept_digital_currency": data.get("accept_digital_currency", "off")
            == "on",
            "from_website": True,
            "itinerant": data.get("itinerant", "off") == "on",
            "want_newsletter_subscription": data.get(
                "want_newsletter_subscription", "off"
            )
            == "on",
            "accept_policy": data.get("accept_policy", "off") == "on",
            "tag_ids": [(4, request.env.ref("lcc_members_portal.categ_oppor_application").id, None)],
        }
        if float(data.get("total_membership", False)):
            values["total_membership"] = float(data.get("total_membership"))
        else:
            values[
                "total_membership"
            ] = self.get_organization_membership_product().list_price
        for field in self._ORGANIZATION_REGISTRATION_FIELDS:
            if data.get(field):
                values[field] = data.pop(field)
        for field in self._EXTRA_FIELDS:
            if data.get(field):
                values[field] = data.pop(field)
        values["name"] = values["company_name"]
        values.update({"zip": values.pop("zipcode", "")})
        values.update({"website": values.pop("website_url", "")})
        return values

    @http.route(
        ["/web/send_request"],
        type="http",
        auth="public",
        website=True,
    )
    def send_registration_request(self, **kwargs):
        # Create a new lead
        values = self._compute_web_form_data(kwargs)
        lead = request.env["crm.lead"].sudo().create(values)
        lead.team_id = kwargs.pop(
            "team_id"
        )  # TODO: see remark above concerning team_id
        return request.render(
            "lcc_members_portal.website_organization_registration_saved", {}
        )


# 양분은 모든 칸에 5만큼 들어있다.
# 같은 1×1 크기의 칸에 여러 개의 나무가 심어져 있을 수도 있다.

# 봄
# 자신의 나이만큼 양분을 먹
# 어린놈부터 먹음

#여름
# 여름에는 봄에 죽은 나무가 양분으로 변하게 된다.
# 각각의 죽은 나무마다 나이를 2로 나눈 값이 나무가 있던 칸에 양분으로 추가된다.
#  소수점 아래는 버린다.

#가을 - 번식
# 나무 나이 5의배수, 인접한 8개칸 나이 1인나무가 하나 생김

#겨울 - 양분추가
# A[r][c]만큼 각 칸에 추가
import sys;input=sys.stdin.readline
import heapq
N,M,K=map(int,input().split())
dx=[0,0,1,-1,-1,1,-1,1]
dy=[1,-1,0,0,-1,-1,1,1]

A=list(list(map(int,input().split())) for _ in range(N))
yangboon=[[5]*N for _ in range(N)]
treecount=dict()
for _ in range(M):
    tree_x,tree_y,age = map(int,input().split())
    if treecount.get((tree_x-1,tree_y-1)):
        heapq.heappush(treecount.get((tree_x-1,tree_y-1)),age)
    else:
        treecount[(tree_x-1,tree_y-1)]=[age]

for _ in range(K):
    dead=[]
    alive=dict()
    for i in treecount:
        while treecount[i]:
            temp=list(treecount[i])
            youngTreeAge=heapq.heappop(treecount[i])
            curY=yangboon[i[0]][i[1]]
            if curY>=youngTreeAge:
                yangboon[i[0]][i[1]]-=youngTreeAge
                if alive.get(i):
                    alive[i].append(youngTreeAge+1)
                else:
                    alive[i]=[youngTreeAge+1]
            else:
                dead.append((i,youngTreeAge//2))

    for xy in alive:
        agelist=alive[xy]
        if type(agelist)==int:
            treecount[(xy[0],xy[1])]=[agelist]
        else:
            heapq.heapify(agelist)
            #agelist.reverse()
            treecount[(xy[0],xy[1])]=agelist

    for xy,age in dead:
        yangboon[xy[0]][xy[1]]+=age
    young=[]
    reAppend=dict()
    for i in treecount:
        for j in range(len(treecount[i])):
            age=heapq.heappop(treecount[i])
            if reAppend.get(i):
                reAppend[i].append(age)
            else:
                reAppend[i]=[age]
            #reAppend.append((i,age))
            x=i[0]
            y=i[1]
            if age%5==0:
                for asdf in range(8):
                    mx=x+dx[asdf]
                    my=y+dy[asdf]
                    if 0<=mx<N and 0<=my<N:
                        young.append((mx,my))
    for xy in reAppend:
        age=reAppend[xy]
        if type(age)==int:
            treecount[xy]=[age]
        else:
            heapq.heapify(age)
            treecount[(xy[0],xy[1])]=age

    for mx,my in young:
        if treecount.get((mx,my)):
            heapq.heappush(treecount[(mx,my)],1)
        else:
            treecount[(mx,my)]=[1]

    for i in range(N):
        for j in range(N):
            yangboon[i][j]+=A[i][j]
ans=0
for i in treecount.values():
    if type(i)==list:
        ans+=len(i)
    else:
        ans+=1
print(ans)
#실패


from functools import lru_cache

cache_fib = {}
def fibo(x):
    if type(x)!=int:
        raise TypeError("type mismatch")
    if x<0:
        raise ValueError("value should be positive")
    if x in cache_fib:
        return cache_fib[x]
    if x==1:
        return 0
    elif x==2:
        return 1
    elif x>2:
        cache_fib[x]=fibo(x-2)+fibo(x-1)
        return fibo(x-2)+fibo(x-1)

for i in range(1,20):
    print(i,':',fibo(i))

for i in cache_fib.items():
    print(i)

#fibo("-2")


import re

from pyparsing import (
    Char,
    Combine,
    LineEnd,
    LineStart,
    Literal,
    MatchFirst,
    OneOrMore,
    Optional,
    ParserElement,
    ParseResults,
    Regex,
    SkipTo,
    StringEnd,
    Token,
)

from jira2markdown.markup.advanced import Panel
from jira2markdown.markup.base import AbstractMarkup
from jira2markdown.markup.text_effects import BlockQuote, Color

class ListIndentState:
    def __init__(self):
        self.indent = 0

    def reset(self):
        self.indent = 0

class ListIndent(Token):
    def __init__(self, indent_state: ListIndentState, tokens: str):
        super().__init__()

        self.indent_state = indent_state
        self.tokens = tokens

    def parseImpl(self, instring, loc, doActions=True):
        exprs = []
        for token in self.tokens:
            for indent in range(self.indent_state.indent + 1, max(0, self.indent_state.indent - 2), -1):
                exprs.append(Literal(token * indent + " "))

        loc, result = MatchFirst(exprs).parseImpl(instring, loc, doActions)
        self.indent_state.indent = len(result[0]) - 1
        return loc, result

class List(AbstractMarkup):
    is_inline_element = False

    def __init__(self, nested_token: str, nested_indent: int, tokens: str, indent: int, bullet: str, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.nested_token = nested_token
        self.nested_indent = nested_indent
        self.tokens = tokens
        self.indent = indent
        self.bullet = bullet

        self.indent_state = ListIndentState()

    def action(self, tokens: ParseResults) -> str:
        result = []

        for line in tokens:
            bullets, text = line.split(" ", maxsplit=1)

            nested_indent = 0
            while bullets[0] == self.nested_token:
                nested_indent += 1
                bullets = bullets[1:]

            count = nested_indent * self.nested_indent + len(bullets) * self.indent

            line_padding = " " * count
            item_padding = " " * (count - self.indent) + self.bullet + " "
            text = self.markup.transform_string(text).splitlines() or [""]

            result.append(
                "\n".join([item_padding + line if i == 0 else line_padding + line for i, line in enumerate(text)]),
            )

        self.indent_state.reset()
        text_end = "\n" if (tokens[-1][-1] == "\n") else ""
        return "\n".join(result) + text_end

    @property
    def expr(self) -> ParserElement:
        WHITESPACE = Regex(r"[ \t]+", flags=re.UNICODE)
        EOL = LineEnd()
        LIST_BREAK = EOL + Optional(WHITESPACE) + EOL | StringEnd()
        IGNORE = BlockQuote(**self.init_kwargs).expr | Panel(**self.init_kwargs).expr | Color(**self.init_kwargs).expr
        ROW = (
            LineStart()
            + Optional(WHITESPACE).suppress()
            + Combine(
                Optional(self.nested_token, default="")
                + ListIndent(self.indent_state, self.tokens)
                + SkipTo(
                    EOL + Optional(WHITESPACE) + Char(self.nested_token + self.tokens) | LIST_BREAK,
                    ignore=IGNORE,
                )
                + Optional(EOL),
            )
        )

        return OneOrMore(ROW, stop_on=LIST_BREAK).set_parse_action(self.action)

class UnorderedList(List):
    def __init__(self, *args, **kwargs):
        super().__init__(nested_token="#", nested_indent=3, tokens="*-", indent=2, bullet="-", *args, **kwargs)

    def action(self, tokens: ParseResults) -> str:
        result = super().action(tokens)
        first_line = (result.splitlines() or [""])[0].strip()

        # Text with dashed below it turns into a heading. To prevent this
        # add a line break before an empty list.
        if first_line == "-":
            return "\n" + result
        else:
            return result

class OrderedList(List):
    def __init__(self, *args, **kwargs):
        super().__init__(nested_token="*", nested_indent=2, tokens="#", indent=3, bullet="1.", *args, **kwargs)


from typing import List
import gymnasium as gym
import numpy as np
from urdfenvs.robots.generic_urdf import GenericUrdfReacher
from urdfenvs.scene_examples.goal import dynamicGoal
from urdfenvs.scene_examples.obstacles import dynamicSphereObst2
from urdfenvs.urdf_common.urdf_env import UrdfEnv

def run_panda_capsules(n_steps=100000, render=False, goal=True, obstacles=True):
    robots = [
        GenericUrdfReacher(urdf="panda_collision_links.urdf", mode="vel"),
    ]
    env: UrdfEnv = gym.make(
        "urdf-env-v0",
        dt=0.01, robots=robots,
        render=render,
        observation_checking=False,
    )
    env.add_goal(dynamicGoal)
    env.add_obstacle(dynamicSphereObst2)
    env.set_spaces()
    action = np.ones(env.n()) * 0.1
    ob = env.reset()

    link_translations = [
            np.array([0.0, 0.0, -0.1915]),
            np.array([0.0, 0.0, 0.0]),
            np.array([0.0, 0.0, -0.145]),
            np.array([0.0, 0.0, 0.0]),
            np.array([0.0, 0.0, -0.26]),
            np.array([0, 0.08, -0.13]),
            np.array([0, 0.0, -0.03]),
            np.array([0, 0.0, 0.01]),
            np.array([0.0424, 0.0424, -0.0250]),
    ]
    link_rotations = [np.identity(3)] * 9
    link_rotations[8] = np.array([[0, 0, -1], [-1, 0, 0], [0, 1, 0]])
    collision_links = [0, 1, 2, 3, 4, 4, 5, 6, 7]
    collision_links: List[str] = [
            "panda_link1",
            "panda_link2",
            "panda_link3",
            "panda_link4",
            "panda_link5",
            "panda_link5",
            "panda_link6",
            "panda_link7",
            "panda_link8",
    ]
    lengths = [0.2830, 0.12, 0.15, 0.12, 0.1, 0.14, 0.08, 0.14, 0.01]

    radii = [0.09, 0.09, 0.09, 0.09, 0.09, 0.055, 0.08, 0.07, 0.06]
    for i in range(len(collision_links)):
        link_transformation = np.identity(4)
        link_transformation[0:3, 3] = link_translations[i]
        link_transformation[0:3, 0:3] = link_rotations[i]
        env.add_collision_link(
                robot_index=0,
                link_index=collision_links[i],
                shape_type="capsule",
                size=[radii[i], lengths[i]],
                link_transformation=link_transformation,
        )

    print(f"Initial observation : {ob}")
    print("Starting episode")
    history = []
    for i in range(n_steps):
        collision_links_position: dict = env.collision_links_poses(position_only=True)
        ob, *_ = env.step(action)
        history.append(ob)
    env.close()
    return history

if __name__ == "__main__":
    run_panda_capsules(render=True)


import paho.mqtt.client as mqtt
import phone_auth_token as auth
from time import sleep
import paho.mqtt.client as mqtt
from tinder_bot_sms import TinderBotSms
import subprocess
import random

phone_number = ''
def on_connect(client, userdata,flags,rc):
    print("connected with result code "+ str(rc))
    client.subscribe("tinder")

def on_connect_oled(client,userdata,flags,rc):
    clientOled.subscribe("tinder/oled")

def on_message(client, userdata, msg):
    if  "00" in msg.payload.decode():
        phone_number = msg.payload.decode()
        log_code = auth.send_otp_code(phone_number)
    else:
        otp_code = msg.payload.decode()
        refresh_token =auth.get_refresh_token(otp_code, phone_number)
        print("Here is your Tinder token: " + str(auth.get_api_token(refresh_token)))
        tinder = TinderBotSms(auth.get_api_token(refresh_token))
        tinder.auto_swipe(5)
        for person in tinder.get_persons():
            client.publish("tinder","name: "+ person.name + "type: " +person.type )
            if(person.type == "like"):
                clientOled.publish("tinder/oled",msg.payload.decode())
            else:
                clientOled.publish("tinder/oled",msg.payload.decode())
            sleep(3)
        #client.disconnect()

def on_message_default(client,userdata,msg):
    if(random.random() < 0.6):
        clientOled.publish("tinder/oled",msg.payload.decode())
    else:
        clientOled.publish("tinder/oled",msg.payload.decode())

client = mqtt.Client()
client.connect("192.168.249.111",1883,60)
clientOled = mqtt.Client()
clientOled.connect("192.168.249.111",1883,60)

client.on_connect = on_connect
client.on_message = on_message_default

clientOled.on_connect = on_connect_oled

client.loop_forever()


def binary_search(array, left, right, target):
    #while Loop 내에서 찾으면 존재
    while left <= right:
        middle_idx = (left + right) // 2
        middle = array[middle_idx]
        if target == middle:
            return True
        elif target < middle:
            right = middle_idx - 1
        else:
            left = middle_idx + 1
    #while Loop 내에서 찾지 못하면 존재하지 않음
    return False

if __name__ == "__main__":
    lst = [10, 5, 1, 9, 7, 39, 58, 24, 66, 73, 22, 11]
    lst.sort()
    if binary_search(lst, 0, len(lst), 24):
        print('exist')
    else:
        print('not exist')


from fenics_concrete.experimental_setups.experiment import Experiment
from fenics_concrete.helpers import Parameters
import dolfin as df

class MinimalCubeExperiment(Experiment):
    def __init__(self, parameters=None):
        # initialize a set of "basic paramters" (for now...)
        p = Parameters()
        # boundary values...
        p['T_0'] = 20  # inital concrete temperature
        p['dim'] = 2  # default boundary setting
        p['mesh_density'] = 1  # default boundary setting
        p['mesh_setting'] = 'left/right'  # default boundary setting
        p = p + parameters
        super().__init__(p)

    def setup(self, bc='full'):
        self.bc = bc  # different boundary settings
        # elements per spacial direction
        n = self.p.mesh_density
        if self.p.dim == 2:
            self.mesh = df.UnitSquareMesh(n, n, self.p.mesh_setting)
        elif self.p.dim == 3:
            self.mesh = df.UnitCubeMesh(n, n, n)
        else:
            print(f'wrong dimension {self.p.dim} for problem setup')
            exit()

    def create_temp_bcs(self, V):
        # no temperature boudary!!!

        temp_bcs = []

        return temp_bcs

    def create_displ_bcs(self, V):
        # define displacement boundary
        displ_bcs = []

        if self.p.dim == 2:
            displ_bcs.append(df.DirichletBC(V, df.Constant((0, 0)), self.boundary_full()))
        elif self.p.dim == 3:
            displ_bcs.append(df.DirichletBC(V, df.Constant((0, 0, 0)), self.boundary_full()))

        return displ_bcs


"""Test for TaskContextConnection"""
from unittest.mock import Mock

import pytest

from pynocular.aiopg_transaction import LockedConnection, TaskContextConnection

@pytest.fixture()
def locked_connection():
    """Return a locked connection"""
    return LockedConnection(Mock())

@pytest.mark.asyncio()
async def test_task_context_connection_set_clear(locked_connection) -> None:
    """Test that we can set and clear the connection"""

    context_conn = TaskContextConnection("key1")
    context_conn.set(locked_connection)
    test_conn = context_conn.get()
    assert test_conn == locked_connection

    context_conn.clear()
    # No connection should exist now
    test_conn = context_conn.get()
    assert test_conn is None

@pytest.mark.asyncio()
async def test_task_context_connection_shared(locked_connection) -> None:
    """Test that we can share context across instances"""

    context_conn = TaskContextConnection("key1")
    context_conn.set(locked_connection)
    test_conn = context_conn.get()
    assert test_conn == locked_connection

    # Create another instance that should share the connection
    context_conn2 = TaskContextConnection("key1")
    test_conn2 = context_conn2.get()
    assert test_conn2 == locked_connection

    context_conn.clear()
    # No connection should exist on either connection
    test_conn = context_conn.get()
    assert test_conn is None
    test_conn2 = context_conn2.get()
    assert test_conn2 is None


import sys
input = sys.stdin.readline

N, K, B = map(int, input().split())
arr = [1] * (N + 1)
for _ in range(B):
    n = int(input())
    arr[n] = 0
cnt = sum(arr[1:1 + K])
ans = min(float('inf'), K - cnt)
for i in range(1, N - K + 1):
    cnt = cnt - arr[i] + arr[K + i]
    ans = min(ans, K - cnt)
print(ans)

백준/Silver/14465. 소가 길을 건너간 이유 5/소가 길을 건너간 이유 5.py

소가 길을 건너간 이유 5.py


import numpy as np

from matplotlib.axes import Axes
from matplotlib.collections import PathCollection
from matplotlib.lines import Line2D
from matplotlib.projections import register_projection

class PickableAxes(Axes):
    """
    A subclass of matplotlib.axes._axes.Axes which support selection and action on data series.

    The axes currently support plotting methods the same as in a basic Axes except that
    a parent Run (i.e. DataFrame) can be supplied with the data. Corresponding data
    from the parent can be displayed for a particular point by clicking on it within
    the active Figure.

    The columns from the parent run which are shown when a daa point is selected are defined
    in the PickableAxes object's options.annotation_data attribute.

    Parameters
    ----------
    *args
        Positional arguments passed to the Axes constructor
    **kwargs
        Arbitrary keyword arguments passed to the Axes constructor

    Notes
    -----
    .. [1] To select multiple points within the same data series, hold Ctrl while clicking

    References
    ----------
    .. [1] matplotlib Custom Projections documentation:
           https://matplotlib.org/gallery/misc/custom_projection.html

    See Also
    --------
    .. [1] PickableAxesOptions
    .. [2] matplotlib.axes._axes.Axes
    """

    name = 'pickable'
    """
    The matplotlib projection name. The user will use this name to activate
    the PickableAxes functionality i.e. subplot(111, projection='pickable').
    """

    DATA_ARTISTS = (Line2D, PathCollection)
    """
    Supported artists (i.e. plot features) for pickable functionality.
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.cla()

        self.handlers = {}
        self.options = PickableAxesOptions(self)

        self.figure.canvas.mpl_connect('pick_event', self.onpick)

    def loglog(self, *args, parent=None, indices=None, **kwargs):
        """
        Make a pickable plot with log scaling on both the x and y axes.

        Parameters
        ----------
        *args:
            Positional arguments passed to the Axes.loglog method
        parent: pygui.data.run.Run or DataFrame, optional. Default=None.
            The parent DataFrame that the x,y data came from.
        indices: list(int), optional
            The indices of each parent that the i'th data point corresponds to (if separate parent for each point).
        **kwargs:
            Arbitrary keyword arguments passed to the Axes.loglog method.

        Returns
        -------
        lines: list(Line2D)
            A list of Line2D object(s) representing the plotted data.

        Notes
        -----
        .. [1] A parent must be supplied in order for the data series to be pickable.
        """
        picker = self.options.picker if parent is not None else None
        lines = super().loglog(*args, picker=picker, **kwargs)
        self._add_artists(lines, parent)
        return lines

    def onpick(self, event):
        """
        Callback function for a pick event.

        Parameters
        ----------
        event: matplotlib.backend_bases.Event
            The pick event obejct.
        """

        # only act when supported objects are picked
        if any(isinstance(event.artist, o) for o in self.DATA_ARTISTS):
            artist = event.artist                   # the picked plot feature
            ind = self._get_closest_index(event)    # the index of the data series closest to the click
            key = event.mouseevent.key              # any keys that were pressed at the time of the click

            # get the artist handler obejct
            handler = self.handlers[artist]

            # TODO: IMPLEMENT ABILITY TO CHECK IF MULTIPLE LINES HAVE BEEN PICKED AND ONLY TAKE ACTION FOR ONE
            if key is None:
                # no keyboard keys held, simply select/deselect the artist
                handler.flip_selection_status(ind)
            elif 'control' in key or 'ctrl' in key:
                # allow multiple selections
                handler.select(ind)
            else:
                # simply select/deselect te artist
                handler.flip_selection_status()

    def plot(self, *args, parent=None, indices=None, **kwargs):
        """
        Make a pickable plot.

        Parameters
        ----------
        *args:
            Positional arguments passed to the Axes.loglog method
        parent: pygui.data.run.Run or DataFrame, optional. Default=None.
            The parent DataFrame that the x,y data came from.
        indices: list(int), optional
            The indices of each parent that the i'th data point corresponds to (if separate parent for each point).
        **kwargs:
            Arbitrary keyword arguments passed to the Axes.loglog method.

        Returns
        -------
        lines: list(Line2D)
            A list of Line2D object(s) representing the plotted data.

        Notes
        -----
        .. [1] A parent must be supplied in order for the data series to be pickable.
        """
        picker = self.options.picker if parent is not None else None
        lines = super().plot(*args, picker=picker, **kwargs)
        self._add_artists(lines, parent, indices)
        return lines

    def scatter(self, *args, parent=None, indices=None, **kwargs):
        """
        Make a pickable scatter plot.

        Parameters
        ----------
        *args:
            Positional arguments passed to the Axes.loglog method
        parent: pygui.data.run.Run or DataFrame, optional. Default=None.
            The parent DataFrame that the x,y data came from.
        indices: list(int), optional
            The indices of each parent that the i'th data point corresponds to (if separate parent for each point).
        **kwargs:
            Arbitrary keyword arguments passed to the Axes.loglog method.

        Returns
        -------
        paths: PathCollection
            Collection representing the plotted data.

        Notes
        -----
        .. [1] A parent must be supplied in order for the data series to be pickable.
        """
        picker = self.options.picker if parent is not None else None
        collections = super().scatter(*args, picker=picker, **kwargs)
        self._add_artists(collections, parent)
        return collections

    def semilogx(self, *args, parent=None, indices=None, **kwargs):
        """
        Make a pickable plot with log scaling on the x axis.

        Parameters
        ----------
        *args:
            Positional arguments passed to the Axes.loglog method
        parent: pygui.data.run.Run or DataFrame, optional. Default=None.
            The parent DataFrame that the x,y data came from.
        indices: list(int), optional
            The indices of each parent that the i'th data point corresponds to (if separate parent for each point).
        **kwargs:
            Arbitrary keyword arguments passed to the Axes.loglog method.

        Returns
        -------
        lines: list(Line2D)
            A list of Line2D object(s) representing the plotted data.

        Notes
        -----
        .. [1] A parent must be supplied in order for the data series to be pickable.
        """
        picker = self.options.picker if parent is not None else None
        lines = super().semilogx(*args, picker=picker, **kwargs)
        self._add_artists(lines, parent)
        return lines

    def semilogy(self, *args, parent=None, indices=None, **kwargs):
        """
        Make a pickable plot with log scaling on the y axis.

        Parameters
        ----------
        *args:
            Positional arguments passed to the Axes.loglog method
        parent: pygui.data.run.Run or DataFrame, optional. Default=None.
            The parent DataFrame that the x,y data came from.
        indices: list(int), optional
            The indices of each parent that the i'th data point corresponds to (if separate parent for each point).
        **kwargs:
            Arbitrary keyword arguments passed to the Axes.loglog method.

        Returns
        -------
        lines: list(Line2D)
            A list of Line2D object(s) representing the plotted data.

        Notes
        -----
        .. [1] A parent must be supplied in order for the data series to be pickable.
        """
        picker = self.options.picker if parent is not None else None
        lines = super().semilogy(*args, picker=picker, **kwargs)
        self._add_artists(lines, parent)
        return lines

    def _add_artists(self, artists, parent, indices=None):
        """
        Create a handler object for each artist and store them.

        Parameters
        ----------
        artists: list(matplotlib.artist.Artist)
            List of matplotlib artists (e.g. Line2D, PathCollection)
        parent: pygui.data.run.Run or DataFrame or None
            The parent DataFrame or None
        """
        if parent is not None:
            if isinstance(artists, PathCollection):
                artists = [artists]
            for artist in artists:
                self.handlers[artist] = self._create_artist_handler(artist, parent=parent, indices=indices)

    @classmethod
    def _create_artist_handler(cls, artist, *args, **kwargs):
        """
        Determine the type of the artist and create an appropriate handler object.

        Parameters
        ----------
        artist: matplotlib.artist.Artist
            The artist for which the handler is to be made.
        *args
            Positional arguments passed to the handler constructor.
        **kwargs
            Arbitrary keywords arguments passed to the handler constructor.

        Returns
        -------
        handler: _PickableArtistHandler or a subclass thereof
        """
        if isinstance(artist, Line2D):
            return _PickableLine2DHandler(artist, *args, **kwargs)
        elif isinstance(artist, PathCollection):
            return _PickablePathCollectionHandler(artist, *args, **kwargs)
        else:
            return _PickableArtistHandler(artist, *args, **kwargs)

    @staticmethod
    def _get_artist_data(artist):
        """
        Get the x,y data which the artist represents.

        Parameters
        ----------
        artist: matplotlib.artist.Artist
            the artist containing the data.

        Returns
        -------
        data: numpy.array (ndim=1), numpy.array (ndim=1)
        """
        if isinstance(artist, Line2D):
            return artist.get_data()
        elif isinstance(artist, PathCollection):
            data = artist.get_offsets()
            rows = data.shape[0]
            return data[:, 0].reshape((rows,)), data[:, 1].reshape((rows,))
        else:
            raise TypeError("Artist type not recognized. Supported types are 'Line2D' and 'PathCollection'")

    def _get_closest_index(self, event):
        """
        Get the data index closest to the pick event's mouse location.

        The event.ind attribute always seems to return the lower of the two indices
        that comprise a selected line segment, even if the mouse click was closer to
        the higher indexed point.

        This method checks both the returned index and the next higher index to determine
        which one is closer.

        Parameters
        ----------
        event: matplotlib.backend_bases.Event
            The pick event.

        Returns
        -------
        ind: int
            The index of the data closest to the click.
        """

        # get the lower index (or indices) that is returned by default
        indices = event.ind

        # get the full data series for the artist
        datax, datay = self._get_artist_data(event.artist)

        # check each returned index
        for i, index in enumerate(indices):
            # verify that the artist has a line and that the last item in the data series was not selected
            if event.artist.get_linestyle() is not None and index != len(datax)-1:
                # if so, append the next higher index
                indices = np.append(indices, indices[i]+1)

        # get the data corresponding to the lower and higher indices
        datax, datay = [datax[i] for i in indices], [datay[i] for i in indices]

        # get the mouse click location
        msx, msy = event.mouseevent.xdata, event.mouseevent.ydata

        # calculate the distance from the mouse click to the data
        dist = np.sqrt((np.array(datax)-msx)**2 + (np.array(datay)-msy)**2)

        # return the index corresponding to the smaller distance
        return indices[np.argmin(dist)]

class PickableAxesOptions(object):
    """
    An object to store options for PickableAxes for which the user has control.

    The attributes of a PickableAxesOptions object can be modified to adjust the
    settings for a particular axes. Alternatively, the class attributes can be modified
    to adjust the settings for all subsequently created PickableAxes, as the object
    attributes are set to the value of the class attributes upon initialization.

    Parameters
    ----------
    ax: matplotlib.axes._axes.Axes
        The axes for which the options correspond.
    """

    ANNOTATION_DATA = []
    """
    The column names from a parent object that will be displayed when a data point is selected.

    dtype: list(str)
    """

    ANNOTATION_PARAMS = {'xycoords': 'data',
                         'xytext': (10, 10),
                         'textcoords': 'offset points',
                         'fontsize': 8,
                         'bbox': {'boxstyle': 'round', 'fc': '0.8'},
                         'arrowprops': {'arrowstyle': '-|>'}}
    """
    Keywords arguments passed to the annotation box constructor when displaying data.

    dtype: dict{str: misc}
    """

    DRAGGABLE_ANNOTATIONS = True
    """
    Flag to allow the user to drag annotation boxes within a figure.

    dtype: bool
    """

    LINEWIDTH_DELTA = 2
    """
    Linewidth increment to indicate that a line has been selected.

    dtype: int
    """

    MARKERSIZE_DELTA = 6
    """
    Markersize delta to indicate that a data point has been selected.

    Note: not currently supported for scatter plots.

    dtype: int
    """

    PICKER = 5.
    """
    Picker setting for pickable artists. See https://matplotlib.org/users/event_handling.html.

    dtype: None, bool, float or function
    """

    def __init__(self, ax):
        self.ax = ax

        self.annotation_data       = self.ANNOTATION_DATA
        self.annotation_params     = self.ANNOTATION_PARAMS
        self.draggable_annotations = self.DRAGGABLE_ANNOTATIONS
        self.linewidth_delta       = self.LINEWIDTH_DELTA
        self.markersize_delta      = self.MARKERSIZE_DELTA
        self.picker                = self.PICKER

class _PickableArtistHandler(object):

    def __init__(self,
                 artist,
                 parent=None,
                 indices=None):
        self.artist = artist

        self.multiparent = False
        self.parent_indices = None
        self.parent = None
        self._store_parent(parent, indices)

        self.selected = False
        self.options = artist.axes.options

        self.annotations = []

        self._original_attributes = self._get_artist_attributes()
        self.selection_indicators = []

    def add_annotation(self, string, xy):
        annotation = self.artist.axes.annotate(string, xy, **self.options.annotation_params)
        if self.options.draggable_annotations:
            annotation.draggable()
        self.annotations.append(annotation)
        self.draw_idle()

    def add_selection_indicator(self, ind):
        x, y = self._get_data_coordinates(ind)
        attributes = self._selection_attributes
        # TODO: CLEAN THIS UP
        # TODO: FIGURE OUT HOW TO ADD INDICATOR FOR SCATTER PLOTS
        if 'linestyle' in attributes:
            del(attributes['linestyle'])
        if 'ls' in attributes:
            del(attributes['ls'])
        si = self.artist.axes.plot(x, y, linestyle=None, **attributes)
        self.selection_indicators += si
        self.draw_idle()

    def deselect(self, ind=None):
        raise NotImplementedError("This method must be overwritten by a subclass implemented for a specific type of" +
                                  "artist")

    def draw_idle(self):
        self.artist.figure.canvas.draw_idle()

    def flip_selection_status(self, ind=None):
        if self.selected:
            self.deselect(ind)
        else:
            self.select(ind)

    def remove_annotations(self):
        for annotation in self.annotations:
            annotation.remove()
        self.annotations = []
        self.draw_idle()

    def remove_selection_indicators(self):
        for si in self.selection_indicators:
            si.remove()
        self.selection_indicators = []
        self.draw_idle()

    def show_data(self, index, names=None):
        names = self.options.annotation_data if names is None else names
        data = self._get_parent_data(index=index, names=names)
        string = self._data_string(data)
        x, y = self._get_data_coordinates(index)
        self.add_annotation(string, (x, y))
        self.draw_idle()

    def select(self, ind=None):
        raise NotImplementedError("This method must be overwritten by a subclass implemented for a specific type of" +
                                  " artist")

    @property
    def _selection_attributes(self):
        raise NotImplementedError("This property must be overwritten by a subclass implemented for a specific type of" +
                                  " artist")

    @staticmethod
    def _data_string(data):
        s = ''
        nkeys = len(data.keys())
        for i, (name, value) in enumerate(data.items()):
            s += '%s: %s' % (name, str(value))
            if i != nkeys - 1:
                s += '\n'
        return s

    def _get_artist_attributes(self):
        return {}

    def _get_data_coordinates(self, ind):
        raise NotImplementedError("This method must be overwritten by a subclass implemented for a specific type of" +
                                  "artist")

    def _get_parent_data(self, index=None, names=None):
        names = self.options.annotation_data if names is None else names
        if self.multiparent:
            parent = self.parent[index]
            i = self.parent_indices[index]
            return {s: parent[s][i] for s in names}
        else:
            if index is None:
                return {s: np.array(self.parent[s]) for s in names}
            else:
                return {s: np.array(self.parent[s])[index] for s in names}

    def _store_parent(self, parent, indices=None):
        if any(isinstance(parent, o) for o in (list, tuple)):
            self.parent = parent
            self.parent_indices = indices
            self.multiparent = True
        else:
            self.parent = parent

class _PickableLine2DHandler(_PickableArtistHandler):

    def add_line_selection_indicator(self):
        attributes = self._selection_attributes
        self.artist.set_linewidth(attributes['lw'])
        self.draw_idle()

    def deselect(self, ind=None):
        self.remove_line_selection_indicator()
        self.remove_selection_indicators()
        self.remove_annotations()
        self.selected = False

    def remove_line_selection_indicator(self):
        lw = self._original_attributes['lw']
        self.artist.set_linewidth(lw)
        self.draw_idle()

    def select(self, ind=None):
        self.add_line_selection_indicator()
        if ind is not None:
            self.add_selection_indicator(ind)
            self.show_data(index=ind)
        self.selected = True

    @property
    def _selection_attributes(self):
        a = self._original_attributes.copy()
        a['lw'] = a['lw'] + self.options.linewidth_delta
        a['ms'] = a['ms'] + self.options.markersize_delta
        return a

    def _get_data_coordinates(self, ind):
        xdata, ydata = self.artist.get_data()
        if isinstance(ind, np.integer):
            return xdata[ind], ydata[ind]
        else:
            return np.array([xdata[i] for i in ind]), np.array([ydata[i] for i in ind])

    def _get_artist_attributes(self):
        return {'color': self.artist.get_color(),
                'ls': self.artist.get_ls(),
                'lw': self.artist.get_lw(),
                'marker': self.artist.get_marker(),
                'mec': self.artist.get_mec(),
                'mew': self.artist.get_mew(),
                'mfcalt': self.artist.get_mfcalt(),
                'ms': self.artist.get_ms()}

class _PickablePathCollectionHandler(_PickableArtistHandler):

    def deselect(self, ind=None):
        self.remove_selection_indicators()
        self.remove_annotations()
        self.selected = False

    def select(self, ind=None):
        if ind is not None:
            self.add_selection_indicator(ind)
            self.show_data(index=ind)
        self.selected = True

    @property
    def _selection_attributes(self):
        return {}

    def _get_artist_attributes(self):
        return {'edgecolor': self.artist.get_edgecolor(),
                'facecolor': self.artist.get_facecolor(),
                'fill': self.artist.get_fill(),
                'sizes': self.artist.get_sizes()}

    def _get_data_coordinates(self, ind):
        data = self.artist.get_offsets()
        if isinstance(ind, np.integer):
            return data[ind, 0], data[ind, 1]
        else:
            return np.array([data[i, 0] for i in ind]), np.array([data[i, 1] for i in ind])

register_projection(PickableAxes)


import numpy as np
from scipy.stats import norm
from stock import Stock

# source: https://github.com/jeromeku/Python-Financial-Tools/blob/master/capm.py

class CAPM(object):
    def __init__(self, risk_free, market, alpha=.05):
        self.risk_free = Stock(risk_free["ticker"], risk_free["date_range"]) if type(risk_free) is dict else Stock(
            risk_free)
        self.market = Stock(market["ticker"], market["date_range"]) if type(market) is dict else Stock(market)

        self.alpha, self.beta = {}, {}
        self.critical_value = norm.ppf(1 - alpha / 2.0)


import time
from random import randint
import matplotlib.pyplot as plt
import algorythms
import threading

threading.stack_size(2 ** 27)

q = 1
n = 10000
r = 1000000

T_fb = []
M_fb = []

T_d = []
M_d = []

def task(m_min, m_step, m_max):
    # creating data
    for m in range(m_min, m_max, m_step):
        arr_edges = []
        for _ in range(m):
            e = algorythms.Edge(randint(1, n), randint(1, n), randint(q, r))
            arr_edges.append(e)
        start_time = time.time()
        M_fb.append(m)
        # execute ford_bellman
        algorythms.ford_bellman(1, n, arr_edges)
        T_fb.append(time.time() - start_time)

        arr_pairs = [[] for _ in range(n)]
        for i in arr_edges:
            arr_pairs[i.startNode - 1].append([i.length, i.endNode])
        start_time = time.time()
        M_d.append(m)
        #  execute dijkstra
        algorythms.dijkstra(1, n, arr_pairs)
        T_d.append(time.time() - start_time)

plt.figure(figsize=(8, 8))
thread_a = threading.Thread(target=task(100000, 100000, 1000001))
thread_a.start()
plt.subplot(2, 2, 1)
plt.title("a) T(m) FB:")
plt.plot(T_fb, M_fb)
plt.subplot(2, 2, 2)
plt.title("a) T(m) D:")
plt.plot(T_d, M_d)
T_fb = []
M_fb = []
T_d = []
M_d = []
thread_b = threading.Thread(target=task(1000, 1000, 100001))
thread_b.start()
plt.subplot(2, 2, 3)
plt.title("b) T(m) FB:")
plt.plot(T_fb, M_fb)
plt.subplot(2, 2, 4)
plt.title("b) T(m) D:")
plt.plot(T_d, M_d)
plt.show()


## 10816. 숫자 카드 2 (01.04)
from collections import Counter
n = int(input())
card = list(map(int, input().split()))
card_count = Counter(card).most_common()
card_count.sort()

m = int(input())
find = list(map(int, input().split()))
answer = []

for f in find:
    flag = 0
    for c in card_count:
        if f == c[0]:
            answer.append(c[1])
            flag = 1
    if flag == 0:
        answer.append(0)

for a in answer:
    print(a, end = " ")


import sys
sys.stdin = open("수의 새로운 연산_input.txt")

t = int(input())

for case in range(1):
    a, b = map(int, input().split())
    print(a, b)
    n = 0
    if a >= b:
        n = int(a**(1/2))+1
    else:
        n = int(b**(1/2))+1
    print(n)
    arr = [[0 for _ in range(n+1)]for _ in range(n+1)]

    for i in range(1, n):
        num = i-1
        for j in range(1, n):
            arr[j][i] = num + i
            num += j

    for i in range(n):
        print(arr[i])

연습/D3-수의 새로운 연산.py

D3-수의 새로운 연산.py


#!/usr/local/bin/python

import sys

current_id = None
answers_length = []
question_length = 0

#input: id\t\isquestion\tlength

def get_average(l):
    if len(l) == 0:
        return 0
    else:
        return sum(l) / len(l)

for line in sys.stdin:
    data_mapped = line.strip().split("\t")
    if (len(data_mapped) != 3):
        continue

    this_id, this_type, this_length = data_mapped
    this_length = int(this_length)

    if current_id and current_id != this_id:

        print("{0}\t{1}\t{2}".format(current_id, question_length, get_average(answers_length)))
        answers_length = []
        question_length = 0

    current_id = this_id
    #question
    if this_type == "0":
        question_length = this_length
    #answer
    elif this_type == "1":
        answers_length.append(this_length)

if current_id:
    print("{0}\t{1}\t{2}".format(current_id, question_length, get_average(answers_length)))