"""
    PSPNet, implemented in PyTorch.
    Original paper: 'Pyramid Scene Parsing Network,' https://arxiv.org/abs/1612.01105.
"""

__all__ = ['PSPNet', 'pspnet_resnet50_voc', 'pspnet_resnet101_voc', 'pspnet_resnet50_ade20k']

import os
import torch.nn as nn
import torch.nn.functional as F
import torch.nn.init as init
from .common import conv1x1, conv1x1_block, conv3x3_block, Concurrent, Identity
from .resnet import resnet50, resnet101

class PyramidPoolingBranch(nn.Module):
    """
    Pyramid Pooling branch.

    Parameters:
    ----------
    in_channels : int
        Number of input channels.
    out_channels : int
        Number of output channels.
    output_size : int
        Target output size of the image.
    """
    def __init__(self,
                 in_channels,
                 out_channels,
                 output_size):
        super(PyramidPoolingBranch, self).__init__()
        self.pool = nn.AdaptiveAvgPool2d(output_size)
        self.conv = conv1x1_block(
            in_channels=in_channels,
            out_channels=out_channels)

    def forward(self, x):
        _, _, h, w = x.size()
        x = self.pool(x)
        x = self.conv(x)
        x = F.interpolate(x, size=(h, w), mode="bilinear", align_corners=True)
        return x

class PyramidPooling(nn.Module):
    """
    Pyramid Pooling module.

    Parameters:
    ----------
    in_channels : int
        Number of input channels.
    """
    def __init__(self,
                 in_channels):
        super(PyramidPooling, self).__init__()
        output_sizes = [1, 2, 3, 6]
        assert (len(output_sizes) == 4)
        assert (in_channels % 4 == 0)
        mid_channels = in_channels // 4

        self.branches = Concurrent()
        self.branches.add_module("branch1", Identity())
        for i, output_size in enumerate(output_sizes):
            self.branches.add_module("branch{}".format(i + 2), PyramidPoolingBranch(
                in_channels=in_channels,
                out_channels=mid_channels,
                output_size=output_size))

    def forward(self, x):
        x = self.branches(x)
        return x

class PSPNet(nn.Module):
    """
    PSPNet model from 'Pyramid Scene Parsing Network,' https://arxiv.org/abs/1612.01105.

    Parameters:
    ----------
    backbone : nn.Sequential
        Feature extractor.
    backbone_out_channels : int, default 2048
        Number of output channels form feature extractor.
    in_channels : int, default 3
        Number of input channels.
    in_size : tuple of two ints, default (224, 224)
        Spatial size of the expected input image.
    num_classes : int, default 21
        Number of segmentation classes.
    """
    def __init__(self,
                 backbone,
                 backbone_out_channels=2048,
                 in_channels=3,
                 in_size=(224, 224),
                 num_classes=21):
        super(PSPNet, self).__init__()
        assert (in_channels > 0)
        self.in_size = in_size
        self.num_classes = num_classes
        pool_out_channels = 2 * backbone_out_channels
        mid_channels = backbone_out_channels // 4

        self.backbone = backbone
        self.pool = PyramidPooling(in_channels=backbone_out_channels)
        self.conv1 = conv3x3_block(
            in_channels=pool_out_channels,
            out_channels=mid_channels)
        self.dropout = nn.Dropout2d(p=0.1, inplace=False)
        self.conv2 = conv1x1(
            in_channels=mid_channels,
            out_channels=num_classes)

        self._init_params()

    def _init_params(self):
        for name, module in self.named_modules():
            if isinstance(module, nn.Conv2d):
                init.kaiming_uniform_(module.weight)
                if module.bias is not None:
                    init.constant_(module.bias, 0)

    def forward(self, x):
        _, _, h, w = x.size()
        x = self.backbone(x)
        x = self.pool(x)
        x = self.conv1(x)
        x = self.dropout(x)
        x = self.conv2(x)
        x = F.interpolate(x, size=(h, w), mode="bilinear", align_corners=True)
        return x

def get_pspnet(backbone,
               num_classes,
               model_name=None,
               pretrained=False,
               root=os.path.join('~', '.torch', 'models'),
               **kwargs):
    """
    Create PSPNet model with specific parameters.

    Parameters:
    ----------
    backbone : nn.Sequential
        Feature extractor.
    num_classes : int
        Number of segmentation classes.
    model_name : str or None, default None
        Model name for loading pretrained model.
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.torch/models'
        Location for keeping the model parameters.
    """

    net = PSPNet(
        backbone=backbone,
        num_classes=num_classes,
        **kwargs)

    if pretrained:
        if (model_name is None) or (not model_name):
            raise ValueError("Parameter `model_name` should be properly initialized for loading pretrained model.")
        from .model_store import download_model
        download_model(
            net=net,
            model_name=model_name,
            local_model_store_dir_path=root)

    return net

def pspnet_resnet50_voc(pretrained_backbone=False, num_classes=21, **kwargs):
    """
    PSPNet model on the base of ResNet-50 for Pascal VOC from 'Pyramid Scene Parsing Network,'
    https://arxiv.org/abs/1612.01105.

    Parameters:
    ----------
    pretrained_backbone : bool, default False
        Whether to load the pretrained weights for feature extractor.
    num_classes : int, default 21
        Number of segmentation classes.
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.torch/models'
        Location for keeping the model parameters.
    """
    backbone = resnet50(pretrained=pretrained_backbone, dilated=True).features[:-1]
    return get_pspnet(backbone=backbone, num_classes=num_classes, model_name="pspnet_resnet50_voc", **kwargs)

def pspnet_resnet101_voc(pretrained_backbone=False, num_classes=21, **kwargs):
    """
    PSPNet model on the base of ResNet-101 for Pascal VOC from 'Pyramid Scene Parsing Network,'
    https://arxiv.org/abs/1612.01105.

    Parameters:
    ----------
    pretrained_backbone : bool, default False
        Whether to load the pretrained weights for feature extractor.
    num_classes : int, default 21
        Number of segmentation classes.
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.torch/models'
        Location for keeping the model parameters.
    """
    backbone = resnet101(pretrained=pretrained_backbone, dilated=True).features[:-1]
    return get_pspnet(backbone=backbone, num_classes=num_classes, model_name="pspnet_resnet101_voc", **kwargs)

def pspnet_resnet50_ade20k(pretrained_backbone=False, num_classes=150, **kwargs):
    """
    PSPNet model on the base of ResNet-50 for ADE20K from 'Pyramid Scene Parsing Network,'
    https://arxiv.org/abs/1612.01105.

    Parameters:
    ----------
    pretrained_backbone : bool, default False
        Whether to load the pretrained weights for feature extractor.
    num_classes : int, default 150
        Number of segmentation classes.
    pretrained : bool, default False
        Whether to load the pretrained weights for model.
    root : str, default '~/.torch/models'
        Location for keeping the model parameters.
    """
    backbone = resnet50(pretrained=pretrained_backbone, dilated=True).features[:-1]
    return get_pspnet(backbone=backbone, num_classes=num_classes, model_name="pspnet_resnet50_ade20k", **kwargs)

def _calc_width(net):
    import numpy as np
    net_params = filter(lambda p: p.requires_grad, net.parameters())
    weight_count = 0
    for param in net_params:
        weight_count += np.prod(param.size())
    return weight_count

def _test():
    import torch
    from torch.autograd import Variable

    pretrained = False

    models = [
        (pspnet_resnet50_voc, 21),
        (pspnet_resnet101_voc, 21),
        (pspnet_resnet50_ade20k, 150),
    ]

    for model, num_classes in models:

        net = model(pretrained=pretrained)

        # net.train()
        net.eval()
        weight_count = _calc_width(net)
        print("m={}, {}".format(model.__name__, weight_count))
        assert (model != pspnet_resnet50_voc or weight_count == 46592576)
        assert (model != pspnet_resnet101_voc or weight_count == 65584704)
        assert (model != pspnet_resnet50_ade20k or weight_count == 46658624)

        x = Variable(torch.randn(1, 3, 224, 224))
        y = net(x)
        y.sum().backward()
        assert ((y.size(0) == x.size(0)) and (y.size(1) == num_classes) and (y.size(2) == x.size(2)) and
                (y.size(3) == x.size(3)))

if __name__ == "__main__":
    _test()


from sys import exit
from my_library import writting_file, checkfile, zagprint, few_columns

# Просто выписывает все гены из списка.

#name_fgens='gens_spliceAI_sorted_concantenated.txt'
name_fgens = 'gens_dominant.txt'
zagprint(name_fgens)
mfile=open(name_fgens,'r')
#name_genom_file='genom.fa'
name_genom_file = 'gnomad_genome.txt'
genom=open(name_genom_file,'r')
#file_out=open('gens.txt','w')
#file_out = open('pax6.txt','w')
file_out = open('pax6_alt.txt','w')
file_er1=open('gens_splice_er.txt','w')
chm=[]
wrong_gens=0
num_gen=0
num_stgen=1
chg='chr1'
const_s='\n'
fl1=0
buk=''
for st in mfile:
    if fl1==0:
        fl1=1
        continue
    fl3=0
    num_stgen+=1
    stm=st.split('\t')
    ch='chr'+stm[1]
    name1=stm[0]
    #name2=stm[12]

    if not(ch in chm):
        chm.append(ch)

    strand=stm[2]
    start=int(stm[3])
    end=int(stm[4])
    num_st=start//50

    if start%50==0:
        ost_st=50
        num_st-=1
    else:
        ost_st=start%50

    # if (num_gen > num_st) and (ch == chg):
    #     genom.close()
    #     name_genom_file = 'genom.fa'
    #     genom = open(name_genom_file, 'r')
    #     num_gen=0
    while ((num_gen <= num_st) or not (ch == chg)):  # Пока положение не перевалит за cе И пока хромосома не равна нужной
        if fl3==1:
            break
        stg = genom.readline()[:-1]
        fl2 = 0
        if not ('>' in stg):
            num_gen += 1
        else:
            num_gen = 0
            fl2 = 1
            chg = stg.rstrip()[1:]
            print('{}'.format(ch), end=' ')

    if not((num_gen == num_st+1) and (ch == chg)): # this is wrong gens
        wrong_gens+=1
        continue

    pos=ost_st-1
    file_out.write('>{}\n'.format(name1))
    file_out.write('${}\t{}\t{}\t{}\t#{}\t{}\t{}\n'.format(ch,start,num_st,ost_st,num_gen,pos+1,str(num_gen*50+pos+1)))

    # if not(num_st==num_gen):
    #     file_er1.write('>{}\n'.format(name1))
    #     file_er1.write('${}\t{}\t{}\t{}\t#{}\t{}\t{}\n'.format(ch,start,num_st,ost_st,num_gen,pos+1,str(num_gen*50+pos+1)))
    pos_out=1
    tkolvo=end-start+1
    kolvo=0
    while (start <= end):
        if pos==50:
            pos=0
            stg = genom.readline()[:-1]
            if not('>' in stg):
                num_gen+=1
            else:
                num_gen=0
                fl2 = 1
                chg = stg.rstrip()[1:]
                print('{}'.format(ch), end=' ')
        try:
            buk=stg[pos]
        except IndexError:
            print('error')
            print(pos)
            print(stg)
            print(st[:-1])
            print(num_stgen)
            print(num_gen)
            print()
            file_out.write('&&\n')
            fl3 = 1
            break
            # if buk.upper=='N':
            #     file_out.write('\n')
            #     fl3=1
            #     break

        if pos_out==50:
            pos_out=1
            file_out.write('\n')
        file_out.write(buk.lower())
        kolvo+=1
        pos_out+=1
        pos += 1
        start+=1
    file_out.write('\n')
    #file_out.write('%t={}\tr={}\n'.format(str(tkolvo), str(kolvo)))

print(chm)
mfile.close()
genom.close()
file_out.close()
file_er1.close()
print('wrong_gens {}'.format(wrong_gens))


'''
runpod | serverless | rp_scale.py
Provides the functionality for scaling the runpod serverless worker.
'''

import asyncio
import typing

from runpod.serverless.modules.rp_logger import RunPodLogger
from .rp_job import get_job
from .worker_state import Jobs

log = RunPodLogger()
job_list = Jobs()

class JobScaler():
    """
    A class for automatically retrieving new jobs from the server and processing them concurrently.

    Attributes:
        server_url (str): The URL of the server to retrieve jobs from.
        max_concurrent_jobs (int): The maximum number of jobs to process concurrently.
        upscale_factor (float): The factor by which to upscale the job retrieval rate.
        downscale_factor (float): The factor by which to downscale the job retrieval rate.

    Methods:
        get_jobs() -> List[Dict]:
            Retrieves multiple jobs from the server in parallel using concurrent requests.

        upscale_rate() -> None:
            Upscales the job retrieval rate by adjusting the number of concurrent requests.

        downscale_rate() -> None:
            Downscales the job retrieval rate by adjusting the number of concurrent requests.

        rescale_request_rate() -> None:
            Rescales the job retrieval rate based on factors such as job queue availability
            and handler utilization.

    Usage example:
        job_scaler = JobScaler(config)

        # Retrieving multiple jobs in parallel
        jobs_list = job_scaler.get_jobs(session)

        # Upscaling the rate for faster job retrieval
        job_scaler.upscale_rate()

        # Downscaling the rate for more conservative job retrieval
        job_scaler.downscale_rate()

        # Rescaling based on the queue, availability, and other metrics
        job_scaler.rescale_request_rate()
    """

    # Scaling Constants
    CONCURRENCY_SCALE_FACTOR = 2
    AVAILABILITY_RATIO_THRESHOLD = 0.90
    INITIAL_CONCURRENT_REQUESTS = 1
    MAX_CONCURRENT_REQUESTS = 100
    MIN_CONCURRENT_REQUESTS = 1
    SLEEP_INTERVAL_SEC = 1

    def __init__(self, concurrency_controller: typing.Any):
        self.background_get_job_tasks = set()
        self.num_concurrent_get_job_requests = JobScaler.INITIAL_CONCURRENT_REQUESTS
        self.job_history = []
        self.concurrency_controller = concurrency_controller
        self._is_alive = True

    def is_alive(self):
        """
        Return whether the worker is alive or not.
        """
        return self._is_alive

    def kill_worker(self):
        """
        Whether to kill the worker.
        """
        self._is_alive = False

    def track_task(self, task):
        """
        Keep track of the task to avoid python garbage collection of the coroutine.
        """
        self.background_get_job_tasks.add(task)
        task.add_done_callback(self.background_get_job_tasks.discard)

    async def get_jobs(self, session):
        """
        Retrieve multiple jobs from the server in parallel using concurrent requests.

        Returns:
            List[Any]: A list of job data retrieved from the server.
        """
        while True:
            # Finish if the job_scale is not alive
            if not self.is_alive():
                break

            for _ in range(self.num_concurrent_get_job_requests):
                job = await get_job(session, retry=False)
                self.job_history.append(1 if job else 0)
                if job:
                    yield job

            # During the single processing scenario, wait for the job to finish processing.
            if self.concurrency_controller is None:
                # Create a copy of the background job tasks list to keep references to the tasks.
                job_tasks_copy = self.background_get_job_tasks.copy()
                if job_tasks_copy:
                    # Wait for the job tasks to finish processing before continuing.
                    await asyncio.wait(job_tasks_copy)
                # Exit the loop after processing a single job (since the handler is fully utilized).
                await asyncio.sleep(JobScaler.SLEEP_INTERVAL_SEC)
                break

            # We retrieve num_concurrent_get_job_requests jobs per second.
            await asyncio.sleep(JobScaler.SLEEP_INTERVAL_SEC)

            # Rescale the retrieval rate appropriately.
            self.rescale_request_rate()

            # Show logs
            log.info(
                f"Concurrent Get Jobs | The number of concurrent get_jobs is "
                f"{self.num_concurrent_get_job_requests}."
            )

    def upscale_rate(self) -> None:
        """
        Upscale the job retrieval rate by adjusting the number of concurrent requests.

        This method increases the number of concurrent requests to the server,
        effectively retrieving more jobs per unit of time.
        """
        self.num_concurrent_get_job_requests = min(
            self.num_concurrent_get_job_requests *
            JobScaler.CONCURRENCY_SCALE_FACTOR,
            JobScaler.MAX_CONCURRENT_REQUESTS
        )

    def downscale_rate(self) -> None:
        """
        Downscale the job retrieval rate by adjusting the number of concurrent requests.

        This method decreases the number of concurrent requests to the server,
        effectively retrieving fewer jobs per unit of time.
        """
        self.num_concurrent_get_job_requests = int(max(
            self.num_concurrent_get_job_requests // JobScaler.CONCURRENCY_SCALE_FACTOR,
            JobScaler.MIN_CONCURRENT_REQUESTS
        ))

    def rescale_request_rate(self) -> None:
        """
        Scale up or down the rate at which we are handling jobs from SLS.
        """
        # Compute the availability ratio of the job queue.
        availability_ratio = sum(self.job_history) / len(self.job_history)

        # If our worker is fully utilized or the SLS queue is throttling, reduce the job query rate.
        if self.concurrency_controller() is True:
            log.debug("Reducing job query rate due to full worker utilization.")

            self.downscale_rate()
        elif availability_ratio < 1 / JobScaler.CONCURRENCY_SCALE_FACTOR:
            log.debug(
                "Reducing job query rate due to low job queue availability.")

            self.downscale_rate()
        elif availability_ratio >= JobScaler.AVAILABILITY_RATIO_THRESHOLD:
            log.debug(
                "Increasing job query rate due to increased job queue availability.")

            self.upscale_rate()

        # Clear the job history
        self.job_history.clear()


"""Custom spawner for JupyterHub.
It extends the DockerSpawner with following features:
- additional fields in spawn screen for named servers (set cpu limit, additional environment variables, ...)
- put each spawned container into its own subnet to separate them from each other. This is needed to protect the 'Tools' part
    of our custom workspace container
"""

from dockerspawner import DockerSpawner

import docker
import docker.types
import docker.errors
from docker.utils import kwargs_from_env

import os
import subprocess
import socket
import ipaddress
from traitlets import default, Unicode, List
from tornado import gen
import psutil
import time
import re

from mlhubspawner import spawner_options, utils

# we create networks in the range of 172.33-255.0.0/24
# Docker by default uses the range 172.17-32.0.0, so we should be save using that range
INITIAL_CIDR_FIRST_OCTET = 172
INITIAL_CIDR_SECOND_OCTET = 33
INITIAL_CIDR = "{}.33.0.0/24".format(INITIAL_CIDR_FIRST_OCTET)

OPTION_SHM_SIZE = "shm_size"

def has_complete_network_information(network):
    """Convenient function to check whether the docker.Network object has all required properties.

    Args:
        network (docker.Network)

    Returns:
        bool: True if it has all properties, False otehrwise.
    """
    return network.attrs["IPAM"] and network.attrs["IPAM"]["Config"] \
        and len(network.attrs["IPAM"]["Config"]) > 0 \
        and network.attrs["IPAM"]["Config"][0]["Subnet"]

class MLHubDockerSpawner(DockerSpawner):
    """Provides the possibility to spawn docker containers with specific options, such as resource limits (CPU and Memory), Environment Variables, ..."""

    #hub_name = Unicode(config=True, help="Name of the hub container.")

    workspace_images = List(
        trait = Unicode(),
        default_value = [],
        config = True,
        help = "Pre-defined workspace images"
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.hub_name = utils.ENV_HUB_NAME
        self.default_labels = {utils.LABEL_MLHUB_ORIGIN: self.hub_name, utils.LABEL_MLHUB_USER: self.user.name, utils.LABEL_MLHUB_SERVER_NAME: self.name}
        # Get the MLHub container name to be used as the DNS name for the spawned workspaces, so they can connect to the Hub even if the container is
        # removed and restarted
        client = self.highlevel_docker_client

        # Connect MLHub to the existing workspace networks (in case of removing / recreation). By this, the hub can connect to the existing
        # workspaces and does not have to restart them.
        try:
            network = client.networks.get(self.network_name)
            self.connect_hub_to_network(network)
        except:
            pass

        # Get available resource information
        self.resource_information = {
            "cpu_count": psutil.cpu_count(),
            "memory_count_in_gb": round(psutil.virtual_memory().total/1024/1024/1024, 1),
            "gpu_count": self.get_gpu_info()
        }

    @property
    def highlevel_docker_client(self):
        """Create a highlevel docker client as 'self.client' is the low-level API client.

        Returns:
            docker.DockerClient
        """

        return utils.init_docker_client(self.client_kwargs, self.tls_config)

    @property
    def network_name(self):
        """
        self.network_name is used by DockerSpawner to connect the newly created container to the respective network
        """
        #return self.object_name
        return "{}-{}".format(self.hub_name, self.user.name)

    @default('options_form')
    def _options_form(self):
        """Return the spawner options screen"""

        # Only show spawner options for named servers (the default server should start with default values)
        if getattr(self, "name", "") == "":
            return ''

        return spawner_options.get_options_form_docker(self)

    def options_from_form(self, formdata):
        """Extract the passed form data into the self.user_options variable."""

        self.new_creating = True
        return spawner_options.options_from_form(self, formdata)

    def get_env(self):
        env = super().get_env()

        # Replace JupyterHub container id with the name for spawned workspaces, so that the workspaces can connect to the hub even if the hub was removed and recreated.
        # Otherwise, the workspaces would have the old container id that does not exist anymore in such a case.
        hostname_regex = re.compile("http(s)?://([a-zA-Z0-9]+):[0-9]{3,5}.*")
        jupyterhub_api_url = env.get('JUPYTERHUB_API_URL')
        if jupyterhub_api_url:
            hostname = hostname_regex.match(jupyterhub_api_url).group(2)
            env['JUPYTERHUB_API_URL'] = jupyterhub_api_url.replace(hostname, self.hub_name)
        jupyterhub_activity_url = env.get('JUPYTERHUB_ACTIVITY_URL')
        if jupyterhub_activity_url:
            hostname = hostname_regex.match(jupyterhub_activity_url).group(2)
            env['JUPYTERHUB_ACTIVITY_URL'] = jupyterhub_activity_url.replace(hostname, self.hub_name)

        if self.user_options.get('env'):
            env.update(self.user_options.get('env'))

        if self.user_options.get('gpus'):
            env['NVIDIA_VISIBLE_DEVICES'] = self.user_options.get('gpus')

        if self.user_options.get(utils.OPTION_CPU_LIMIT):
            env[utils.OPTION_MAX_NUM_THREADS] = self.user_options.get(utils.OPTION_CPU_LIMIT)

        env[utils.OPTION_SSH_JUMPHOST_TARGET] = self.object_name

        return env

    @gen.coroutine
    def start(self) -> (str, int):
        """Set custom configuration during start before calling the super.start method of Dockerspawner

        Returns:
            (str, int): container's ip address or '127.0.0.1', container's port
        """

        self.saved_user_options = self.user_options

        if self.user_options.get(utils.OPTION_IMAGE):
            self.image = self.user_options.get(utils.OPTION_IMAGE)

        extra_host_config = {}
        if self.user_options.get(utils.OPTION_CPU_LIMIT):
            # nano_cpus cannot be bigger than the number of CPUs of the machine (this method would currently not work in a cluster, as machines could be different than the machine where the runtime-manager and this code run.
            max_available_cpus = self.resource_information["cpu_count"]
            limited_cpus = min(
                int(self.user_options.get(utils.OPTION_CPU_LIMIT)), max_available_cpus)

            # the nano_cpu parameter of the Docker client expects an integer, not a float
            nano_cpus = int(limited_cpus * 1e9)
            extra_host_config['nano_cpus'] = nano_cpus
        if self.user_options.get(utils.OPTION_MEM_LIMIT):
            extra_host_config[utils.OPTION_MEM_LIMIT] = str(self.user_options.get(
                utils.OPTION_MEM_LIMIT)) + "gb"

        if self.user_options.get('is_mount_volume') == 'on':
            # {username} and {servername} will be automatically replaced by DockerSpawner with the right values as in template_namespace
            #volumeName = self.name_template.format(prefix=self.prefix)
            self.highlevel_docker_client.volumes.create(name=self.object_name, labels=self.default_labels)
            self.volumes = {self.object_name: "/workspace"}

        extra_create_kwargs = {}
        # set default label 'origin' to know for sure which containers where started via the hub
        extra_create_kwargs[utils.OPTION_LABELS] = self.default_labels
        if self.user_options.get(utils.OPTION_DAYS_TO_LIVE):
            days_to_live_in_seconds = int(self.user_options.get(utils.OPTION_DAYS_TO_LIVE)) * 24 * 60 * 60 # days * hours_per_day * minutes_per_hour * seconds_per_minute
            expiration_timestamp = time.time() + days_to_live_in_seconds
            extra_create_kwargs[utils.OPTION_LABELS][utils.LABEL_EXPIRATION_TIMESTAMP] =  str(expiration_timestamp)
        else:
            extra_create_kwargs[utils.OPTION_LABELS][utils.LABEL_EXPIRATION_TIMESTAMP] = str(0)

        if self.user_options.get(OPTION_SHM_SIZE):
            extra_host_config[OPTION_SHM_SIZE] = self.user_options.get('shm_size')

        if self.user_options.get('gpus'):
            extra_host_config['runtime'] = "nvidia"
            extra_create_kwargs[utils.OPTION_LABELS][utils.LABEL_NVIDIA_VISIBLE_DEVICES] = self.user_options.get('gpus')

        self.extra_host_config.update(extra_host_config)
        self.extra_create_kwargs.update(extra_create_kwargs)

        # Check whether the network still exists to which the container will try to connect
        try:
            self.highlevel_docker_client.networks.get(self.network_name)
        except docker.errors.NotFound:
            created_network = self.create_network(self.network_name)
            self.connect_hub_to_network(created_network)
        except docker.errors.APIError:
            self.log.error("Could not look up network {network_name}".format(network_name=self.network_name))

        # Delete existing container when it is created via the options_form UI (to make sure that not an existing container is re-used when you actually want to create a new one)
        # reset the flag afterwards to prevent the container from being removed when just stopped
        # Also make it deletable via the user_options (can be set via the POST API)
        if ((hasattr(self, 'new_creating') and self.new_creating == True)
            or self.user_options.get("update", False)):
            self.remove = True
        res = yield super().start()
        self.remove = False
        self.new_creating = False
        return res

    @gen.coroutine
    def create_object(self):
        created_network = None
        try:
            created_network = self.create_network(self.network_name)
            self.connect_hub_to_network(created_network)
        except:
            self.log.error(
                "Could not create the network {network_name} and, thus, cannot create the container."
                    .format(network_name=self.network_name)
            )
            return

        obj = yield super().create_object()
        return obj

    @gen.coroutine
    def remove_object(self):
        yield super().remove_object()

    def create_network(self, name):
        """Create a new network to put the new container into it.
        Containers are separated by networks to prevent them from seeing each other.
        Determine whether a new subnet has to be used. Otherwise, the default Docker subnet would be used
        and, as a result, the amount of networks that can be created is strongly limited.
        We create networks in the range of 172.33-255.0.0/24 whereby Docker by default uses the range 172.17-32.0.0
        See: https://stackoverflow.com/questions/41609998/how-to-increase-maximum-docker-network-on-one-server ; https://loomchild.net/2016/09/04/docker-can-create-only-31-networks-on-a-single-machine/

        Args:
            name (str): name of the network to be created

        Returns:
            docker.Network: the newly created network or the existing network with the given name

        """

        client = self.highlevel_docker_client
        networks = client.networks.list()
        highest_cidr = ipaddress.ip_network(INITIAL_CIDR)

        # determine subnet for the network to be created by finding the highest subnet so far.
        # E.g. when you have three subnets 172.33.1.0, 172.33.2.0, and 172.33.3.0, highest_cidr will be 172.33.3.0
        for network in networks:
            if network.name.lower() == name.lower():
                self.log.info("Network {} already exists".format(name))
                return network

            if (has_complete_network_information(network)):
                cidr = ipaddress.ip_network(
                    network.attrs["IPAM"]["Config"][0]["Subnet"])

                if cidr.network_address.packed[0] == INITIAL_CIDR_FIRST_OCTET \
                        and cidr.network_address.packed[1] >= INITIAL_CIDR_SECOND_OCTET:
                    if cidr > highest_cidr:
                        highest_cidr = cidr

        # take the highest cidr and add 256 bits, so that if the highest subnet was 172.33.2.0, the new subnet is 172.33.3.0
        next_cidr = ipaddress.ip_network(
            (highest_cidr.network_address + 256).exploded + "/24")
        if next_cidr.network_address.packed[0] > INITIAL_CIDR_FIRST_OCTET:
            raise Exception("No more possible subnet addresses exist")

        self.log.info("Create network {} with subnet {}".format(
            name, next_cidr.exploded))
        ipam_pool = docker.types.IPAMPool(subnet=next_cidr.exploded,
                                          gateway=(next_cidr.network_address + 1).exploded)
        ipam_config = docker.types.IPAMConfig(pool_configs=[ipam_pool])
        return client.networks.create(name, ipam=ipam_config, labels=self.default_labels)

    def connect_hub_to_network(self, network):
        try:
            network.connect(self.hub_name)
        except docker.errors.APIError as e:
            # In the case of an 403 error, JupyterHub is already in the network which is okay -> continue starting the new container
            # Example 403 error:
            # 403 Client Error: Forbidden ("endpoint with name mlhub already exists in network jupyter-admin")
            if e.status_code != 403:
                self.log.error(
                    "Could not connect mlhub to the network and, thus, cannot create the container.")
                return

    def get_workspace_config(self) -> str:
        return utils.get_workspace_config(self)

    def is_update_available(self):
        try:
            # compare the last parts of the images, so that also "mltooling/ml-workspace:0.8.7 = ml-workspace:0.8.7" would match
            config_image = self.image.split("/")[-1]
            workspace_image = self.highlevel_docker_client.containers.get(self.container_id).image.tags[0].split("/")[-1]

            return config_image != workspace_image
        except (docker.errors.NotFound, docker.errors.NullResource):
            return False

    def get_labels(self) -> dict:
        try:
            return self.highlevel_docker_client.containers.get(self.container_id).labels
        except:
            return {}

    # Override
    def template_namespace(self):
        template = super().template_namespace()
        if template["servername"] != "":
            template["servername"] = "-" + template["servername"]

        return template

    # get_state and load_state are functions used by Jupyterhub to save and load variables that shall be persisted even if the hub is removed and re-created
    # Override
    def get_state(self):
        state = super(MLHubDockerSpawner, self).get_state()
        state = utils.get_state(self, state)
        return state

    # Override
    def load_state(self, state):
        super(MLHubDockerSpawner, self).load_state(state)
        utils.load_state(self, state)

    def get_gpu_info(self) -> list:
        count_gpu = 0
        try:
            # NOTE: this approach currently only works for nvidia gpus.
            ps = subprocess.Popen(('find', '/proc/irq/', '-name', 'nvidia'), stdout=subprocess.PIPE)
            output = subprocess.check_output(('wc', '-l'), stdin=ps.stdout)
            ps.wait()
            count_gpu = int(output.decode("utf-8"))
        except:
            pass

        return count_gpu


"""
Test cases for the serializers
"""

import json
from datetime import datetime

import pytz
from dateutil import parser
from django.test import TestCase
from django.utils.six import BytesIO
from rest_framework.parsers import JSONParser
from rest_framework.renderers import JSONRenderer

from edx_notifications.data import NotificationMessage  # pylint: disable=unused-import
from edx_notifications.data import NotificationType
from edx_notifications.serializers import NotificationMessageSerializer

class SerializerTests(TestCase):
    """
    Go through all the test cases of the serializers.py
    """

    def test_message_serialization(self):
        """
        Test serialization/deserialization of a sample Notification Message
        """

        msg = NotificationMessage(
            id=1001,
            msg_type=NotificationType(
                name='edx_notifications.sample',
                renderer='foo.renderer',
            ),
            namespace='my-namespace',
            payload={
                'name1': 'val1',
                'name2': datetime.utcnow(),
            },
            deliver_no_earlier_than=datetime.utcnow(),
            created=datetime.utcnow(),
        )

        serializer = NotificationMessageSerializer(msg)
        json_data = JSONRenderer().render(serializer.data)

        # no deserialize the string and compare resulting objects
        stream = BytesIO(json_data)
        data = JSONParser().parse(stream)

        deserializer = NotificationMessageSerializer(data=data)
        self.assertTrue(deserializer.is_valid())

        # compare the original data object to our deserialized version
        # and make sure they are the same
        msg_payload = json.loads(deserializer.data['payload'])
        msg_output = NotificationMessage(
            id=deserializer.data['id'],
            msg_type=NotificationType(
                name=deserializer.data['msg_type']['name'],
                renderer=deserializer.data['msg_type']['renderer'],
            ),
            namespace=deserializer.data['namespace'],
            payload={
                'name1': msg_payload['name1'],
                'name2': msg_payload['name2'],
            },
            deliver_no_earlier_than=parser.parse(
                deserializer.data['deliver_no_earlier_than']
            ).replace(tzinfo=pytz.timezone('UTC')),
            created=parser.parse(deserializer.data['created']).replace(tzinfo=pytz.timezone('UTC')),
        )
        self.assertEqual(msg.namespace, msg_output.namespace)
        self.assertEqual(msg.msg_type, msg_output.msg_type)  # pylint: disable=maybe-no-member

        # now intentionally try to break it
        data['namespace'] = 'busted'
        data['msg_type']['name'] = 'not-same'

        deserializer = NotificationMessageSerializer(data=data)
        self.assertTrue(deserializer.is_valid())

        # compare the original data object to our deserialized version
        # and make sure they are not considered the same
        msg_payload = json.loads(deserializer.data['payload'])
        msg_output = NotificationMessage(
            id=deserializer.data['id'],
            msg_type=NotificationType(
                name=deserializer.data['msg_type']['name'],
                renderer=deserializer.data['msg_type']['renderer'],
            ),
            namespace=deserializer.data['namespace'],
            payload={
                'name1': msg_payload['name1'],
                'name2': msg_payload['name2'],
            },
            deliver_no_earlier_than=parser.parse(
                deserializer.data['deliver_no_earlier_than']
            ).replace(tzinfo=pytz.timezone('UTC')),
            created=parser.parse(deserializer.data['created']).replace(tzinfo=pytz.timezone('UTC')),
        )
        self.assertNotEqual(msg.namespace, msg_output.namespace)
        self.assertNotEqual(msg.msg_type, msg_output.msg_type)  # pylint: disable=maybe-no-member


import numpy as np
from tensorflow.keras.preprocessing.image import ImageDataGenerator # 전처리

train_datagen = ImageDataGenerator( # 이미지 데이터 제네레이터 정의
    rescale = 1./255,  # 부동소수점으로 계산 최소값 0 최대값 255, 0~1로 정규화
    horizontal_flip = True, # 수평 상하 반전(무작위)
    vertical_flip = True, #  수평 좌우 반전(무작위)
    width_shift_range = 0.1, # 0.1(10%)만큼 가로이동(무작위)
    height_shift_range = 0.1, # 0.1(10%)만큼 세로 이동(무작위)
    rotation_range = 5, # 이미지를 5도를 회전한다.(무작위)
    zoom_range = 1.2, # 약 20%까지 확대/축소(무작위)
    shear_range = 0.7, # 이미지를 한축 방향으로 변형시킨다. 지정이 안되어있으면 디폴트값 0(변환 없음)으로 된다.
    fill_mode= 'nearest', # 가장 가까운 픽셀 값을 사용하여 빈공간을 채운다.
)

test_datagen = ImageDataGenerator( # test 데이터는 변경 X
    rescale = 1./255,  # 부동소수점으로 계산 최소값 0 최대값 255, 0~1로 정규화
)

xy_train = train_datagen.flow_from_directory(
    'd:/study_data/_data/brain/train', # 가져올 데이터의 상위폴더까지만 지정 경로설정
    target_size = (200, 200), # 이미지 사이즈를 200 * 200으로 확대/축소를 한다. 사이즈를 동일하게 만드는과정
    batch_size = 5, # 한번에 처리할 수 있는 이미지 수를 지정한다.
    class_mode = 'binary', # 0과1만 된다. 수치화해서 만들어준다. 0,1,2같음
    color_mode = 'grayscale', # # 이미지의 색을 지정한다.
    shuffle = True, # 데이터를 섞는다.
) # Found 160 images belonging to 2 classes. 0과1의 2개의 클래스가 나온다.

xy_test = test_datagen.flow_from_directory(
    'd:/study_data/_data/brain/test', # 가져올 데이터의 상위폴더까지만 지정 경로설정
    target_size = (200, 200), # 이미지 사이즈를 200 * 200으로 확대/축소를 한다. 사이즈를 동일하게 만드는과정
    batch_size = 5, # 한번에 처리할 수 있는 이미지 수를 지정한다.
    class_mode = 'binary', # 0과1만 된다. 수치화해서 만들어준다. 0,1,2같음
    color_mode = 'grayscale', # 이미지의 색을 지정한다.
    shuffle = True, # 데이터를 섞는다.
) # Found 120 images belonging to 2 classes. 0과1의 2개의 클래스가 나온다.
# 이터레이터 값을 차례대로 꺼낼수있는 객체 값이 필요한 시점에서만 값을 만들어서 사용을 한다.(데이터 생성을 미룬다.) 메모리를 효율적으로 데이터 처리할 수 있다.
print(xy_train)
# <keras.preprocessing.image.DirectoryIterator object at 0x000001606C17D6A0>
print(xy_train[0])
# print(xy_train.shape) # error
# AttributeError: 'DirectoryIterator' object has no attribute 'shape'
print(len(xy_train)) # 32
print(len(xy_train[0])) # x값과 y값이 2개

print(xy_train[0][0]) # x 5개가 들어가있다.
print(xy_train[0][1]) # [0. 1. 0. 1. 1.]

print(xy_train[0][0].shape) # (5, 200, 200, 1)
print(xy_train[0][1].shape) # (5,)

print("################################################")
print(type(xy_train)) # <class 'keras.preprocessing.image.DirectoryIterator'>
print(type(xy_train[0])) # <class 'tuple'> 튜플 값 못바꿈
print(type(xy_train[0][0])) # <class 'numpy.ndarray'>
print(type(xy_train[0][1])) # <class 'numpy.ndarray'>


import sys
def welcome_Screen():
    """
    Print the logo and number of attempts.

    :param None
    :return: None
    :rtype: None
    """

    HANGMAN_GAME_LOGO = """
     __    __       ___      .__   __.   _______ .___  ___.      ___      .__   __.      _______      ___      .___  ___.  _______
    |  |  |  |     /   \     |  \ |  |  /  _____||   \/   |     /   \     |  \ |  |     /  _____|    /   \     |   \/   | |   ____|
    |  |__|  |    /  ^  \    |   \|  | |  |  __  |  \  /  |    /  ^  \    |   \|  |    |  |  __     /  ^  \    |  \  /  | |  |__
    |   __   |   /  /_\  \   |  . `  | |  | |_ | |  |\/|  |   /  /_\  \   |  . `  |    |  | |_ |   /  /_\  \   |  |\/|  | |   __|
    |  |  |  |  /  _____  \  |  |\   | |  |__| | |  |  |  |  /  _____  \  |  |\   |    |  |__| |  /  _____  \  |  |  |  | |  |____
    |__|  |__| /__/     \__\ |__| \__|  \______| |__|  |__| /__/     \__\ |__| \__|     \______| /__/     \__\ |__|  |__| |_______|
                                                                                """
    print(HANGMAN_GAME_LOGO)
    MAX_TRIES = 6
    print(f"you have {MAX_TRIES} guess")

def choose_word(file_path, index):
    """
    the function return the secret word for guessing.

    :param file_path: A string representing a path to a text file containing space-separated words
    :param index: Position of a particular word in the file
    :return: the secret word for guessing
    :rtype: str
    """
    # open the file at read mode and read the words from the file
    while True:  # check if user file_path correct
        try:
            with open(file_path, 'r') as file:
                words = file.read().split()
            # take the secret word
            while True:  # check if user index is correct
                try:
                    secret_word = words[(int(index) - 1) % len(words)]
                    return secret_word
                except ValueError:
                    print(f"sorry, {index} is not a corret index. Please try again!")
                    sys.exit()

        except:
            print(f"sorry, {file_path} is not a corret file name. Please try again!")
            sys.exit()

def print_hangman(num_of_tries):
    """Prints the value of the key given as paramter.

    :param num_of_tries: a key for the dict(HANGMAN_PHOTOS)
    :type num_of_tries: int
    :return: None
    """

    HANGMAN_PHOTOS = {
        1: """    x-------x""",
        2: """    x-------x
    |
    |
    |
    |
    |""",
        3: """    x-------x
    |       |
    |       0
    |
    |
    |""",
        4: """    x-------x
    |       |
    |       0
    |       |
    |
    |""",
        5: """    x-------x
    |       |
    |       0
    |      /|\\
    |
    |""",
        6: """    x-------x
    |       |
    |       0
    |      /|\\
    |      /
    |""",
        7: """    x-------x
    |       |
    |       0
    |      /|\\
    |      / \\
    |"""
    }
    hangman_status = HANGMAN_PHOTOS[num_of_tries]
    print(hangman_status)

def check_valid_input(letter_guessed, old_letters_guessed):
    """
    A Boolean function that accepts a character and a list of letters
    that the user has guessed previously. The function checks
    two things: the correctness of the input and whether it is legal
    to guess this letter (that is, the player has not guessed this letter before)
    and returns true or false accordingly.

    :param letter_guessed: character received from the user.
    :type letter_guessed: str
    :param old_letters_guessed: list contains the letters the player has guessed.
    :type old_letters_guessed: list
    :return: return True if it is a legal input, else return False
    :rtype: bool
    """
    # if the character is not valid return false
    if letter_guessed.isalpha() != True or len(letter_guessed) > 1:
        return False
    elif letter_guessed in old_letters_guessed: # if the character is not in the letters the player has guessed we return false
        return False
    else:
        return True

def try_update_letter_guessed(letter_guessed, old_letters_guessed):
    """
    The method checks if the character is correct
    and if it is correct and does not exist in
    the letters that the user guessed then it updates the list with
    the new character and returns true otherwise it returns false

    :param letter_guessed: character received from the user.
    :type letter_guessed: str
    :param old_letters_guessed: list contains the letters the player has guessed.
    :type old_letters_guessed: list
    :return: return True if it is a legal input, else return False
    :rtype: bool
    """
    # check if the input is valid
    if check_valid_input(letter_guessed, old_letters_guessed) == False:
        print('X')
        old_letters_guessed = ' -> '.join(sorted(old_letters_guessed))
        print(old_letters_guessed)
        return False
    else:
        old_letters_guessed.append(letter_guessed)
        return True

def show_hidden_word(secret_word, old_letters_guessed):
    """
    A function that returns a string consisting of letters and underscores.

    :param secret_word: word the user has to guess
    :type secret_word: str
    :param old_letters_guessed: list contains the letters the player has guessed.
    :type old_letters_guessed: str
    :return: reveal the secret word to the player in a lower-line structure
    :rtype: str
    """
    # we making the result string by loop all the letters in the secret word
    # and if the letter in the letters the user has guessed we add the letter to the result
    # and if not we and _ to the result
    result = ''
    for letter in secret_word:
        if letter in old_letters_guessed:
            result += letter + ' '
        else:
            result += '_ '
    return result

def check_win(secret_word, old_letters_guessed):
    """
    This is a boolean function that returns true if all the letters that make up the secret word
    are included in the list of letters that the user guessed. Otherwise, the function returns false.

    :param secret_word: word the user has to guess
    :param old_letters_guessed: list contains the letters the player has guessed.
    :type secret_word: str
    :type old_letters_guessed: list
    :return: true if all the letters that make up the secret word are included int the list of old_letters_guessed otherwise return false
    :rtype: bool
    """
    # looping all the letters in secret word if one of them not int the guessed word we return False otherwise we return True
    for letter in secret_word:
        if letter not in old_letters_guessed:
            return False
    return True

def main():

    # print the welcome screen
    welcome_Screen()
    wrong_guess = 0
    num_of_tries = 1
    old_letters_guessed = list()  # create an empty list for the beginning
    # take from user the file path and index
    file_path = input("Enter file path: ")
    index = input("Enter index: ")
    secret_word = choose_word(file_path, index)
    print("Let’s start!")
    print_hangman(num_of_tries)
    print("_ " * len(secret_word))
    # game loop
    while wrong_guess in range(6):
        # take user input
        guessed_letter = input("Guess a letter: ").lower()
        # the main logic of the game
        if try_update_letter_guessed(guessed_letter, old_letters_guessed):
            if guessed_letter not in secret_word:
                wrong_guess += 1
                num_of_tries += 1
                print(":(")
                print_hangman(num_of_tries)
                print(show_hidden_word(secret_word, old_letters_guessed))
            else:
                print(show_hidden_word(secret_word, old_letters_guessed))
                if check_win(secret_word, old_letters_guessed):
                    print("WIN")
                    break
    if wrong_guess == 6:
        if check_win(secret_word, old_letters_guessed):
            print("WIN")
        else:
            print("LOSE")

if __name__ == "__main__":
    main()


import math

class Point2D(object):

    def __init__(self, x, y):
        self.x = x
        self.y = y

def add(p1, p2):
    """

    :param p1: Point2D type
    :param p2: Point2D type
    :return:
    """
    return Point2D(p1.x + p2.x, p1.y + p2.y)

def sub(p1, p2):
    """

    :param p1: Point2D type
    :param p2: Point2D type
    :return:
    """
    return Point2D(p1.x - p2.x, p1.y - p2.y)

def multi_n(p1, n):
    """

    :param p1: Point2D type
    :param n: Point2D type
    :return:
    """
    return Point2D(p1.x * n, p1.y * n)

def multi(p1, p2):
    """

    :param p1: Point2D type
    :param p2: Point2D type
    :return:
    """
    return p1.x * p2.x + p1.y * p2.y

def expon(p1, p2):
    """

    :param p1: Point2D type
    :param p2: Point2D type
    :return:
    """
    return p1.x * p2.y - p1.y * p2.x

def compute_line(polygon, scale):
    """

    :param polygon: polygon
    :param scale: scale
    :return:
    """
    tem_polygon = []
    for index in range(len(polygon)):
        tem_polygon.append(sub(polygon[0 if index == len(polygon) - 1 else index + 1], polygon[index]))
    mid_polygon = []
    for index in range(len(tem_polygon)):
        mid_polygon.append(multi_n(tem_polygon[index], 1.0 / math.sqrt(multi(tem_polygon[index], tem_polygon[index]))))

    length = len(polygon)
    new_polygon = []
    for index in range(length):
        start_index = length - 1 if index == 0 else index - 1
        end_index = index
        sina = expon(mid_polygon[start_index], mid_polygon[end_index])
        lens = scale / sina
        vector = sub(mid_polygon[end_index], mid_polygon[start_index])
        point = add(polygon[index], multi_n(vector, lens))
        new_polygon.append(point)
    return new_polygon

def change_point(datas):
    """

    :param datas:
    :return:
    """
    polygon = []
    for data in datas:
        point = (float(data[0]), float(data[1]))
        polygon.append(point)
    return polygon

def equal_scale_polygon(polygon, scale):
    """

    :param polygon: polygon
    :param scale: scale
    :return:
    """
    if isinstance(polygon, str):
        polygon = [x.split(',') for x in polygon.split(';')]
    polygon = change_point(polygon)
    polygon = [Point2D(i[0], i[1]) for i in polygon]
    new_polygon = compute_line(polygon, scale)
    new_polygon = [(i.x, i.y) for i in new_polygon]
    return new_polygon


import re

# ----------------------------------------------------------------------------
# Private Functions
# ----------------------------------------------------------------------------

def _findFirst( pattern, src ):
    """
    A helper function that simplifies the logic of using regex to find
    the first match in a string.
    """

    results = re.findall( pattern, src )
    if len(results) > 0:
        return results[0]
    return None

# ----------------------------------------------------------------------------
# HtmlClipboardFormat Object
# ----------------------------------------------------------------------------

class HtmlClipboardFormat:
    """
    Encapsulates the conversation between the clipboard HTML
    format and standard HTML format.
    """

    # The 1.0 HTML clipboard header format.
    HEADER_FORMAT = \
        "Version:1.0\r\n" \
        "StartHTML:%(htmlStart)09d\r\n" \
        "EndHTML:%(htmlEnd)09d\r\n" \
        "StartFragment:%(fragmentStart)09d\r\n" \
        "EndFragment:%(fragmentEnd)09d\r\n" \
        "StartSelection:%(fragmentStart)09d\r\n" \
        "EndSelection:%(fragmentEnd)09d\r\n" \
        "SourceURL:Enso\r\n"

    # A generic HTML page.
    HTML_PAGE = \
        "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n" \
        "\n<title></title>\n" \
        "%s\n" \
        ""

    # These regexps find the character offsets of the fragment strings (see
    # below) from the HTML clipboard format header.
    START_RE = "StartFragment:(\d+)"
    END_RE = "EndFragment:(\d+)"

    # The Clipboard HTML format uses the following comment strings to mark
    # the beginning and end of the text fragment which represents the user's
    # actual selection; everything else is envelope.
    START_FRAG = ""
    END_FRAG   = ""

    def __init__( self, html ):
        """
        Initializes the class to represent html.
        """

        # Preconditions:
        assert( type( html ) == str )

        # The internal storage format is platonic unicode.
        self.html = html

    @classmethod
    def fromClipboardHtml( cls, clipboardHtml ):
        """
        Instantiates the class given a string containing the Win32 Html
        Clipboard format.  The given clipboardHtml is expected to be in
        utf-8 and is expected to contain the special start-fragment and
        end-fragment markers as defined in the class constants.  If it's
        not utf-8 or if it doesn't have the right delimiters, this function
        logs a warning message and creates an instance empty of text.
        """
        # Preconditions:
        #assert( type( clipboardHtml ) == str )

        try:
            html = clipboardHtml.decode( "utf-8" )
        except UnicodeDecodeError:
            # input can't be decoded from utf-8:
            logging.warn( "Non-Utf-8 string in fromClipboardHtml." )
            return cls( "" )

        start = _findFirst( cls.START_RE, clipboardHtml )
        end = _findFirst( cls.END_RE, clipboardHtml )

        if start and end:
            html = clipboardHtml[ int(start): int(end) ]
            html = html.decode( "utf-8" )
            return cls( html )
        else:
            # Start and end not found in input:
            logging.warn( "Missing delimiters in fromClipboardHtml." )
            return cls( "" )

    @classmethod
    def fromHtml( cls, html ):
        """
        Instantiates the class given a string containing plain Html.
        """
        # Preconditions:
        assert( isinstance( html, str ) )

        return cls( html )

    def toClipboardHtml( self ):
        """
        Returns the contents in the Win32 Html format.
        """

        return self._encodeHtmlFragment( self.html )

    def toHtml( self ):
        """
         Returns the contents in the plain Html format.
        """

        return self.html

    def _createHtmlPage( self, fragment ):
        """
        Takes an Html fragment and encloses it in a full Html page.
        """

        return self.HTML_PAGE % fragment

    def _encodeHtmlFragment(self, sourceHtml):
        """
        Join all our bits of information into a string formatted as per the
        clipboard HTML format spec.

        The return value of this function is a Python string
        encoded in UTF-8.
        """

        # Preconditions:
        assert( type( sourceHtml ) == str )

        # LONGTERM TODO: The above contract statement involving
        # .encode().decode() could have damaging performance
        # repercussions.

        # NOTE: Every time we construct a string, we must encode it to
        # UTF-8 *before* we do any position-sensitive operations on
        # it, such as taking its length or finding a substring
        # position.

        if "" in sourceHtml:
            htmlheader, fragment = sourceHtml.split( "" )
            fragment, footer = fragment.split( "" )
            htmlheader = htmlheader + ""
            footer = "" + footer
            fragment = "".join( [self.START_FRAG,
                                 fragment,
                                 self.END_FRAG] )
            html = "".join([ htmlheader, fragment, footer ])
        else:
            fragment = sourceHtml
            html = self._createHtmlPage( fragment )
        fragment = fragment.encode( "utf-8" )
        html = html.encode( "utf-8" )
        assert html == html.decode( "utf-8" ).encode( "utf-8" ), \
               "Encoding got out of whack in HtmlClipboardFormat."

        # How long is the header going to be?
        dummyHeader = self.HEADER_FORMAT % dict( htmlStart = 0,
                                                 htmlEnd   = 0,
                                                 fragmentStart = 0,
                                                 fragmentEnd = 0 )
        dummyHeader = dummyHeader.encode( "utf-8" )
        headerLen = len(dummyHeader)

        fragmentStart = html.find( fragment )
        fragmentEnd   = fragmentStart + len( fragment )

        positions = dict( htmlStart     = headerLen,
                          htmlEnd       = headerLen + len(html),
                          fragmentStart = headerLen + fragmentStart,
                          fragmentEnd   = headerLen + fragmentEnd )
        header = self.HEADER_FORMAT % positions
        header = header.encode( "utf-8" )

        result = header + html

        # Postconditions:
        #assert( type( result ) == str )
        assert( result == result.decode( "utf-8" ).encode( "utf-8" ) )
        return result


import os
import cv2
import time
from threading import Thread
from flask import Flask, request
from waitress import serve
import numpy as np

app = Flask(__name__, static_url_path='', static_folder='.')

# Dictionary of filter functions
# that can be applied to video
# frame.
filter_funcs = {}

# Dictionary of filter options
# to apply to video frames
# Keys should match keys of
# the `filter_funcs` dictionary
# Values will pass to these functions
# as a `value` parameter
image_filters = {
    "colors": ""
}

def main():
    # Define a dictionary of filtering functions
    # (You can add more different functions here)
    filter_funcs["colors"] = colors
    filter_funcs["blur"] = blur
    filter_funcs["binary"] = binary
    filter_funcs["brightness"] = brightness
    filter_funcs["contrast"] = contrast
    filter_funcs["edges"] = edges
    filter_funcs["only_face"] = only_face

    # Run camera capturing and filtering
    # in a background thread
    thread = Thread(target=run_camera)
    thread.start()

    # Run web service in a main thread
    serve(app, port=8080)

@app.route('/')
def root():
    return app.send_static_file('index.html')

@app.route('/filter', methods=["POST"])
def filter():
    """
    Receives a dictionary of filters
    that user setup on the frontend
    in a POST request and set it to
    the `image_filters` global variable.
    """
    global image_filters
    image_filters = request.json
    return "OK"

def run_camera():
    """
    Function captures each video frame from web camera
    as OpenCV image in a background thread,
    applies defined filters to it using
    defined filter functions and saves modified
    frame to the `frame.jpg` file
    """

    # Connect to the default web camera
    source = cv2.VideoCapture(0)

    # capture frames from web camera every 30 ms
    while True:
        has_frame, frame = source.read()
        if not has_frame:
            break
        # go over all enabled image filters that came
        # from frontend and call appropriate filter
        # functions to apply them to current
        # frame
        for filter_func, value in image_filters.items():
            frame = filter_funcs[filter_func](frame, value)
        # save modified frame to the image file
        cv2.imwrite("temp.jpg", frame)
        os.rename("temp.jpg", "frame.jpg")
        time.sleep(0.03)

def colors(frame, colors):
    """
    Color channels filter. Used to apply
    specified color channels to the frame
    :param frame: Current video frame
    :param colors: Color channels string, that can contain "r", "g" and "b" symbols
    :return: Modified frame
    """

    # if no channels, return grayscale image
    if len(colors) == 0:
        return cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # get color channels of original frame
    b, g, r = cv2.split(frame)

    # create an empty black image
    empty = np.zeros(r.shape, dtype=np.uint8)
    res_channels = [empty, empty, empty]

    # Add only color channels, that
    # specified in the `colors` string
    # to the source video frame
    if str(colors).find("r") != -1:
        res_channels[2] = r
    if str(colors).find("g") != -1:
        res_channels[1] = g
    if str(colors).find("b") != -1:
        res_channels[0] = b
    frame = cv2.merge(res_channels)
    return frame

def blur(frame, value):
    """
    Blur filter
    :param frame: Current video frame
    :param value: Blur kernel size
    :return: Modified frame
    """
    if value == 0:
        return frame
    return cv2.blur(frame, (value, value))

def binary(frame, value):
    """
    Black and white threshold filter
    :param frame: Current video frame
    :param value: Threshold value
    :return: Modified frame
    """
    if value == 0:
        return frame
    if len(frame.shape) == 3:
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    (_, result) = cv2.threshold(frame, value, 255, cv2.THRESH_BINARY)
    return result

def brightness(frame, value):
    """
    Brightness filter
    :param frame: Current video frame
    :param value: Brightness value
    :return: Modified frame
    """
    to_add = np.ones(frame.shape, dtype=np.uint8)*abs(value)
    if value < 0:
        return cv2.subtract(frame, np.uint8(to_add))
    else:
        return cv2.add(frame, np.uint8(to_add))

def contrast(frame, value):
    """
    Contrast filter
    :param frame: Current video frame
    :param value: Contrast value
    :return: Modified frame
    """
    to_add = np.ones(frame.shape, dtype=np.float64)*value
    return np.uint8(np.clip(cv2.multiply(np.float64(frame), to_add),0,255))

def edges(frame, value):
    """
    Canny edge detector filter
    :param frame: Current video frame
    :param value: unused
    :return:
    """
    return cv2.Canny(frame, 80, 150)

def only_face(frame, value):
    """
    Function uses neural network to
    detect all faces on the frame,
    select the bounding box of first
    face and crop the frame using this
    bounding box. Finally, the frame contains
    only detected face, if the face detected
    """
    net = cv2.dnn.readNetFromCaffe("deploy.prototxt", "res10_300x300_ssd_iter_140000_fp16.caffemodel")
    # Model parameters
    in_width = 300
    in_height = 300
    mean = [104, 117, 123]
    conf_threshold = 0.7

    frame_height = frame.shape[0]
    frame_width = frame.shape[1]

    # prepare input
    blob = cv2.dnn.blobFromImage(frame, 1.0, (in_width, in_height), mean, swapRB=False, crop=False)
    net.setInput(blob)

    # run model
    detections = net.forward()

    # process the output
    for i in range(detections.shape[2]):
        confidence = detections[0, 0, i, 2]
        if confidence > conf_threshold:
            x_left = int(detections[0, 0, i, 3] * frame_width)
            y_top = int(detections[0, 0, i, 4] * frame_height)
            x_right = int(detections[0, 0, i, 5] * frame_width)
            y_bottom = int(detections[0, 0, i, 6] * frame_height)
            return frame[y_top:y_bottom, x_left:x_right]
    return frame

main()


from flask import Flask, render_template, jsonify, request
from os import environ
from helper.flask_cors import add_cors_headers

app = Flask(__name__)
app.after_request(add_cors_headers)

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

if __name__ == '__main__':
    app.run(port = int(environ.get("PORT", 5000)))


from datetime import datetime

from sqlalchemy.orm import joinedload
from sqlalchemy import and_

from database.db import session
from database.models import Student, Teacher, ContactPerson

def get_students():
    students = session.query(Student).options(joinedload('teachers')).all()
    for s in students:
        print(vars(s))
        print(f"{[f'id: {teacher.id} first_name: {teacher.first_name}' for teacher in s.teachers]}")

def get_students_join():
    students = session.query(Student).join('teachers').all()
    for s in students:
        print(vars(s))
        print(f"{[f'id: {teacher.id} first_name: {teacher.first_name}' for teacher in s.teachers]}")

def get_students_all():
    students = session.query(Student).options(joinedload(Student.teachers), joinedload(Student.contacts)).all()
    for s in students:
        print(vars(s))
        print(f"{[f'id: {teacher.id} first_name: {teacher.first_name}' for teacher in s.teachers]}")
        print(f"{[f'id: {contact.id} first_name: {contact.first_name}' for contact in s.contacts]}")

def get_teachers():
    teachers = session.query(Teacher).options(joinedload('students')).all()
    for t in teachers:
        print(vars(t))
        print(f"{[f'id: {student.id} first_name: {student.first_name}' for student in t.students]}")

# WHERE start_work > 1234 AND start_work < 3456
def get_teachers_filter():
    teachers = session.query(Teacher).options(joinedload('students')).filter(and_(
        Teacher.start_work > datetime(year=2021, month=6, day=1),
        Teacher.start_work < datetime(year=2021, month=12, day=31)
    )).all()
    for t in teachers:
        print(vars(t))
        print(f"{[f'id: {student.id} first_name: {student.first_name}' for student in t.students]}")

if __name__ == '__main__':
    # get_students()
    # get_teachers()
    # get_students_join()
    # get_teachers_filter()
    get_students_all()


import io
from flask import Flask, render_template, Response
import processamento
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas

app = Flask(__name__)

@app.route('/')
def home():
    describe = processamento.getDescribe()
    head = processamento.getDataHead(10)
    data = [describe, head]

    return render_template("dashboard.html", dados=data)

@app.route('/user')
def user():
    return render_template("user.html")

@app.route('/plot.png')
def plot_png():
    fig = processamento.create_bar()
    output = io.BytesIO()
    FigureCanvas(fig).print_png(output)
    return Response(output.getvalue(), mimetype='image/png')

app.run(port=5400, debug=True)


from tests.base_testcases import ExtendedTestCase
import core
import exceptions

import unittest
import os

class TestPrimitive(ExtendedTestCase):
    """Basic test cases."""

    def test_absolute_truth_and_meaning(self):
        truth = True
        self.assertTrue(truth)

    def test_import_of_module(self):
        primitive = core._TestingPrimitive()

        flag = primitive.verify_import_tester()

        self.assertTrue(flag)

    def test_raising_root_exceptions(self):
        import validator
        root_exception = exceptions.NextGenError
        primitive = core._TestingPrimitive()

        with self.assertRaises(root_exception):
            primitive.raise_package_error()

class TestGlobals(ExtendedTestCase):

    def test_has_global_for_ini_path(self):
        self.assertHasAttr(obj=core, attrname="CORE_SETTINGS_FILENAME")

    def test_ini_path_is_to_a_file(self):
        path = core.CORE_SETTINGS_FILENAME

        self.assertTrue(os.path.isfile(path),
                        msg=f"path:{repr(path)} does not lead to a file.")

if __name__ == '__main__':
    unittest.main()


import cv2
import matplotlib.pyplot as plt
from pypot import vrep
from pypot.creatures import PoppyErgoJr
import random as r
from math import pi
from math import sqrt
from time import sleep

#C'était donné au début j'sais pas a quoi ça sert
#img=poppy.camera.frame
#plt.imshow(cv2.cvtColor(img.cv2.COLOR_BGR2RGB))

# Fermeture des connexion en entrant dans le programme afin d'éviter les bugs
vrep.close_all_connections()
poppy = PoppyErgoJr(simulator='vrep', scene='poppy_ergo_jr_holder.ttt', camera='dummy')

def showpos():
    print(poppy.m1)
    print(poppy.m2)
    print(poppy.m3)
    print(poppy.m4)
    print(poppy.m5)
    print(poppy.m6)

def default():
    poppy.m1.goal_position = 0
    poppy.m2.goal_position = 0
    poppy.m3.goal_position = 0
    poppy.m4.goal_position = 0
    poppy.m5.goal_position = 0
    poppy.m6.goal_position = 0

# def closeall():
#     poppy.stop_simulation()
#     vrep.close_all_connections()

def setfly(x,y,z,r,nbfly):
    points = []
    for i in range(0, nbfly):
        factor = np.random.uniform(0.3,1)
        ir = r * factor
        itheta = np.arccos(np.random.uniform(-1,1))
        iphi = np.random.uniform(0,2*np.pi)
        ix = x + ir * np.sin(itheta) * np.cos(iphi)
        iy = y + ir * np.sin(itheta) * np.sin(iphi)
        iz = abs(z + ir * np.cos(itheta))
        points.append((ix,iy,iz))
    return points

def translategraph(all_pos):
    # Passage de arr = [[x1,y1,z1],[x2,y2,z2]] a arr [[x1,x2],[y1,y2],[z1,z2]]
    arr = [[],[],[]]
    y = 0
    while y < len(all_pos):
        arr[0].append(all_pos[y][0])
        arr[1].append(all_pos[y][1])
        arr[2].append(all_pos[y][2])
        y += 1
    return arr

def getactualpos():
    # Récupération de la position du robot
    pos = poppy.chain.end_effector
    actualpos = [[pos[0],pos[1],pos[2]]]
    return actualpos

def old(init_pos, all_pos):
    dist = []
    for i in all_pos:
        dist.append([sqrt(((init_pos[0] - i[0]) ** 2) + ((init_pos[1] - i[1]) ** 2)+((init_pos[2] - i[2]) ** 2)), i])
    dist.sort()
    print(dist)
    nearest = dist[0]
    return nearest

def sortbynearest(arr,sort_final):
    sort = []
    l = len(arr[1][0])
    pos_min = 0
    if 0 < l:
        i = 0
        while i < l:
            # Calcul de la norme des vecteurs
            sort.append([sqrt(((arr[0][0] - arr[1][0][i]) ** 2) + ((arr[0][1] - arr[1][1][i]) ** 2)+((arr[0][2] - arr[1][2][i]) ** 2)), i])
            i += 1

        sort.sort()
        pos_min = sort[0][1]
        # enregistrement des coordonées les plus proches sous la forme [x,y,x]
        arr.insert(0,[arr[1][0][pos_min], arr[1][1][pos_min], arr[1][2][pos_min]])
        sort_final.append(arr[0])
        arr.pop(1)
        # supression des coordonées du vecteur le plus proche
        arr[1][0].pop(pos_min)
        arr[1][1].pop(pos_min)
        arr[1][2].pop(pos_min)
        # Récursivité
        sortbynearest(arr,sort_final)

    else:
        return sort_final

def creategraph(xyz):
    x = xyz[0]
    y = xyz[1]
    z = xyz[2]
    fig = plt.figure()
    ax = plt.gca(projection='3d')
    ax.plot(x, y, z)

def creategraph2D(xy):
    x = xy[0]
    y = xy[1]
    fig, ax = plt.subplots()
    ax.scatter(x,y)
    plt.show()

def moove(pos):
    x = 0
    for i in pos:
        x = x + 1
        print("")
        print(x)
        print(i)
        # Récupération des angles des moteurs en rad
        angles = poppy.chain.inverse_kinematics(i)
        print(angles)
        # Traduction de l'angle de m1 de radian a degré
        print(angles[1]*(180/pi))
        poppy.m1.goto_position(angles[1]*(180/pi),2)
        poppy.m2.goto_position(angles[2]*(180/pi),2)
        poppy.m3.goto_position(angles[3]*(180/pi),2)
        poppy.m4.goto_position(angles[4]*(180/pi),2)
        poppy.m5.goto_position(angles[5]*(180/pi),2)
        poppy.m6.goto_position(angles[6]*(180/pi),2)
        sleep(2)

def main():
    fly = setfly(0,0,0,0.2,10)
    fly = translategraph(fly)
    init_pos = getactualpos()
    init_pos.append(fly)
    sort_final = []
    fly = sortbynearest(init_pos,sort_final)
    path = translategraph(sort_final)

    print(sort_final)
    print("")

    creategraph(path)
    plt.show()

    moove(sort_final)

def rotate():
    i = 0
    graph = [[],[]]
    while i < 180:
        print(i)
        poppy.m1.goto_position(i,5,wait=True)
        graph[0].append(poppy.chain.end_effector[0])
        graph[1].append(poppy.chain.end_effector[1])
        poppy.m1.goto_position(i+180,5,wait=True)
        graph[0].append(poppy.chain.end_effector[0])
        graph[1].append(poppy.chain.end_effector[1])
        i = i + 15

    creategraph2D(graph)

# Fonction de test afin de vérifier la position dans le plan(x,y) de la pince
# rotate()

# Fonction principale permettant de créer les mouches aléatoirement et mettre en marche le robot
main()

# sleep(4)

# Fermeture de la simulation et de la connexion
poppy.stop_simulation()
vrep.close_all_connections()


import numpy as np
from regli.regli import bisect_interval
from regli import Regli
from astropy.table import Table, Column, vstack
from .isochrone_interp import isoc_interp, isoc_linterp

# ######################## #
# to evaluate [M/H] from Z #
# ######################## #

# parsec
def eval_mh_parsec(Z):
    ZXsun = 0.0207
    Y=0.2485+1.78*Z
    X = 1-Y-Z
    MH = np.log10(Z/X)-np.log10(ZXsun)
    return MH

# mist
def eval_zx_mist(Z):
    Yp = 0.249
    Ypsun = 0.2703
    Zpsun = 0.0142
    Y = Yp + (Ypsun-Yp)/Zpsun*Z
    X = 1-Y-Z
    return np.log10(Z/X)

def eval_mh_mist(Z):
    Zpsun = 0.0142
    return eval_zx_mist(Z)-eval_zx_mist(Zpsun)

# combined
def eval_mh(Z, model="parsec"):
    if model == "parsec":
        return eval_mh_parsec(Z)
    elif model == "mist":
        return eval_mh_mist(Z)
    else:
        raise ValueError("@IsochroneSet: invalid model!")

# ######################## #
# isochrone grid
# ######################## #

class IsochroneGrid:
    def __init__(self, isoc_lgage, isoc_mhini, isocs, model=None, Zsun=0.0152):
        """isocs should be a list of astropy.table.Table / Isochrone instances
        """
        # assert same length
        n_isocs = len(isocs)
        assert len(isoc_lgage) == n_isocs
        assert len(isoc_mhini) == n_isocs

        # self.isocs = isocs
        self.grid_lgage = np.unique(isoc_lgage)             # grid of lg(age)
        self.grid_mhini = np.unique(isoc_mhini)             # grid of [M/H]ini
        self.r = Regli(self.grid_lgage, self.grid_mhini)
        self.ind_dict = self.r.ind_dict

        # sort isocs
        print("@IsochroneGrid: sorting isocs ...")
        isocs_sorted = []
        i_isocs = []
        lgage_sorted = []
        mhini_sorted = []
        for _lgage, _mhini in self.r.flats:
            d_isoc = np.abs(isoc_lgage - _lgage) + np.abs(isoc_mhini - _mhini)
            i_isoc = np.argmin(d_isoc)
            # print(i_isoc, d_isoc[i_isoc])
            i_isocs.append(i_isoc)
            isocs_sorted.append(isocs[i_isoc])
            lgage_sorted.append(isoc_lgage[i_isoc])
            mhini_sorted.append(isoc_mhini[i_isoc])

        # flat [lgage, mhini, isocs]
        self.lgage = np.array(lgage_sorted)
        self.mhini = np.array(mhini_sorted)
        self.set_isocs(np.array(isocs_sorted))

        self.Zsun = Zsun
        self.post_proc(model=model, Zsun=Zsun)

        self.delta_ready = False

    def __repr__(self):
        s = ("==============================================================\n"
             "* IsochroneGrid [N_isoc={}   N_tot={}]\n"
             "* lg(Age)   grid[{}]: {}\n"
             "* [M/H]ini  grid[{}]: {}\n"
             "==============================================================\n"
             "Column names:\n"
             "{}\n"
             "==============================================================\n"
             ).format(
            len(self.isocs), np.sum([len(_) for _ in self]),
            len(self.grid_lgage), self.grid_lgage,
            len(self.grid_mhini), self.grid_mhini,
            self.colnames)
        return s

    @staticmethod
    def add_column(tbl, col, name=None):
        if name is None:
            add_column_safely(tbl, col)
        else:
            add_column_safely(tbl, Column(col, name))
        return

    @property
    def colnames(self):
        return self.isocs[0].colnames

    def set_isocs(self, isocs):
        self.isocs = isocs

    def get_a_isoc(self, lgage, mhini):
        """ return the closest isoc via [logAge, [M/H]]"""
        d_isoc = np.abs(self.lgage - lgage) + np.abs(self.mhini - mhini)
        i_isoc = np.argmin(d_isoc)
        return self.isocs[i_isoc]

    def post_proc(self, model=None, Zsun=0.0152):
        """ post-processing of isochrone

        Parameters
        ----------
        model:
            {None | "parsec" | "mist"}

        """
        if model is None:
            pass

        elif model == "parsec":
            print("@post_proc: processing PARSEC isochrones ...")
            for isoc in self.isocs:
                _lgmini = Column(np.log10(isoc["Mini"]), name="_lgmini")
                _mhini = Column(eval_mh_parsec(isoc["Zini"]), name="_mhini")
                _lgage  = Column(isoc["logAge"], name="_lgage")
                add_columns_safely(isoc, (_lgmini, _lgage, _mhini))
            self.model = model

        elif model == "mist":
            print("@post_proc: processing MIST isochrones ...")
            for isoc in self.isocs:
                _lgmini = Column(np.log10(isoc["initial_mass"]), name="_lgmini")
                _mhini = Column(isoc["[Fe/H]_init"], name="_mhini")
                _lgage = Column(isoc["log10_isochrone_age_yr"], name="_lgage")
                add_columns_safely(isoc, (_lgmini, _lgage, _mhini))
            self.model = model

        else:
            raise ValueError("@Isochrone: model *{}* unknown!".format(model))

    def __getitem__(self, item):
        return self.isocs[item]

    def isoc_linterp(self, restrictions=(('logG', 0.01), ('logTe', 0.01)),
                     interp_colnames=('logG', 'logTe'), sampling_factor=1.0,
                     sampling_mode="linear", Mini='Mini',
                     n_jobs=-1, verbose=10):
        if interp_colnames == "all":
            interp_colnames = self.colnames

        from joblib import Parallel, delayed
        isoc_interp_ = Parallel(n_jobs=n_jobs, verbose=verbose)(
            delayed(isoc_linterp)(isoc, restrictions=restrictions,
                                  sampling_factor=sampling_factor,
                                  sampling_mode=sampling_mode,
                                  interp_colnames=interp_colnames,
                                  Mini=Mini) for isoc in self.isocs)

        return IsochroneGrid(self.lgage, self.mhini, isoc_interp_)

    def vstack(self):
        return vstack(tuple(self.isocs))

    def make_delta(self):
        # [d_lgage, d_mhini, d_mini]
        _d_lgage = make_delta(self.grid_lgage, "log10")
        _d_mhini = make_delta(self.grid_mhini, "linear")
        print("@make_delta: setting deltas for isochrones ...")
        for (i_lgage, i_mhini), i_isoc in self.r.ind_dict.items():
            n_pts = len(self.isocs[i_isoc])
            self.add_column(self.isocs[i_isoc],
                            np.ones((n_pts,), float) * _d_lgage[i_lgage],
                            "_d_age")
            self.add_column(self.isocs[i_isoc],
                            np.ones((n_pts,), float) * _d_mhini[i_mhini],
                            "_d_mhini")
            self.add_column(self.isocs[i_isoc],
                            make_delta(self.isocs[i_isoc]["_lgmini"], "log10"),
                            "_d_mini")
        self.delta_ready = True

    def make_prior_sb(self, func_prior=None, qs=["logTe", "logG"]):
        if not self.delta_ready:
            raise ValueError("@IsochroneGrid: delta is not ready!")
        else:
            if func_prior is None:
                from berliner.utils.imf import imf

                def func_prior(mhini, lgage, lgmini):
                    return imf(10 ** lgmini, kind="salpeter")

            # stack isochrones
            isoc_stacked = self.vstack()
            # evaluate function prior / [IMF in the simplest case]
            w = func_prior(isoc_stacked["_lgage"], isoc_stacked["_mhini"],
                           isoc_stacked["_lgmini"])
            # d_volume
            dv = isoc_stacked["_d_age"] * isoc_stacked["_d_mhini"] * \
                 isoc_stacked["_d_mini"]

            return np.array([isoc_stacked[q] for q in qs]).T, np.array(w*dv)

    # for histogram
    @staticmethod
    def edge_to_center(edge):
        return np.array(edge[:-1]+np.diff(edge))

    @staticmethod
    def edges_to_centers(edges):
        return [np.array(edge[:-1]+np.diff(edge)) for edge in edges]

    @staticmethod
    def center_to_edge(center):
        pass

    @staticmethod
    def centers_to_edges(centers):
        pass

# for table manipulations
def add_column_safely(t, col):
    if col.name in t.colnames:
        t[col.name] = col.data
    else:
        t.add_column(col)
    return

def add_columns_safely(t, cols):
    for col in cols:
        add_column_safely(t, col)
    return

# for isochrone delta
def make_delta(x, scale="linear", loose=True):
    if scale == "linear":
        if loose:
            xedges = np.concatenate(([1.5 * x[0] - 0.5 * x[1]],
                                     x[:-1] + np.diff(x) / 2.,
                                     [1.5 * x[-1] - 0.5 * x[-2]]))
        else:
            xedges = np.concatenate(
                ([x[0]], x[:-1] + np.diff(x) / 2., [x[-1]]))
        return np.diff(xedges)
    elif scale == "log10":
        x = 10 ** x
        if loose:
            xedges = np.concatenate(([1.5 * x[0] - 0.5 * x[1]],
                                     x[:-1] + np.diff(x) / 2.,
                                     [1.5 * x[-1] - 0.5 * x[-2]]))
        else:
            xedges = np.concatenate(
                ([x[0]], x[:-1] + np.diff(x) / 2., [x[-1]]))
        return np.diff(xedges)


import re
import sys
import os
import os.path
import json
import time
import os,shutil
from pathlib import Path
import logging

'''检查标签和图片文件是否对应'''

def check_image_label(image_dir, label_file):
    '''根据label文件，检查图片文件是否存在'''
    file_object = open(label_file, 'r')
    success_count = 0
    failure_count = 0
    try:
        for line in file_object:
            billiards_and_picture_name = line.rstrip('\n').split(" ")
            billiards_picture_name = billiards_and_picture_name[2]   #第三个，图片文件名
            picture_name = os.path.join(image_dir, billiards_picture_name + '.bmp')
            my_file = Path(picture_name)
            if not my_file.exists():# 指定的文件存在
                failure_count = failure_count + 1
                logger.error('%s文件不存在' % my_file)
            else:
                success_count = success_count + 1
    finally:
        file_object.close()

    return success_count, failure_count

def  check_filename(root_path):
    # 0为directory_count，1为directory_succ_count，2为directory_fail_count,3为success_count，4为failure_count
    result = [0,0,0,0,0]
    success_count, failure_count, directory_count, directory_succ_count, directory_fail_count  = 0, 0, 0, 0, 0
    new_label_file = ''
    for dirpath, dirnames, filenames in os.walk(root_path):
        if '1' in dirnames:
            image_dir = os.path.join(dirpath, '1')
            rec_dir = os.path.join(dirpath, 'rec')
            directory_count = directory_count +1
            if not os.path.exists(os.path.join(rec_dir, 'revised.txt')):
                logger.info("revised.txt或者revise.txt文件不存在，请查看%s目录" % rec_dir)
                directory_fail_count + directory_fail_count + 1
                continue
            else: #遍历score文件和1目录
                label_file = os.path.join(rec_dir, 'revised.txt')
                succ_count, fail_count = check_image_label(image_dir, label_file)
                success_count = success_count + succ_count
                failure_count = failure_count + fail_count
                directory_succ_count = directory_succ_count + 1
    result =  directory_count, directory_succ_count, directory_fail_count, success_count, failure_count
    return result

def main():
    # 要拷贝数据的根目录
    #root_path = "/home/zealens/dyq/datas/train1/"
    root_path = "/media/zealens/TX2Data/dyq/datas/train/20200314-1000-Train"
    # root_path = "E:\\coco_bill\\20200203-mijiqiu"

    result = check_filename(root_path)
    logger.info('数据检查完成，共完成%d个目录，成功%d个，失败%d个' % (result[0], result[1], result[2]))
    logger.info('共完成图片检查%d张，失败%d个' % (result[3], result[4]))

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    logger = logging.getLogger(os.path.basename(sys.argv[0]).split(".")[0])
    main()


import bs4
from urllib.request import urlopen as uReq
from bs4 import BeautifulSoup as soup

my_url= 'https://www.imdb.com/search/title/?release_date=2017&sort=num_votes,desc&page=1'

uClient = uReq(my_url)
page_html = uClient.read()
uClient.close()
page_soup = soup(page_html, "html.parser")
movie_containers = page_soup.find_all('div', class_ = 'lister-item mode-advanced')
filename = "filmovi.txt"
import io
with io.open(filename, 'w',encoding="utf-8") as f:
    first_movie = movie_containers [0]
    for first_movie in movie_containers:
        name= first_movie.h3.a.text
        year = first_movie.h3.find('span',class_='lister-item-year').text
        imdb=first_movie.strong.text
        vote = first_movie.find('span', attrs={'name':'nv'})['data-value']
        print("name " + name)
        print("year " + year)
        print("imdb " + imdb)
        print("votes " + vote)
        f.write(name + "," + year + ","+ imdb + ","+ vote + "\n")

    f.close()


from typing import Callable

import numpy as np
import pandas as pd
from athena.src.core.services.optimizer import Optimizer
from pypfopt import HRPOpt
from pypfopt.risk_models import risk_matrix

class HRP(Optimizer):

    """

                                            Hierarchical Risk Parity

        Hierarchical Risk Parity is a novel portfolio optimization method developed by Marcos Lopez de Prado. It works
    differently when compared to the Efficient Frontier based method. However the principle of finding an optimal
    combination of risk and financial return is still the same.

    The algorithm works roughly as follows:

        1. From a universe of assets, form a distance matrix based on the correlation of the assets;
        2. Using this distance matrix, cluster the assets into a tree via hierarchical clustering;
        3. Within each branch of the tree, form the minimum variance portfolio (normally between just two assets);
        4. Iterate over each level, optimally combining the mini-portfolios at each node.

    The advantages of this are that it does not require the inversion of the covariance matrix as with traditional
    mean-variance optimization, and seems to produce diverse portfolios that perform well out of sample.

    In this implementation there a few parameters that can be tweaked when doing some parameters optimization via simulations
    and backtesting. They being:

        covariance_function: The algorithm for calculating the covariance matrix of the assets.

                    Implemented options: "sample_cov", "semicovariance", "exp_cov", "ledoit_wolf", "ledoit_wolf_constant_variance",
                                         "ledoit_wolf_single_factor", "ledoit_wolf_constant_correlation", "oracle_approximating".

        linkage_method: The algorithm that is used to created the hierarchical clustering tree.

                    Implemented options: "single", "complete", "average", "weighted", "centroid", "median", "ward".

    """

    historical_prices: pd.DataFrame
    hrp: HRPOpt
    covariance_function: str
    linkage_method: str

    def __init__(
        self,
        historical_prices: pd.DataFrame,
        covariance_function: str,
        linkage_method: str,
    ) -> None:
        self.linkage_method = linkage_method
        self.historical_prices = historical_prices.dropna(how="any")
        self.covariance_function = covariance_function
        self.hrp = self._optimize()

    def _get_covariance(self) -> pd.DataFrame:
        covariance = risk_matrix(
            self.historical_prices, method=self.covariance_function
        )
        covariance = self._fix_covariance_matrix(covariance=covariance)

        return covariance

    @staticmethod
    def _fix_covariance_matrix(covariance: pd.DataFrame) -> pd.DataFrame:
        covariance = covariance.replace(0, np.nan)

        for column in covariance.columns:
            values = covariance[column]
            num_nan = values.isna().sum()

            if num_nan >= len(values) - 1:
                covariance = covariance.drop(column, axis=1)
                covariance = covariance.drop(column, axis=0)

        return covariance

    def _optimize(self) -> HRPOpt:
        covariance = self._get_covariance()

        if len(covariance.columns) == 1:  # When there is only one asset
            hrp = pd.DataFrame(
                [1.0],
                columns=covariance.columns,
                index=[self.historical_prices.index[-1]],
            )

        else:
            hrp = HRPOpt(cov_matrix=covariance)
            hrp.optimize(linkage_method=self.linkage_method)

        return hrp

    def get_weights(self) -> pd.DataFrame:
        if type(self.hrp) == pd.DataFrame:
            weights = self.hrp

        else:
            weights = self.hrp.clean_weights(cutoff=0.01, rounding=3)

            num_tickers = len(weights.keys())
            date = self.historical_prices.index[-1]

            weights = pd.DataFrame(
                np.array(list(weights.values())).reshape((1, num_tickers)),
                columns=weights.keys(),
                index=[date],
            )

        return weights

def hrp_optimizer(df: pd.DataFrame, parameters: dict) -> Callable:
    covariance_function = parameters.get("covariance_function", None)
    linkage_method = parameters.get("linkage_method", None)
    prices = df["Close"]

    hrp = HRP(
        historical_prices=prices,
        covariance_function=covariance_function,
        linkage_method=linkage_method,
    )

    return hrp


"""
Building
========

The building module contains functions related to building acoustics.

"""
import numpy as np

def rw_curve(tl):
    """
    Calculate the curve of :math:`Rw` from a NumPy array `tl` with third
    octave data between 100 Hz and 3.15 kHz.

    :param tl: Transmission Loss

    """
    ref_curve = np.array([0, 3, 6, 9, 12, 15, 18, 19, 20, 21, 22, 23, 23, 23, 23, 23])
    residuals = 0
    while residuals > -32:
        ref_curve += 1
        diff = tl - ref_curve
        residuals = np.sum(np.clip(diff, np.min(diff), 0))
    ref_curve -= 1
    return ref_curve

def rw(tl):
    """
    Calculate :math:`R_W` from a NumPy array `tl` with third octave data
    between 100 Hz and 3.15 kHz.

    :param tl: Transmission Loss
    """
    return rw_curve(tl)[7]

def rw_c(tl):
    """
    Calculate :math:`R_W + C` from a NumPy array `tl` with third octave data
    between 100 Hz and 3.15 kHz.

    :param tl: Transmission Loss
    """
    k = np.array([-29, -26, -23, -21, -19, -17, -15, -13, -12, -11, -10, -9, -9, -9, -9, -9])
    a = -10 * np.log10(np.sum(10**((k - tl) / 10)))
    return a

def rw_ctr(tl):
    """
    Calculate :math:`R_W + C_{tr}` from a NumPy array `tl` with third octave
    data between 100 Hz and 3.15 kHz.

    :param tl: Transmission Loss
    """
    k_tr = np.array([-20, -20, -18, -16, -15, -14, -13, -12, -11, -9, -8, -9, -10, -11, -13, -15])
    a_tr = -10 * np.log10(np.sum(10**((k_tr - tl) / 10)))
    return a_tr

def stc_curve(tl):
    """
    Calculate the Sound Transmission Class (STC) curve from a NumPy array `tl`
    with third octave data between 125 Hz and 4 kHz.

    :param tl: Transmission Loss
    """
    ref_curve = np.array([0, 3, 6, 9, 12, 15, 16, 17, 18, 19, 20, 20, 20, 20, 20, 20])
    top_curve = ref_curve
    res_sum = 0
    while True:
        diff = tl - top_curve
        residuals = np.clip(diff, np.min(diff), 0)
        res_sum = np.sum(residuals)
        if res_sum < -32:
            if np.any(residuals > -8):
                top_curve -= 1
                break
        top_curve += 1
    return top_curve

def stc(tl):
    """
    Calculate the Sound Transmission Class (STC) from a NumPy array `tl` with
    third octave data between 125 Hz and 4 kHz.

    :param tl: Transmission Loss
    """
    return stc_curve(tl)[6]

def mass_law(freq, vol_density, thickness, theta=0, c=343, rho0=1.225):
    """ Calculate transmission loss according to mass law.

    :param freq: Frequency of interest in Hz.
    :type freq: `float` or `NumPy array`
    :param vol_density: Volumetric density of material in [kg/m^3].
    :type vol_density: `float`
    :param thickness: Thickness of wall.
    :type thickness: `float`
    :param theta: Angle of incidence in degrees. Default value is `0` (normal incidence).
    :type theta: `float`
    :param c: Speed of sound in [m/s].
    :type c: `float`
    :param rho0: Density of air in kg/m^3.
    :type rho0: `float`
    """
    rad_freq = 2.0 * np.pi * freq
    surface_density = vol_density * thickness
    theta_rad = np.deg2rad(theta)
    a = rad_freq * surface_density * np.cos(theta_rad) / (2 * rho0 * c)
    tl_theta = 10 * np.log10(1 + a**2)
    return tl_theta

__all__ = ['rw_curve', 'rw', 'rw_c', 'rw_ctr', 'stc_curve', 'stc', 'mass_law']


# 2. Закодируйте любую строку по алгоритму Хаффмана.

import heapq
from collections import Counter
from collections import namedtuple

class Node(namedtuple("Node", ["left", "right"])):
    def walk(self, code, acc):
        self.left.walk(code, acc + "0")
        self.right.walk(code, acc + "1")

class Leaf(namedtuple("Leaf", ["char"])):
    def walk(self, code, acc):
        code[self.char] = acc or "0"

def huffman_encode(s):
    h = []
    for ch, freq in Counter(s).items():
        h.append((freq, len(h), Leaf(ch)))
    heapq.heapify(h)
    count = len(h)

    while len(h) > 1:
        freq1, _count1, left = heapq.heappop(h)
        freq2, _count2, right = heapq.heappop(h)

        heapq.heappush(h, (freq1 + freq2, count, Node(left, right)))
        count += 1

    code = {}
    if h:
        [(_freq, _count, root)] = h
        root.walk(code, "")
    return code

def result(s: str):
    code = huffman_encode(s)
    encoded = "".join(code[ch] for ch in s)
    return f'Закодированная строка: {encoded}'

string = input('Введите строку латинскими буквами: ')
print(result(string))


import numpy as np
from . import _fastmath_ext

__all__ = ['inv2', 'inv3']

def inv3(matrices):
    if matrices.shape[-2:] != (3, 3):
        raise ValueError("Can only invert 3x3 matrices")
    Ts = matrices.reshape((-1, 3, 3))
    Qs = _fastmath_ext.inv3(Ts)
    return Qs.reshape(matrices.shape).astype(matrices.dtype)

def inv2(matrices):
    if matrices.shape[-2:] != (2, 2):
        raise ValueError("Can only invert 2x2 matrices")
    Ts = matrices.reshape((-1, 2, 2))
    Qs = _fastmath_ext.inv2(Ts)
    return Qs.reshape(matrices.shape)


import pywhatkit  # To make searches on Yt
import random  # For the random number game and jokes
import webbrowser  # To make urls of news and gmail
import playsound  # Plays background song when a joke is said
import time  # For some time break

name = 'Ankit'
while True:

    print('')
    print(f'Google Assistant: How can I help you {name}?\n')

    tasks = [

        '1. play songs',
        '2. surf news',
        '3. random jokes',
        '4. show last emails',
        '5. random number choosing game',
        '6. Change my name',
    ]

    for task in tasks:
        print(task)

    print('\n')  # For a line break

    print('Enter the task number')
    work = input(f"What's on your mind {name}?: ")
    print('\n')  # Line break

    if work == '1':
        print(f'What do you want to listen {name}? \n')
        song_list = [
            '1: Phao - 2 phut hon',
            '2: how you like that',
            '3: shape of you',
            '4: despacito\n'
        ]
        for songs in song_list:
            print(songs)

        print('Type the number of the song you want to play, type (0) for random song selection')

        try:
            search = int(input('Type the number of the song: '))
            if search == 0:
                random_song = random.choice(song_list)
                pywhatkit.playonyt(random_song)

            elif search == 1:
                pywhatkit.playonyt('2 phut hon(kiaz remix)')

            elif search == 2:
                pywhatkit.playonyt('how you like that blackpink')

            elif search == 3:
                pywhatkit.playonyt('shape of you official')

            elif search == 4:
                pywhatkit.playonyt('despacito official')

            else:
                print('Song number invalid or not found!')
                last_search = input(
                    'Type the name of the song you want to listen: ')
                pywhatkit.playonyt(last_search)
        except ValueError:
            print('You entered invalid  input')
            last_search = input(
                'Type the name of the song you want to listen: ')
            pywhatkit.playonyt(last_search)

    # Open news
    elif work == '2':
        webbrowser.open('https://www.cnet.com/news/')

    # Tell a joke
    elif work == '3':
        jokes = [
            'The Problem With Atoms \nQ: Why can’t you trust atoms?\nA: They make up everything.',
            'Q. What is the biggest lie in the entire universe?\nA. "I have read and agree to the Terms & Conditions."',
            'Q: Why was the cell phone wearing glasses?\nA: It lost its contacts.',
            'You know you are texting too much when....you say LOL in real life, instead of just laughing.',
        ]

        selected_joke = random.choices(jokes)

        for joke in selected_joke:
            print(joke)
            time.sleep(2)
            playsound.playsound(r'laugh.mp3')

    # Open email
    elif work == '4':
        webbrowser.open('https://mail.google.com/mail/u/0/#inbox')

    # Number guessing game
    elif work == '5':

        secret_number = random.randint(1, 10)  # Setting the secret number

        guess_count = 0
        guess_limits = 3
        tries = 3

        # Code Below!
        print("Guess a secret number from 1 to 10")

        try:
            while guess_count < guess_limits:
                print(f'You have {tries} tries left')
                guess = int(input("Guess: \n"))

                if guess > 10 or guess < 1:
                    print(
                        f"The number {guess} you guessed is in Invalid range")

                if guess == secret_number:
                    print('You won')
                    print("Maybe due to luck?")
                    break

                elif guess_count >= 2:
                    print("Out of chances, You lose!")
                    print("The secret number was " + str(secret_number))
                    break
                guess_count += 1
                tries -= 1

        except ValueError:
            print("Integers are only allowed!")

    # To change the name
    elif work == '6':
        name2 = input('Enter your name, you want me to call you?: ')
        sure = input(
            f'Do you want to change your name to -- {name2} -- Yes or No?: ')

        if sure == 'yes' or sure == 'Yes' or sure == 'YES':
            print('Your name is confirmed!')
            name = name2

        elif sure == 'no' or sure == 'NO' or sure == 'No':
            print('Ok! Not changing your name')
        else:
            print('A error occured while changing your name! Try again')
    else:
        print('Google Assistant: Task Number not found')