import math
import copy

import torch
import torch.nn.functional as F
from torch import nn

from util import segment_ops
from util.misc import (NestedTensor, nested_tensor_from_tensor_list,
                       accuracy, get_world_size,
                       is_dist_avail_and_initialized, inverse_sigmoid)
from models.matcher import build_matcher
from models.position_encoding import build_position_encoding
from .custom_loss import sigmoid_focal_loss
from .transformer import build_deformable_transformer
from opts import cfg

if not cfg.disable_cuda:
    from models.ops.roi_align import ROIAlign

def _get_clones(module, N):
    return nn.ModuleList([copy.deepcopy(module) for i in range(N)])

def get_norm(norm_type, dim, num_groups=None):
    if norm_type == 'gn':
        assert num_groups is not None, 'num_groups must be specified'
        return nn.GroupNorm(num_groups, dim)
    elif norm_type == 'bn':
        return nn.BatchNorm1d(dim)
    else:
        raise NotImplementedError

class TadTR(nn.Module):
    """ This is the TadTR module that performs temporal action detection """

    def __init__(self, position_embedding, transformer, num_classes, num_queries, aux_loss=True, with_segment_refine=True, with_act_reg=True):
        """ Initializes the model.
        Parameters:
            backbone: torch module of the backbone to be used. See backbone.py
            transformer: torch module of the transformer architecture. See deformable_transformer.py
            num_classes: number of action classes
            num_queries: number of action queries, ie detection slot. This is the maximal number of actions
                         TadTR can detect in a single video.
            aux_loss: True if auxiliary decoding losses (loss at each decoder layer) are to be used.
            with_segment_refine: iterative segment refinement
        """
        super().__init__()
        self.num_queries = num_queries
        self.transformer = transformer
        hidden_dim = transformer.d_model
        self.class_embed = nn.Linear(hidden_dim, num_classes)
        self.segment_embed = MLP(hidden_dim, hidden_dim, 2, 3)
        self.query_embed = nn.Embedding(num_queries, hidden_dim*2)

        self.input_proj = nn.ModuleList([
            nn.Sequential(
                nn.Conv1d(2048, hidden_dim, kernel_size=1),
                nn.GroupNorm(32, hidden_dim),
            )])
        # self.backbone = backbone
        self.position_embedding = position_embedding
        self.aux_loss = aux_loss
        self.with_segment_refine = with_segment_refine
        self.with_act_reg = with_act_reg

        prior_prob = 0.01
        bias_value = -math.log((1 - prior_prob) / prior_prob)
        self.class_embed.bias.data = torch.ones(num_classes) * bias_value
        nn.init.constant_(self.segment_embed.layers[-1].weight.data, 0)
        nn.init.constant_(self.segment_embed.layers[-1].bias.data, 0)
        for proj in self.input_proj:
            nn.init.xavier_uniform_(proj[0].weight, gain=1)
            nn.init.constant_(proj[0].bias, 0)

        num_pred = transformer.decoder.num_layers
        if with_segment_refine:
            self.class_embed = _get_clones(self.class_embed, num_pred)
            self.segment_embed = _get_clones(self.segment_embed, num_pred)
            nn.init.constant_(
                self.segment_embed[0].layers[-1].bias.data[1:], -2.0)
            # hack implementation for segment refinement
            self.transformer.decoder.segment_embed = self.segment_embed
        else:
            nn.init.constant_(
                self.segment_embed.layers[-1].bias.data[1:], -2.0)
            self.class_embed = nn.ModuleList(
                [self.class_embed for _ in range(num_pred)])
            self.segment_embed = nn.ModuleList(
                [self.segment_embed for _ in range(num_pred)])
            self.transformer.decoder.segment_embed = None

        if with_act_reg:
            # RoIAlign params
            self.roi_size = 16
            self.roi_scale = 0
            self.roi_extractor = ROIAlign(self.roi_size, self.roi_scale)
            self.actionness_pred = nn.Sequential(
                nn.Linear(self.roi_size * hidden_dim, hidden_dim),
                nn.ReLU(inplace=True),
                nn.Linear(hidden_dim, hidden_dim),
                nn.ReLU(inplace=True),
                nn.Linear(hidden_dim, 1),
                nn.Sigmoid()
            )

    def _to_roi_align_format(self, rois, T, scale_factor=1):
        '''Convert RoIs to RoIAlign format.
        Params:
            RoIs: normalized segments coordinates, shape (batch_size, num_segments, 4)
            T: length of the video feature sequence
        '''
        # transform to absolute axis
        B, N = rois.shape[:2]
        rois_center = rois[:, :, 0:1]
        rois_size = rois[:, :, 1:2] * scale_factor
        rois_abs = torch.cat(
            (rois_center - rois_size/2, rois_center + rois_size/2), dim=2) * T
        # expand the RoIs
        rois_abs = torch.clamp(rois_abs, min=0, max=T)  # (N, T, 2)
        # add batch index
        batch_ind = torch.arange(0, B).view((B, 1, 1)).to(rois_abs.device)
        batch_ind = batch_ind.repeat(1, N, 1)
        rois_abs = torch.cat((batch_ind, rois_abs), dim=2)
        # NOTE: stop gradient here to stablize training
        return rois_abs.view((B*N, 3)).detach()

    def forward(self, samples):
        """ The forward expects a NestedTensor, which consists of:
               - samples.tensors: batched images, of shape [batch_size x 3 x H x W]
               - samples.mask: a binary mask of shape [batch_size x H x W], containing 1 on padded pixels
            or a tuple of tensors and mask

            It returns a dict with the following elements:
               - "pred_logits": the classification logits (including no-action) for all queries.
                                Shape= [batch_size x num_queries x (num_classes + 1)]
               - "pred_segments": The normalized segments coordinates for all queries, represented as
                               (center, width). These values are normalized in [0, 1],
                               relative to the size of each individual image (disregarding possible padding).
                               See PostProcess for information on how to retrieve the unnormalized segment.
               - "aux_outputs": Optional, only returned when auxilary losses are activated. It is a list of
                                dictionnaries containing the two above keys for each decoder layer.
        """
        if not isinstance(samples, NestedTensor):
            if isinstance(samples, (list, tuple)):
                samples = NestedTensor(*samples)
            else:
                samples = nested_tensor_from_tensor_list(samples)  # (n, c, t)

        pos = [self.position_embedding(samples)]
        src, mask = samples.tensors, samples.mask
        srcs = [self.input_proj[0](src)]
        masks = [mask]

        query_embeds = self.query_embed.weight
        hs, init_reference, inter_references, memory = self.transformer(
            srcs, masks, pos, query_embeds)

        outputs_classes = []
        outputs_coords = []
        # gather outputs from each decoder layer
        for lvl in range(hs.shape[0]):
            if lvl == 0:
                reference = init_reference
            else:
                reference = inter_references[lvl - 1]

            reference = inverse_sigmoid(reference)
            outputs_class = self.class_embed[lvl](hs[lvl])
            tmp = self.segment_embed[lvl](hs[lvl])
            # the l-th layer (l >= 2)
            if reference.shape[-1] == 2:
                tmp += reference
            # the first layer
            else:
                assert reference.shape[-1] == 1
                tmp[..., 0] += reference[..., 0]
            outputs_coord = tmp.sigmoid()
            outputs_classes.append(outputs_class)
            outputs_coords.append(outputs_coord)
        outputs_class = torch.stack(outputs_classes)
        outputs_coord = torch.stack(outputs_coords)

        if not self.with_act_reg:
            out = {'pred_logits': outputs_class[-1],
                   'pred_segments': outputs_coord[-1]}
        else:
            # perform RoIAlign
            B, N = outputs_coord[-1].shape[:2]
            origin_feat = memory

            rois = self._to_roi_align_format(
                outputs_coord[-1], origin_feat.shape[2], scale_factor=1.5)
            roi_features = self.roi_extractor(origin_feat, rois)
            roi_features = roi_features.view((B, N, -1))
            pred_actionness = self.actionness_pred(roi_features)

            last_layer_cls = outputs_class[-1]
            last_layer_reg = outputs_coord[-1]

            out = {'pred_logits': last_layer_cls,
                   'pred_segments': last_layer_reg, 'pred_actionness': pred_actionness}

        if self.aux_loss:
            out['aux_outputs'] = self._set_aux_loss(
                outputs_class, outputs_coord)

        return out

    @torch.jit.unused
    def _set_aux_loss(self, outputs_class, outputs_coord):
        # this is a workaround to make torchscript happy, as torchscript
        # doesn't support dictionary with non-homogeneous values, such
        # as a dict having both a Tensor and a list.
        return [{'pred_logits': a, 'pred_segments': b}
                for a, b in zip(outputs_class[:-1], outputs_coord[:-1])]

class SetCriterion(nn.Module):
    """ This class computes the loss for TadTR.
    The process happens in two steps:
        1) we compute hungarian assignment between ground truth segments and the outputs of the model
        2) we supervise each pair of matched ground-truth / prediction (supervise class and segment)
    """

    def __init__(self, num_classes, matcher, weight_dict, losses, focal_alpha=0.25):
        """ Create the criterion.
        Parameters:
            num_classes: number of action categories, omitting the special no-action category
            matcher: module able to compute a matching between targets and proposals
            weight_dict: dict containing as key the names of the losses and as values their relative weight.
            losses: list of all the losses to be applied. See get_loss for list of available losses.
            focal_alpha: alpha in Focal Loss
        """
        super().__init__()
        self.num_classes = num_classes
        self.matcher = matcher
        self.weight_dict = weight_dict
        self.losses = losses
        self.focal_alpha = focal_alpha

    def loss_labels(self, outputs, targets, indices, num_segments, log=True):
        """Classification loss (NLL)
        targets dicts must contain the key "labels" containing a tensor of dim [nb_target_segments]
        """
        assert 'pred_logits' in outputs
        src_logits = outputs['pred_logits']

        idx = self._get_src_permutation_idx(indices)
        target_classes_o = torch.cat([t["labels"][J] for t, (_, J) in zip(targets, indices)])
        target_classes = torch.full(src_logits.shape[:2], self.num_classes,
                                    dtype=torch.int64, device=src_logits.device)
        target_classes[idx] = target_classes_o

        target_classes_onehot = torch.zeros([src_logits.shape[0], src_logits.shape[1], src_logits.shape[2] + 1],
                                            dtype=src_logits.dtype, layout=src_logits.layout, device=src_logits.device)
        target_classes_onehot.scatter_(2, target_classes.unsqueeze(-1), 1)

        target_classes_onehot = target_classes_onehot[:,:,:-1]
        loss_ce = sigmoid_focal_loss(src_logits, target_classes_onehot, num_segments, alpha=self.focal_alpha, gamma=2) * src_logits.shape[1]  # nq
        losses = {'loss_ce': loss_ce}

        if log:
            # TODO this should probably be a separate loss, not hacked in this one here
            losses['class_error'] = 100 - accuracy(src_logits[idx], target_classes_o)[0]

        return losses

    def loss_segments(self, outputs, targets, indices, num_segments):
        """Compute the losses related to the segmentes, the L1 regression loss and the IoU loss
           targets dicts must contain the key "segments" containing a tensor of dim [nb_target_segments, 2]
           The target segments are expected in format (center, width), normalized by the video length.
        """
        assert 'pred_segments' in outputs
        idx = self._get_src_permutation_idx(indices)
        src_segments = outputs['pred_segments'][idx]
        target_segments = torch.cat([t['segments'][i] for t, (_, i) in zip(targets, indices)], dim=0)

        loss_segment = F.l1_loss(src_segments, target_segments, reduction='none')

        losses = {}
        losses['loss_segments'] = loss_segment.sum() / num_segments

        loss_iou = 1 - torch.diag(segment_ops.segment_iou(
            segment_ops.segment_cw_to_t1t2(src_segments),
            segment_ops.segment_cw_to_t1t2(target_segments)))
        losses['loss_iou'] = loss_iou.sum() / num_segments
        return losses

    def loss_actionness(self, outputs, targets, indices, num_segments):
        """Compute the actionness regression loss
           targets dicts must contain the key "segments" containing a tensor of dim [nb_target_segments, 2]
           The target segments are expected in format (center, width), normalized by the video length.
        """
        assert 'pred_segments' in outputs
        assert 'pred_actionness' in outputs
        src_segments = outputs['pred_segments'].view((-1, 2))
        target_segments = torch.cat([t['segments'] for t in targets], dim=0)

        losses = {}

        iou_mat = segment_ops.segment_iou(
            segment_ops.segment_cw_to_t1t2(src_segments),
            segment_ops.segment_cw_to_t1t2(target_segments))

        gt_iou = iou_mat.max(dim=1)[0]
        pred_actionness = outputs['pred_actionness']
        loss_actionness = F.l1_loss(pred_actionness.view(-1), gt_iou.view(-1).detach())

        losses['loss_actionness'] = loss_actionness
        return losses

    def _get_src_permutation_idx(self, indices):
        # permute predictions following indices
        batch_idx = torch.cat([torch.full_like(src, i) for i, (src, _) in enumerate(indices)])
        src_idx = torch.cat([src for (src, _) in indices])
        return batch_idx, src_idx

    def _get_tgt_permutation_idx(self, indices):
        # permute targets following indices
        batch_idx = torch.cat([torch.full_like(tgt, i) for i, (_, tgt) in enumerate(indices)])
        tgt_idx = torch.cat([tgt for (_, tgt) in indices])
        return batch_idx, tgt_idx

    def get_loss(self, loss, outputs, targets, indices, num_segments, **kwargs):
        loss_map = {
            'labels': self.loss_labels,
            'segments': self.loss_segments,
            'actionness': self.loss_actionness,
        }

        assert loss in loss_map, f'do you really want to compute {loss} loss?'
        return loss_map[loss](outputs, targets, indices, num_segments, **kwargs)

    def forward(self, outputs, targets):
        """ This performs the loss computation.
        Parameters:
             outputs: dict of tensors, see the output specification of the model for the format
             targets: list of dicts, such that len(targets) == batch_size.
                      The expected keys in each dict depends on the losses applied, see each loss' doc
        """
        outputs_without_aux = {k: v for k, v in outputs.items() if k != 'aux_outputs'}

        # Retrieve the matching between the outputs of the last layer and the targets
        indices = self.matcher(outputs_without_aux, targets)

        # Compute the average number of target segments accross all nodes, for normalization purposes
        num_segments = sum(len(t["labels"]) for t in targets)
        num_segments = torch.as_tensor([num_segments], dtype=torch.float, device=next(iter(outputs.values())).device)
        if is_dist_avail_and_initialized():
            torch.distributed.all_reduce(num_segments)
        num_segments = torch.clamp(num_segments / get_world_size(), min=1).item()

        # Compute all the requested losses
        losses = {}
        for loss in self.losses:
            kwargs = {}
            losses.update(self.get_loss(loss, outputs, targets, indices, num_segments, **kwargs))

        # In case of auxiliary losses, we repeat this process with the output of each intermediate layer.
        if 'aux_outputs' in outputs:
            for i, aux_outputs in enumerate(outputs['aux_outputs']):
                indices = self.matcher(aux_outputs, targets)
                for loss in self.losses:
                    # we do not compute actionness loss for aux outputs
                    if 'actionness' in loss:
                        continue

                    kwargs = {}
                    if loss == 'labels':
                        # Logging is enabled only for the last layer
                        kwargs['log'] = False
                    l_dict = self.get_loss(loss, aux_outputs, targets, indices, num_segments, **kwargs)
                    l_dict = {k + f'_{i}': v for k, v in l_dict.items()}
                    losses.update(l_dict)

        self.indices = indices
        return losses

class PostProcess(nn.Module):
    """ This module converts the model's output into the format expected by the TADEvaluator"""

    @torch.no_grad()
    def forward(self, outputs, target_sizes, fuse_score=True):
        """ Perform the computation
        Parameters:
            outputs: raw outputs of the model
            target_sizes: tensor of dimension [batch_size] containing the duration of each video of the batch
        """
        out_logits, out_segments = outputs['pred_logits'], outputs['pred_segments']

        assert len(out_logits) == len(target_sizes)
        # assert target_sizes.shape[1] == 1

        prob = out_logits.sigmoid()   # [bs, nq, C]
        if fuse_score:
            prob *= outputs['pred_actionness']

        segments = segment_ops.segment_cw_to_t1t2(out_segments)   # bs, nq, 2

        if cfg.postproc_rank == 1:     # default
            # sort across different instances, pick top 100 at most
            topk_values, topk_indexes = torch.topk(prob.view(
                out_logits.shape[0], -1), min(cfg.postproc_ins_topk, prob.shape[1]*prob.shape[2]), dim=1)
            scores = topk_values
            topk_segments = topk_indexes // out_logits.shape[2]
            labels = topk_indexes % out_logits.shape[2]

            # bs, nq, 2; bs, num, 2
            segments = torch.gather(
                segments, 1, topk_segments.unsqueeze(-1).repeat(1, 1, 2))
            query_ids = topk_segments
        else:
            # pick topk classes for each query
            # pdb.set_trace()
            scores, labels = torch.topk(prob, cfg.postproc_cls_topk, dim=-1)
            scores, labels = scores.flatten(1), labels.flatten(1)
            # (bs, nq, 1, 2)
            segments = segments[:, [
                i//cfg.postproc_cls_topk for i in range(cfg.postproc_cls_topk*segments.shape[1])], :]
            query_ids = (torch.arange(0, cfg.postproc_cls_topk*segments.shape[1], 1, dtype=labels.dtype,
                         device=labels.device) // cfg.postproc_cls_topk)[None, :].repeat(labels.shape[0], 1)

        # from normalized [0, 1] to absolute [0, length] coordinates
        vid_length = target_sizes
        scale_fct = torch.stack([vid_length, vid_length], dim=1)
        segments = segments * scale_fct[:, None, :]

        results = [{'scores': s, 'labels': l, 'segments': b, 'query_ids': q}
                   for s, l, b, q in zip(scores, labels, segments, query_ids)]

        return results

class MLP(nn.Module):
    """ Very simple multi-layer perceptron (also called FFN)"""

    def __init__(self, input_dim, hidden_dim, output_dim, num_layers):
        super().__init__()
        self.num_layers = num_layers
        h = [hidden_dim] * (num_layers - 1)
        self.layers = nn.ModuleList(nn.Linear(n, k)
                                    for n, k in zip([input_dim] + h, h + [output_dim]))

    def forward(self, x):
        for i, layer in enumerate(self.layers):
            x = F.relu(layer(x)) if i < self.num_layers - 1 else layer(x)
        return x

def build(args):
    if args.binary:
        num_classes = 1
    else:
        if args.dataset_name == 'thumos14':
            num_classes = 20
        elif args.dataset_name == 'muses':
            num_classes = 25
        elif args.dataset_name in ['activitynet', 'hacs']:
            num_classes = 200
        else:
            raise ValueError('unknown dataset {}'.format(args.dataset_name))

    pos_embed = build_position_encoding(args)
    transformer = build_deformable_transformer(args)

    model = TadTR(
        pos_embed,
        transformer,
        num_classes=num_classes,
        num_queries=args.num_queries,
        aux_loss=args.aux_loss,
        with_segment_refine=args.seg_refine,
        with_act_reg=args.act_reg
    )

    matcher = build_matcher(args)
    losses = ['labels', 'segments']

    weight_dict = {
        'loss_ce': args.cls_loss_coef,
        'loss_segments': args.seg_loss_coef,
        'loss_iou': args.iou_loss_coef}

    if args.act_reg:
        weight_dict['loss_actionness'] = args.act_loss_coef
        losses.append('actionness')

    if args.aux_loss:
        aux_weight_dict = {}
        for i in range(args.dec_layers - 1):
            aux_weight_dict.update({k + f'_{i}': v for k, v in weight_dict.items()})
        aux_weight_dict.update({k + f'_enc': v for k, v in weight_dict.items()})
        weight_dict.update(aux_weight_dict)

    criterion = SetCriterion(num_classes, matcher,
        weight_dict, losses, focal_alpha=args.focal_alpha)

    postprocessor = PostProcess()

    return model, criterion, postprocessor


# Converting image to NDVI colored scale

from PIL import ImageDraw, ImageFont, Image  # Pillow library

data = open('index_convert.csv', 'w')
data.write("Name: ;Longtitude: ; Latitude: ;Index name: ;Maximum: ;Average: ;Minimum: \n")
data.close()

def index_convert(image, lon, lat):
    dr = ''
    path = image.split("/")
    for p in path[:-1]:
        dr += p + '/'
    dr += '/indicies/'
    date = '.'.join(path[-1].split('.')[:-1])
    img = Image.open(image)
    # I get height and width of the image
    w, h = img.size

    # function below is useful, because it can be used to many various indexes defined after
    def operation(code, name, contrast):
        # ^^ kolejno: nazwa funkcji indeksu, nazwa do zapisania w pliku, funkcja kontrastu
        # name of index func, name to save in file, contrast func

        # for every single index, that's what happen:
        nonlocal img, date
        global data
        print('index: ' + name)
        index_col = img.copy().convert('HSV')  # creating hsv picture (h means color, i'll use it later)

        img_rgb = img.convert('RGB')
        index_bw = img_rgb.copy()  # creating copy for black-white index

        px_index_bw = index_bw.load()  # I get pixel information of b-w picture
        px_index_col = index_col.load()  # and hsv one
        index_sum = []  # list of every pixel's index

        # checking every single pixel

        for X in range(0, w):  # width
            for Y in range(0, h):  # height
                pixel_rgb = img_rgb.getpixel((X, Y))  # Get pixel's RGB values

                r, g, b = pixel_rgb

                # ~via Kuba Frączek
                brightness = sum(pixel_rgb) / 3  # 0 is dark (black) and 255 is bright (white)

                if 35 < brightness < 250:  # white and dark spots off
                    index = code(r, g, b)
                    index_sum.append(index)  # add index value to the list t.b.c.

                    index = contrast(index)  # a nice, suitable contrast

                    px_index_bw[X, Y] = (index, index, index)
                    # one picture in GRAYSCALE (r +b +g equals gray (or white (or black)))
                    px_index_col[X, Y] = (index, 200, 200)
                    # and one picture in HSV, in which H is index, so index value is one color of the spectrum

        # ####### scale ######

        s = int((h - 100) / 200)  # scale of the scale (I check how many times it could fit)

        if s > 3:
            s -= 3  # however its still to big, unless it would be too small to exist
        end = s * 200 + 100
        beg = 100

        # if average index value is too high or too low scale must adapt
        if sum(index_sum) / len(index_sum) > 0.4:
            end = h - 10
            if s > 1:
                s -= 1
        if sum(index_sum) / len(index_sum) < -0.4:
            beg = 10
            if s > 2:
                s -= 2
        try:
            font = ImageFont.truetype("DejaVuSansMono.ttf", 2 + s * 10)  # for linux
        except OSError:
            font = ImageFont.truetype("arial.ttf", 2 + s * 10)  # for windows

        for x in range(w - 10 - s * 10, w - 10):
            n = -0.2
            for y in range(beg, end):
                nv = contrast(n)  # the same contrast as at the picture
                px_index_bw[x, y] = (nv, nv, nv)
                px_index_col[x, y] = (nv, 200, 200)
                n += 0.003 / s

        ss = 32 * s  # odstępy między numerami
        hh = beg - 2  # początek skali

        # scale text on the hsv picture
        zo = ImageDraw.Draw(index_col)
        zo.text((w - 13 - s * 30, hh),          "-.2",  (0, 0, 200), font=font)
        zo.text((w - 13 - s * 30, hh + 1 * ss), "-.1",  (0, 0, 200), font=font)
        zo.text((w - 3 - s * 30, hh + 2 * ss),  "0",    (0, 0, 200), font=font)
        zo.text((w - 7 - s * 30, hh + 3 * ss),  ".1",   (0, 0, 200), font=font)
        zo.text((w - 7 - s * 30, hh + 4 * ss),  ".2",   (0, 0, 200), font=font)
        zo.text((w - 7 - s * 30, hh + 5 * ss),  ".3",   (0, 0, 200), font=font)
        zo.text((w - 7 - s * 30, hh + 6 * ss),  ".4",   (0, 0, 200), font=font)

        # scale on the grayscale picture
        za = ImageDraw.Draw(index_bw)
        za.text((w - 13 - s * 30, hh),          "-.2",  (255, 255, 255), font=font)
        za.text((w - 13 - s * 30, hh + 1 * ss), "-.1",  (255, 255, 255), font=font)
        za.text((w - 3 - s * 30, hh + 2 * ss),  "0",    (255, 255, 255), font=font)
        za.text((w - 7 - s * 30, hh + 3 * ss),  ".1",   (255, 255, 255), font=font)
        za.text((w - 7 - s * 30, hh + 4 * ss),  ".2",   (255, 255, 255), font=font)
        za.text((w - 7 - s * 30, hh + 5 * ss),  ".3",   (255, 255, 255), font=font)
        za.text((w - 7 - s * 30, hh + 6 * ss),  ".4",   (255, 255, 255), font=font)

        '''
        what scale does:
        - fits in any picture above 300 px height
        - change its value according to contrast on the picture
        - if the average index value is too high or too low, the scale can do things to fit
        - ...
        '''

        try:
            # works on raspberry pi:
            index_bw.save(dr + date + "_bw_" + name + ".jpg")  # saves picture in grayscale
            index_col = index_col.convert("RGB")
            index_col.save(dr + date + "_col_" + name + ".jpg")  # picture in color scale
        except (FileNotFoundError, OSError):
            index_bw.save(date + "_bw_" + name + ".jpg")  # saves picture in grayscale
            index_col = index_col.convert("RGB")
            index_col.save(date + "_col_" + name + ".jpg")  # picture in color scale

        # print('worked')

        # max value, average, and min
        data = open('index_convert.csv', 'a')
        data.write(str(date) + ';' +
                   str(lon) + ';' +
                   str(lat) + ';' +
                   str(name) + ';' +
                   str(min(index_sum)) + ';' +
                   str(sum(index_sum) / len(index_sum)) + ';' +
                   str(max(index_sum)) + ';' + '\n')

        data.close()

        dane = [name, (min(index_sum), sum(index_sum) / len(index_sum), max(index_sum))]
        return dane
    out = []

    class Code:
        # I define indices functions (mostly) from:
        # https://www.int-arch-photogramm-remote-sens-spatial-inf-sci.net/XLII-3/1215/2018/isprs-archives-XLII-3-1215-2018.pdf
        # plus once I read:
        # because of the way the dyes are coupled to these layers, reproduce:
        # infrared as red, red as green, and green as blue.
        # do zrobienia: sprawdzić wszystkie indeksy w odsłonach normalnych i po powyższej zmianie

        @staticmethod
        def rgbvi(r, g, b):
            if (r - g) / (r + g) < -0.2:
                ix = -2
            else:
                ix = (g * g - r * b) / (g * g + r * b + 0.1)
            return ix

        @staticmethod
        def ndvi(r, g, b):
            ix = (r - b) / (r + b + 0.1)
            return ix

        @staticmethod
        def ndwi(r, g, b):
            ix = (r - g) / (r + g + 0.1)
            return ix

        @staticmethod
        def gli(r, g, b):
            if (r - g) / (r + g + 0.1) < -0.2:
                ix = -2
            else:
                ix = (2 * g - r - b) / (2 * g + r + b + 0.1)
            return ix

        @staticmethod
        def vari(r, g, b):
            if (r - g) / (r + g) < -0.2:
                ix = 2
            else:
                ix = (g - r) / (g + r - b + 0.1)
            return - ix

        @staticmethod
        def rgi(r, g, b):
            ix = r / (g + 0.1)
            return ix

        @staticmethod
        def ergbve(r, g, b):
            ix = 3.14159 * (g * g - r * b) / (g * g + r * b + 0.1)
            return ix

    # contrast function
    # every value below 0 ends up as 0, water starts at about -0.1, so I add 0.15
    # then I multiply it by 500 to make a good contrast
    # it cannot be float, because hsv and rgb can't read that ;c
    # different indexes need different contrast
    # after all I changed it randomly to make it look good

    def con(add, multi):
        def con_new(v):
            return int((v + add) * multi)
        return con_new

    # IMPORTANT! comment if needn't:
    '''
    operation(Code.vari, 'vari', con(0.15, 500))
    operation(Code.ergbve, 'ergbve', con(0.2, 300))
    operation(Code.gli, 'gli', con(0.01, 2000))
    operation(Code.rgbvi, 'rgbvi', con(0.2, 450))

    '''
    out.append(operation(Code.ndwi, 'ndwi', con(0.2, 550)))
    out.append(operation(Code.ndvi, 'ndvi', con(0.35, 300)))
    out.append(operation(Code.rgi, 'rgi', con(-0.6, 200)))

    return out


"""
This program solves the river crossing problem of the cannibals and missionaries using NDS.
The homework consists of 6 missionaries, 6 cannibals, and a boat of 5 seats.
"""
import random

class Node(object):
    "our node class. used for nds search and to show the parent"

    def __init__(self, parent, state, depth):
        self.parent = parent
        self.state = state
        self.depth = depth

    "by using the new_states function, yields new child nodes with parent as self"

    def child_node(self):
        for state in self.state.new_states():
            yield Node(parent=self, state=state, depth=self.depth + 1)

    "used to obtain the solution. Adds nodes starting from the goal state and reverses the list at the end for the solution."

    def get_solution(self):
        solution = []
        node = self
        solution.append(node)
        while node.parent is not None:
            solution.append(node.parent)
            node = node.parent
        solution.reverse()
        return solution

    "checks for the state in the state_list"

class State(object):
    """
    Left side of the river is set to state '0' and right side of the river is set to state '1'
    """
    "constructor"

    def __init__(self, total_m, total_c, boat_size, missionary_num, cannibal_num, boat_place, move):
        self.total_missionaries = total_m
        self.total_cannibals = total_c
        self.boat_size = boat_size
        self.missionary_num = missionary_num
        self.cannibal_num = cannibal_num
        self.boat_place = boat_place
        self.move = move

    "prints the state"

    def __str__(self):
        return "{:s}, {:d} {:d} {:d}".format(self.move, self.missionary_num, self.cannibal_num, self.boat_place)

    "checks if the state is valid"

    def is_state_valid(self):
        if self.missionary_num < 0 or self.missionary_num > self.total_missionaries:
            return False
        if self.cannibal_num < 0 or self.cannibal_num > self.total_cannibals:
            return False
        if self.boat_place < 0 or self.boat_place > 1:
            return False
        if self.missionary_num < self.cannibal_num and self.missionary_num > 0:
            return False
        if self.missionary_num > self.cannibal_num and self.missionary_num < self.total_missionaries:
            return False
        else:
            return True

    "returns true if goal state is met, i.e. 0 0 1"

    def goal(self):
        return self.missionary_num == 0 and self.cannibal_num == 0 and self.boat_place == 1

    "yields new states by iterating on possible m and c values. moves the boat to the other side and checks for validity too"

    def new_states(self):
        if self.boat_place > 1 or self.boat_place < 0:
            print("""Boat is somewhere it cant be.
                  """)
        elif self.boat_place == 0:
            movement = "from left to right"
            boat_place = 1
            op = -1
        elif self.boat_place == 1:
            movement = "from right to left"
            boat_place = 0
            op = 1
        for x in range(self.total_missionaries):
            for y in range(self.total_cannibals):
                move = "Moved {:d} missionaries and {:d} cannibals {:s}".format(x, y, movement)
                new_state = State(self.total_missionaries, self.total_cannibals, self.boat_size,
                                  self.missionary_num + op * x, self.cannibal_num + op * y, boat_place, move)
                if x + y >= 1 and x + y <= self.boat_size and new_state.is_state_valid():
                    yield new_state

    "checks if two states are equal"

    def is_states_equal(self, state):
        if self.missionary_num == state.missionary_num:
            if self.cannibal_num == state.cannibal_num:
                if self.boat_place == state.boat_place:
                    return True
        return False

def does_state_exists(state_list, state_two):
    for state in state_list:
        if state.is_states_equal(state_two):
            return True
    return False
    "the nds search function. adds the node to queue randomly. then pops it and adds its child nodes."
    "If goal state is found get_solution is called"

def NDS(root_node):
    queue = []
    queue.append(root_node)
    iteration_check_list = []
    while True:
        if not len(queue):
            return None
        node = queue.pop(0)

        if does_state_exists(iteration_check_list, node.state):
            continue
        iteration_check_list.append(node.state)

        if node.state.goal():
            return (node.get_solution())

        for child_node in node.child_node():
            queue.insert(random.randint(0,len(queue)),child_node)

"checks for the solution of 6 each and boat capacity 5"
print()
begin_state = State(6, 6, 5, 6, 6, 0, "Initial State")
root_node = Node(parent=None, state=begin_state, depth=0)
sol = NDS(root_node)
for element in sol:
    print(str(element.state))

    """Output can vary depending on the random node selection
    due to the behaviour of """


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

#==============================================================================#
# HISTORY                                                                      #
# -------                                                                      #
# Developed by Philippe Muise, October 2017                                    #
#                                                                              #
#==============================================================================#
"""USAGE
- 1st step following visual analysis of GEM1 step 5 output.

SUMMARY
- This modifies the GEM1 visualisation process dark feature shapefile developed
after Step 5 of the GEM1 process and prepares it to be compatible with the GEM2
process for chlorophyll and persistence analysis. The Radarsat-2 image information
is added to each polygon.

INPUT
- NOS File (user input): Polygon Shapefile of dark features for a specific year.
The shapefile must have the same fields as the template file.

- Mosaic Datasets (user input): Collection of mosaic datasets for that specific year
found in a geodatabase. GEM1 Step 5 output.

OUTPUT
- Modified NOS File (automated output):"""

import arcpy
import os
import sys
import datetime
import logging

class getRSImageInfo(object):
    def __init__(self):
        """Define the tool (tool name is the name of the class)."""
        self.label = "1. GEM1 NOS File to GEM2 Compatibility Tool "
        self.description = "The first step in the GEM1 to GEM2 process, this\
         tool populates the NOS file following GEM1 Step 5 with information to\
         access the Radarsat-2 images associated with each dark feature. See \
         help document to make sure the NOS File is properly organised first."
        self.canRunInBackground = False

    def getParameterInfo(self):
        """Define parameter definitions"""
        params0 = arcpy.Parameter(
            displayName="Input: NOS File",
            name="NOS File",
            datatype="DEShapefile",
            parameterType="Required",
            direction="Input")

        params1 = arcpy.Parameter(
            displayName="Mosaic Datasets from Year GDB",
            name="Mosaic Dataset",
            parameterType="Required",
            direction="Input",
            datatype= "DEDatasetType",
            multiValue = True
            )
        params = [params0, params1]

        return params

    def isLicensed(self):
        """Set whether tool is licensed to execute. This script requires Spatial Analyst extension to function."""

        return True

    def updateParameters(self, parameters):
        """Modify the values and properties of parameters before internal
        validation is performed.  This method is called whenever a parameter
        has been changed."""
        return

    def updateMessages(self, parameters):
        """Modify the messages created by internal validation for each tool
        parameter.  This method is called after internal validation."""
        return

    def execute(self, parameters, messages):
        arcpy.env.overwriteOutput = True

        # Script arguments specified by the user
        inputMaskShp = os.path.abspath(parameters[0].valueAsText)
        mosaicDatasets = os.path.abspath(parameters[1].valueAsText)
        mosaicList = mosaicDatasets.split(";")

        # Scratch Folder
        scratchFolder = os.path.join(os.path.dirname(inputMaskShp),"Scratch")
        if not os.path.exists(scratchFolder):
            os.makedirs(scratchFolder)
            arcpy.AddMessage("{} folder made".format(scratchFolder))

        # Output
        outMask = os.path.join(scratchFolder,"{}_RSImageInfo".format(os.path.splitext(os.path.basename(inputMaskShp))[0]))
        footprintShp = os.path.join(scratchFolder,"footprint.shp")
        footprintShpAll = os.path.join(scratchFolder,"footprint_all.shp")

        for mosaic in mosaicList:
            arcpy.AddMessage("Selecting images in the mosaic dataset " + os.path.basename(mosaic)\
                             + " and copying their attributes...")

            #Create the mosaic layer for each mosaic dataset
            mosaicLyr = os.path.basename(mosaic)+"_lyr"
            arcpy.MakeMosaicLayer_management(mosaic,mosaicLyr)

            #Select images in the mosaic dataset that intersect the mask and save each one to a shapefile
            arcpy.SelectLayerByLocation_management(mosaicLyr+"\Footprint","INTERSECT",inputMaskShp)
            arcpy.CopyFeatures_management(mosaicLyr+"\Footprint",footprintShp)

            #Append all the shapefiles created above into one shapefile
            if arcpy.Exists(footprintShpAll) == True:
                arcpy.Append_management(footprintShp,footprintShpAll,"NO_TEST")
            else:
                arcpy.CopyFeatures_management(footprintShp,footprintShpAll)

        # Extract attributes of images and add them to the shapefile by joining images and the shapefile spatially
        arcpy.AddMessage("Saving the mask layer with attributes of all the selected images...")
        arcpy.SpatialJoin_analysis(inputMaskShp,footprintShpAll,outMask ,"JOIN_ONE_TO_MANY","KEEP_ALL",\
                                   "","INTERSECT","","")

        tempOutMask = '{}.shp'.format(outMask)

        # Delete unnecessary fields
        dropFields = ["SAT_NAME","BEAM_MODE","PASS","POLARIZ","ACQ_DATE","YEAR","AREA_HA","DIAMETER_M",\
                      "DESCR","BeamMode","Polarizati","PixelSize","Projection","BitSize","FilterType",\
                      "Join_Count","TARGET_FID","JOIN_FID","MaskID_1","MinPS","MaxPS","LowPS","HighPS",\
                      "Category","CenterX","CenterY","ZOrder","SOrder","TypeID","StereoID","ItemTS","UriHash",\
                      "Shape_Leng","Shape_Area_1","RefImgName_1","GdbImgName_1","Date_1","BeamMode_1",\
                      "Polarizati_1","PixelSize_1","Projection_1","BitSize_1","FilterType_1"]
        arcpy.DeleteField_management(tempOutMask,dropFields)

        # New field for overlapping images
        arcpy.AddField_management(tempOutMask,'OVERLAP','SHORT',1)

        # Take out rows with satellite imagery that does not coincide with the date of the dark feature
        overlapexpression = 'overlapimage( !GDBIMGNAME!, !Date!)'
        codeblock = """def overlapimage(mosaicdate,radardate):
                           if (mosaicdate[7:] ==  radardate):
                             return '1'
                           else:
                             return '0'"""
        arcpy.CalculateField_management(tempOutMask, "OVERLAP", overlapexpression, "PYTHON_9.3", codeblock)

        # Change Radar imagery field name to GEM2 standard
        arcpy.AddField_management(tempOutMask,'RsatID','TEXT',100)
        arcpy.CalculateField_management(tempOutMask,'RsatID','!GdbImgNa_1!','Python_9.3')
        arcpy.DeleteField_management(tempOutMask,'GdbImgNa_1')

        # Make layer from feature class for selection
        arcpy.MakeFeatureLayer_management(tempOutMask,'overlapping','OVERLAP = 1' )
        with arcpy.da.SearchCursor('overlapping', 'SEEP_ID') as cursor:
            seepIDList = [row[0] for row in cursor]
        duplicateSeepID = list(set(x for x in seepIDList if seepIDList.count(x)>1))
        with arcpy.da.UpdateCursor('overlapping',['FID','SEEP_ID']) as cursor:
            for row in cursor:
                if row[1] in duplicateSeepID and (row[0] % 2 == 0):
                    row[1] = 0
                    cursor.updateRow(row)
        arcpy.SelectLayerByAttribute_management('overlapping', 'NEW_SELECTION', "\"SEEP_ID\" <> '0'")

        # Add 'Pid' field and populate for intergration into GEM2. Start counter at 1
        arcpy.AddField_management('overlapping','Pid','SHORT',4)
        arcpy.CalculateField_management('overlapping','Pid','int(!SEEP_ID!.split("_")[2]) + 2','PYTHON_9.3')

        # Declare final output path
        final_output = os.path.join(os.path.dirname(inputMaskShp),"{}_RSimageinfo".format(os.path.splitext(os.path.basename(inputMaskShp))[0]))

        # Save to Products folder
        arcpy.CopyFeatures_management('overlapping', final_output)

        # Delete all the intermediate files from the scratch folder
        arcpy.AddMessage("Deleting all the intermediate files...")
        if arcpy.Exists(footprintShp):
            arcpy.Delete_management(footprintShp,"")
        if arcpy.Exists(footprintShpAll):
            arcpy.Delete_management(footprintShpAll,"")
        arcpy.AddMessage("All the intermediate files have been deleted.")

        arcpy.AddMessage("The mask layer with image attributes is created.")

        return final_output


import threading
from django.shortcuts import render, redirect
from django.contrib.contenttypes.models import ContentType
from .models import Comment
from .forms import CommentForm
from django.core.mail import send_mail
from django.template.loader import render_to_string
from django.http import JsonResponse
from django.conf import settings
from django.urls import reverse

class SendMail(threading.Thread):
    def __init__(self,subject,text,email,fail_silently=False):
        self.subject = subject
        self.text = text
        self.email = email
        self.fail_silently = fail_silently
        threading.Thread.__init__(self)
    def run(self):
        send_mail(
                self.subject,
                '',
                settings.EMAIL_HOST_USER,
                [self.email],
                fail_silently=self.fail_silently,
                html_message=self.text
            )

def update_comment(request):
    referer = request.META.get('HTTP_REFERER', reverse('home'))
    comment_form = CommentForm(request.POST, user =request.user)
    data ={}
    if comment_form.is_valid():
        comment = Comment()
        comment.user = comment_form.cleaned_data['user']
        comment.content = comment_form.cleaned_data['text']
        comment.content_object = comment_form.cleaned_data['content_object']

        parent =  comment_form.cleaned_data['parent']
        if parent:
            comment.parent = parent
            comment.reply = parent.user
            comment.root = parent.root if parent.root else parent
        comment.save()

        #评论发送邮件
        if parent:
            #回复评论
            subject = '有人回复你的评论'
            email = comment.reply.email
        else:
            #发表评论
            subject = '有人评论你的博客'
            email = comment.content_object.get_email()
        content = {}
        content['comment_text'] = comment.content
        content['url'] = comment.content_object.get_url()
        text = render_to_string('send_email.html',content)
        if email != '':
            sendmail = SendMail(subject,text,email)
            sendmail.start()

        data['status'] = 'SUCCESS'
        data['username'] = comment.user.get_nickname_or_username()
        data['comment_time'] = comment.comment_time.strftime('%Y-%m-%d %H:%M:%S')
        data['text'] = comment.content
        if parent:
            data['reply'] = comment.reply.get_nickname_or_username()
        else:
            data['reply'] = ''
        data['pk'] = comment.pk
        data['root_pk'] = comment.root.pk if comment.root else ''
    else:
        data['status'] = 'ERROR'
        data['message'] = list(comment_form.errors.values())[0][0]
    return JsonResponse(data)


# -*- coding: utf-8 -*-
"""
Created on Sun Oct 27 14:00:50 2019

@author: 朱小五

微信公众号: 凹凸玩数据

哈哈还有一个：凹凸数读
"""

import pandas as pd
import requests
import time
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36'}

#生成出生当年所有日期
def dateRange(a,b):
    fmt = '%Y-%m-%d'
    bgn = int(time.mktime(time.strptime(a,fmt)))
    end = int(time.mktime(time.strptime(b,fmt)))
    list_date = [time.strftime(fmt,time.localtime(i)) for i in range(bgn,end+1,3600*24)]
    return list_date

def get_json(url):
    try:
        response = requests.get(url,headers=headers)
        if response.status_code == 200:
            json_text=response.json()
            return json_text
    except Exception:
        print('此页有问题！')
        return None

def get_comments(url):
    doc = get_json(url)
    dic = {}
    dic['pigprice'] = doc['pigprice']
    dic['pig_in'] = doc['pig_in']
    dic['pig_local'] = doc['pig_local']
    dic['maizeprice'] = doc['maizeprice']
    dic['bean'] = doc['bean']
    a = '-'.join(doc['time'][3])
    b = time.strftime('%Y-%m-%d',time.localtime(time.time()))
    print(dateRange(a,b))
    dic['time'] = dateRange(a,b)
    return pd.DataFrame(dic)

data =get_comments('http://zhujia.zhuwang.cc/index/api/chartData?areaId=-1&aa=1571997555296')

#作图
from pylab import mpl
import  matplotlib.pyplot as plt
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
mpl.rcParams['axes.unicode_minus']

plt.figure(figsize=(8,10), dpi=80)
plt.figure(1)
ax1 = plt.subplot(311)
plt.plot(data['time'],data['pigprice'], color="r",linestyle = "-")
plt.xticks([])
plt.annotate(data['pigprice'][365], xy=(data['time'][365], 40), xytext=(data['time'][270], 35), arrowprops=dict(facecolor='black', shrink=0.1, width=0.5))
plt.xlabel("生猪(外三元) 元/公斤")

ax2 = plt.subplot(312)
plt.plot(data['time'],data['maizeprice'],color="y",linestyle = "-")
plt.xticks([])
plt.xlabel("玉米(15%水分) 元/吨")

ax3 = plt.subplot(313)
plt.plot(data['time'],data['bean'],color="g",linestyle = "-")
plt.xlabel("豆粕(43%蛋白) 元/吨")
plt.xticks(data['time'][2::121], rotation=0)


from typing import Dict
from kedro.pipeline import Pipeline

from equity_investing.pipelines import data_processing as dp
from equity_investing.pipelines import feature_engineering as fe
from equity_investing.pipelines import models_ml_exploratory as me
from equity_investing.pipelines import models_ml_final as mf
from equity_investing.pipelines import models_ml_holdout_eval as mhe
from equity_investing.pipelines import portfolio_backtesting as pb
from equity_investing.pipelines import production as prod

# Run the registry
def register_pipelines() -> Dict[str, Pipeline]:
    """Register the project's pipelines.

    Returns:
        A mapping from a pipeline name to a ``Pipeline`` object.
    """
    data_processing_pipeline = dp.create_pipeline()
    raw_data_eda_pipeline = dp.create_eda_pipeline()
    feature_engineering_pipeline = fe.create_pipeline()
    final_data_eda_pipeline = fe.create_final_eda_pipeline()
    train_test_split_pipeline = mf.create_test_train_validation_sets_pipeline()
    exploratory_models_pipeline = me.create_exploratory_models_pipeline()
    coarse_hyperparameter_tuning_pipeline = mf.create_coarse_hyperparameter_tuning_pipeline()
    fine_hyperparameter_tuning_pipeline = mf.create_fine_hyperparameter_tuning_pipeline()
    model_holdout_testing_results_pipeline = mhe.create_holdout_validation_pipeline()
    portfolio_backtesting_pipeline = pb.portfolio_backtesting_pipeline()
    production_results_pipeline = prod.production_pipeline()

    return {
        # Individual pipelines
        "data_processing": data_processing_pipeline,
        "raw_data_eda": raw_data_eda_pipeline,
        "feature_engineering": feature_engineering_pipeline,
        "final_data_eda": final_data_eda_pipeline,
        "train_test_splits": train_test_split_pipeline,
        "exploratory_models": exploratory_models_pipeline,
        "coarse_hyperparameter_tuning": coarse_hyperparameter_tuning_pipeline,
        "fine_hyperparameter_tuning": fine_hyperparameter_tuning_pipeline,
        "model_holdout_testing_results": model_holdout_testing_results_pipeline,
        "portfolio_backtesting": portfolio_backtesting_pipeline,
        "production_results": production_results_pipeline,

        # PIPELINES FOR EXECUTION
        # Default pipeline
        "__default__": data_processing_pipeline + feature_engineering_pipeline + train_test_split_pipeline +
                       model_holdout_testing_results_pipeline + portfolio_backtesting_pipeline +
                       production_results_pipeline,
        # EDA pipelines
        "raw_eda": data_processing_pipeline + raw_data_eda_pipeline,
        "full_eda": data_processing_pipeline + raw_data_eda_pipeline + feature_engineering_pipeline +
                    final_data_eda_pipeline,
        # Full pipeline (takes long to run)
        "full_pipeline_ex_eda": data_processing_pipeline + feature_engineering_pipeline +
                                train_test_split_pipeline + exploratory_models_pipeline +
                                coarse_hyperparameter_tuning_pipeline + fine_hyperparameter_tuning_pipeline,
    }


#!/usr/bin/python

# Martin Kersner, m.kersner@gmail.com
# 2015/12/14

from Collage import *
from Dataset import *

def main():
    img_path     = "lena.png"
    dataset_path = "/home/martin/datasets/flickr/thumbnails"
    dataset_csv  = "dataset.csv"
    block_size   = 64

    dataset = Dataset(dataset_path)
    #dataset.create()
    file_paths, rgb_means = dataset.load(dataset_csv)

    collage = Collage(img_path, file_paths, rgb_means, block_size)
    img_collage = collage.create()
    io.imsave("collage.png", img_collage)

if __name__ == "__main__":
    main()


a="shubham"
b=35
c=45.31
'''data types in poython
integer
float
string
boolean
None
'''
d=None

a='''shubham
this "is" my program'''

print(a)
print(type(a))
print(d)

#python is case sensiitive


import random
import pickle
import string
from typing import Union
from collections import Counter
from dataclasses import dataclass, field

@dataclass
class NgrammModel:
    model_filename: str = field(default="model.pkl")
    model_weights: dict = field(default_factory=dict)

    def fit(self, filename: str, n: int) -> tuple[bool, Union[Exception, None]]:
        try:
            with open(filename, 'r', encoding='UTF-8') as reading_file:
                text = reading_file.read()
        except FileNotFoundError as e:
            return False, e
        try:
            text = text.lower().translate(str.maketrans("", "", string.punctuation + "«»—…")).replace('\n\n',
                                                                                '\n').split(" ")
            dict = {}
            for i in range(len(text) - (n - 1)):
                next_words = []
                for j in range(n - 1):
                    next_words.append(text[i + j + 1])
                if text[i] not in dict:
                    dict[text[i]] = [' '.join(next_words)]
                else:
                    dict[text[i]].append(' '.join(next_words))
            for key, val in dict.items():
                for k, v in Counter(val).items():
                    val = (k, v)
                    if val in dict[key]:
                        dict[key] = [val]
                    else:
                        dict[key].append(val)
            for key, val in dict.items():
                filtered_val = [x for x in val if type(x) != str]
                val.clear()
                for x in filtered_val:
                    val.append(x)
            self.model_weights |= dict
            return True, None
        except Exception as e:
            return False, e

    def generate(self, length, prefix=None) -> tuple[bool, Union[Exception, None]]:
        try:
            with open(self.model_filename, 'rb') as f:
                self.model_weights = pickle.load(f)
        except FileNotFoundError as e:
            return False, e
        try:
            if len(self.model_weights) != 0:
                random.seed(random.randint(0, len(self.model_weights)))
                keys = list(self.model_weights.keys())
                variaty_list = []
                word_list = []
                generated_str = ''
                if prefix:
                    prefix = ' '.join(prefix)
                else:
                    prefix = random.choice(list(self.model_weights.keys()))
                generated_str += ' '.join(prefix.split()[:-1])
                if prefix.split()[-1] not in self.model_weights.keys():
                    k = random.choice(keys)
                else:
                    k = prefix.split()[-1]
                    generated_str += " "
                    generated_str += k
                for i in range(length):
                    for j in range(len(self.model_weights[k])):
                        variaty_list.append(self.model_weights[k][j][1])
                        word_list.append(self.model_weights[k][j][0])
                    generated_phrase = random.choices(word_list, weights=variaty_list, k=1)
                    variaty_list.clear()
                    word_list.clear()
                    generated_str += k + " " if i > 0 and k != generated_str.split()[-1] else " "
                    generated_str += generated_phrase[0]
                    k = generated_phrase[0].split()[-1] if generated_phrase[0].split()[
                                                               -1] in self.model_weights else random.choice(keys)
                generated_str = ' '.join(generated_str.split()[:length]).replace("  ", " ")
                generated_str += ' '
            else:
                generated_str = 'Текст слишком короткий для генерации по данной модели'
            yield generated_str
            with open('generated.txt', 'a+') as f:
                f.write(generated_str)
            return True, str
        except Exception as e:
            return False, e

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        with open(file=self.model_filename, mode='wb') as file:
            pickle.dump(self.model_weights, file)


__author__ = "Michael Gonzalez"
__email__ = "mmg005@eng.ucsd.edu"

import xml.etree.ElementTree as ETree
import functools
import jinja2
import os
from InoCommenter import *
class ClassGenerator:
    libraries = []
    gadgetron_components = []
    loopBody = []
    name = ""
    funcs = ""
    functionDeclarations = ""

    jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader( os.path.dirname( __file__ ) ))
    jinja_env.line_comment_prefix = "#//"
    jinja_env.line_statement_prefix = "%"
    variableDeclarations = ""
    jinja_file = "ino_template.jinja.ino"

    def declare_objects(self, objs):
        self.gadgetron_components = objs

    def __init__( self, api, include_str="<>"):
        self.gadgetron_components = []
        self.objInstances = []
        self.setupBody = []
        self.variableDeclarations = []
        self.functionDeclarations = []
        self.loopBody = []
        self.find_name(api)
        self.include_str = include_str
        self.behavior_tree = None

    def appendToSetup(self, lines):
        self.setupBody += lines

    def appendToLoop(self, lines):
        self.loopBody += lines

    def define_functions(self, funcs):
        self.function_definitions = funcs

    def declare_functions(self, funcs):
        self.functionDeclarations = funcs

    def declare_variables(self, vars):
        self.variableDeclarations = vars

    def find_name(self, root):
        for component in root:
            if component.tag == "name": self.name = component.text

    def getClass(self):
        jinja_vars = {
            "gadgetron_objs"        : self.gadgetron_components,
            "variable_declarations" : self.variableDeclarations,
            "function_declarations" : self.functionDeclarations,
            "function_definitions"  : self.function_definitions,
            "setup_body"            : self.setupBody,
            "loop_body"             : self.loopBody,
            "name"                  : self.name,
            "custom_header_file"    : self.name.replace(" ", "-") + '.h',
            "header" : createRobotHeader( self.name ),
            "bt"     : self.behavior_tree,
        }

        template = self.jinja_env.get_template(self.jinja_file)
        code = template.render( jinja_vars )
        return code

if __name__ == "__main__":
    import argparse
    argparser = argparse.ArgumentParser("stuff")
    argparser.add_argument("-g", "--gspec", required=True)
    args = argparser.parse_args()
    api = ETree.parse(args.gspec).getroot()
    generator = ClassGenerator(api)
    generator.getClass()


from toontown.coghq.SpecImports import *
GlobalEntities = {1000: {'type': 'levelMgr',
        'name': 'LevelMgr',
        'comment': '',
        'parentEntId': 0,
        'cogLevel': 0,
        'farPlaneDistance': 1500,
        'modelFilename': 'phase_10/models/cashbotHQ/ZONE18a',
        'wantDoors': 1},
 1001: {'type': 'editMgr',
        'name': 'EditMgr',
        'parentEntId': 0,
        'insertEntity': None,
        'removeEntity': None,
        'requestNewEntity': None,
        'requestSave': None},
 0: {'type': 'zone',
     'name': 'UberZone',
     'comment': '',
     'parentEntId': 0,
     'scale': 1,
     'description': '',
     'visibility': []},
 10000: {'type': 'attribModifier',
         'name': '<unnamed>',
         'comment': '',
         'parentEntId': 10004,
         'attribName': 'modelPath',
         'recursive': 1,
         'typeName': 'model',
         'value': ''},
 10001: {'type': 'attribModifier',
         'name': '<unnamed>',
         'comment': '',
         'parentEntId': 10004,
         'attribName': 'scale',
         'recursive': 1,
         'typeName': 'model',
         'value': 'Vec3(.955,1,1)'},
 10019: {'type': 'attribModifier',
         'name': '<unnamed>',
         'comment': '',
         'parentEntId': 10015,
         'attribName': 'modelPath',
         'recursive': 1,
         'typeName': 'model',
         'value': ''},
 10006: {'type': 'gear',
         'name': '<unnamed>',
         'comment': '',
         'parentEntId': 10003,
         'pos': Point3(0.0, 0.0, 0.0),
         'hpr': Vec3(0.0, 0.0, 0.0),
         'scale': Vec3(1.0, 1.0, 1.0),
         'degreesPerSec': -4.0,
         'gearScale': 14.193780914463838,
         'modelType': 'mint',
         'orientation': 'horizontal',
         'phaseShift': 0},
 10007: {'type': 'gear',
         'name': 'copy of <unnamed>',
         'comment': '',
         'parentEntId': 10003,
         'pos': Point3(0.0, 0.0, 4.28999996185),
         'hpr': Vec3(0.0, 0.0, 0.0),
         'scale': Vec3(1.0, 1.0, 1.0),
         'degreesPerSec': 4.0,
         'gearScale': 14.193780914463838,
         'modelType': 'mint',
         'orientation': 'horizontal',
         'phaseShift': 0},
 10009: {'type': 'gear',
         'name': 'copy of <unnamed> (2)',
         'comment': '',
         'parentEntId': 10003,
         'pos': Point3(0.0, 0.0, 8.57999992371),
         'hpr': Vec3(0.0, 0.0, 0.0),
         'scale': Vec3(1.0, 1.0, 1.0),
         'degreesPerSec': -4.0,
         'gearScale': 14.193780914463838,
         'modelType': 'mint',
         'orientation': 'horizontal',
         'phaseShift': 0.055},
 10014: {'type': 'gear',
         'name': 'copy of <unnamed> (3)',
         'comment': '',
         'parentEntId': 10003,
         'pos': Point3(0.0, 0.0, 12.8699998856),
         'hpr': Vec3(0.0, 0.0, 0.0),
         'scale': Vec3(1.0, 1.0, 1.0),
         'degreesPerSec': 4.0,
         'gearScale': 14.193780914463838,
         'modelType': 'mint',
         'orientation': 'horizontal',
         'phaseShift': 0.06},
 10018: {'type': 'healBarrel',
         'name': '<unnamed>',
         'comment': '',
         'parentEntId': 10017,
         'pos': Point3(-2.03643107414, 2.34967470169, 5.46433734894),
         'hpr': Vec3(34.1522636414, 0.0, 0.0),
         'scale': Vec3(1.0, 1.0, 1.0),
         'rewardPerGrab': 5,
         'rewardPerGrabMax': 0},
 10002: {'type': 'model',
         'name': '<unnamed>',
         'comment': '',
         'parentEntId': 10003,
         'pos': Point3(0.0, 0.0, 0.0),
         'hpr': Vec3(0.0, 0.0, 0.0),
         'scale': Vec3(6.5, 6.5, 6.5),
         'collisionsOnly': 0,
         'flattenType': 'light',
         'loadType': 'loadModelCopy',
         'modelPath': 'phase_10/models/cogHQ/RoundShadow.bam'},
 10005: {'type': 'model',
         'name': 'doorwayCrate',
         'comment': '',
         'parentEntId': 0,
         'pos': Point3(27.0090961456, 0.850000023842, 0.0),
         'hpr': Vec3(0.0, 0.0, 0.0),
         'scale': Vec3(1.0, 1.0, 1.0),
         'collisionsOnly': 0,
         'flattenType': 'light',
         'loadType': 'loadModelCopy',
         'modelPath': 'phase_10/models/cogHQ/CBMetalCrate2.bam'},
 10008: {'type': 'model',
         'name': 'shaft',
         'comment': '',
         'parentEntId': 10003,
         'pos': Point3(0.0, 0.0, 7.25891637802),
         'hpr': Vec3(0.0, 0.0, 180.0),
         'scale': Vec3(5.35842609406, 5.35842609406, 5.35842609406),
         'collisionsOnly': 0,
         'flattenType': 'light',
         'loadType': 'loadModel',
         'modelPath': 'phase_10/models/cashbotHQ/MintGearPost.bam'},
 10010: {'type': 'model',
         'name': 'middle',
         'comment': '',
         'parentEntId': 10004,
         'pos': Point3(0.0, 0.0, 0.0),
         'hpr': Vec3(0.0, 0.0, 0.0),
         'scale': Vec3(0.954999983311, 1.0, 1.0),
         'collisionsOnly': 0,
         'flattenType': 'light',
         'loadType': 'loadModelCopy',
         'modelPath': 'phase_10/models/cogHQ/CBMetalCrate2.bam'},
 10011: {'type': 'model',
         'name': 'copy of middle',
         'comment': '',
         'parentEntId': 10004,
         'pos': Point3(-5.72357320786, 0.0, 0.0),
         'hpr': Vec3(0.0, 0.0, 0.0),
         'scale': Vec3(0.954999983311, 1.0, 1.0),
         'collisionsOnly': 0,
         'flattenType': 'light',
         'loadType': 'loadModelCopy',
         'modelPath': 'phase_10/models/cogHQ/CBMetalCrate2.bam'},
 10012: {'type': 'model',
         'name': 'copy of middle',
         'comment': '',
         'parentEntId': 10004,
         'pos': Point3(5.71999979019, 0.0, 0.0),
         'hpr': Vec3(0.0, 0.0, 0.0),
         'scale': Vec3(0.954999983311, 1.0, 1.0),
         'collisionsOnly': 0,
         'flattenType': 'light',
         'loadType': 'loadModelCopy',
         'modelPath': 'phase_10/models/cogHQ/CBMetalCrate2.bam'},
 10013: {'type': 'model',
         'name': 'copy of middle',
         'comment': '',
         'parentEntId': 10004,
         'pos': Point3(11.4399995804, 0.0, 0.0),
         'hpr': Vec3(0.0, 0.0, 0.0),
         'scale': Vec3(0.954999983311, 1.0, 1.0),
         'collisionsOnly': 0,
         'flattenType': 'light',
         'loadType': 'loadModelCopy',
         'modelPath': 'phase_10/models/cogHQ/CBMetalCrate2.bam'},
 10015: {'type': 'model',
         'name': 'crateStack',
         'comment': '',
         'parentEntId': 0,
         'pos': Point3(-18.0376968384, 20.2023410797, 0.0),
         'hpr': Vec3(0.0, 0.0, 0.0),
         'scale': Vec3(1.0, 1.0, 1.0),
         'collisionsOnly': 0,
         'flattenType': 'light',
         'loadType': 'loadModelCopy',
         'modelPath': 'phase_10/models/cogHQ/CBMetalCrate2.bam'},
 10016: {'type': 'model',
         'name': 'upper',
         'comment': '',
         'parentEntId': 10015,
         'pos': Point3(0.0, 0.0, 5.42841148376),
         'hpr': Vec3(0.0, 0.0, 0.0),
         'scale': Vec3(1.0, 1.0, 1.0),
         'collisionsOnly': 0,
         'flattenType': 'light',
         'loadType': 'loadModelCopy',
         'modelPath': 'phase_10/models/cogHQ/CBMetalCrate2.bam'},
 10017: {'type': 'model',
         'name': 'copy of upper',
         'comment': '',
         'parentEntId': 10016,
         'pos': Point3(0.0, 0.0, 5.43412637711),
         'hpr': Vec3(0.0, 0.0, 0.0),
         'scale': Vec3(1.0, 1.0, 1.0),
         'collisionsOnly': 0,
         'flattenType': 'light',
         'loadType': 'loadModelCopy',
         'modelPath': 'phase_10/models/cogHQ/CBMetalCrate2.bam'},
 10021: {'type': 'model',
         'name': 'crateStack',
         'comment': '',
         'parentEntId': 10020,
         'pos': Point3(21.064825058, 20.1899757385, 9.87216758728),
         'hpr': Vec3(270.0, 0.0, 0.0),
         'scale': Vec3(1.0, 1.0, 1.0),
         'collisionsOnly': 0,
         'flattenType': 'light',
         'loadType': 'loadModelCopy',
         'modelPath': 'phase_10/models/cashbotHQ/crates_C1.bam'},
 10003: {'type': 'nodepath',
         'name': 'gears',
         'comment': '',
         'parentEntId': 0,
         'pos': Point3(-3.18650078773, 0.0, 0.0),
         'hpr': Vec3(0.0, 0.0, 0.0),
         'scale': Vec3(1.0, 1.0, 1.0)},
 10004: {'type': 'nodepath',
         'name': 'wall',
         'comment': '',
         'parentEntId': 0,
         'pos': Point3(19.5468139648, 6.37875938416, 0.0),
         'hpr': Point3(270.0, 0.0, 0.0),
         'scale': Vec3(1.95812249184, 1.5, 1.79999995232)},
 10020: {'type': 'nodepath',
         'name': 'props',
         'comment': '',
         'parentEntId': 0,
         'pos': Point3(0.0, 0.0, 0.0),
         'hpr': Vec3(0.0, 0.0, 0.0),
         'scale': 1}}
Scenario0 = {}
levelSpec = {'globalEntities': GlobalEntities,
 'scenarios': [Scenario0]}


###################################
# File Name : process_pipe.py
###################################
#!/usr/bin/python3

import multiprocessing

def child(pipe):
    p = multiprocessing.current_process()

    msg = "Hello World"
    pipe.send(msg)

    print ("[%s] Send a message to pipe : %s" % (p.name, msg))

def main():
    parent_pipe, child_pipe = multiprocessing.Pipe()

    p = multiprocessing.Process(name="child", target=child, args=(child_pipe,))
    p.start()

    print ("Recieved message : %s" % parent_pipe.recv())
    p.join()

if __name__ == "__main__":
    main()


from datetime import datetime
from django.db import models
from django.contrib.auth.models import User

class ResetData(models.Model):
    date_time = models.DateTimeField()
    end_date_time = models.DateTimeField(default=datetime.utcfromtimestamp(2147483640))
    max_clips = models.IntegerField(default=2)
    ranks = models.IntegerField(default=5)
    user_created_clip = models.BooleanField(default=True)
    clip_newer_than = models.DateTimeField(default=datetime.utcfromtimestamp(1))

class AllowedChannel(models.Model):
    broadcaster_id = models.CharField(max_length=100)
    reset_data = models.ForeignKey(ResetData, on_delete=models.CASCADE)

    class Meta:
        unique_together = (
            "broadcaster_id",
            "reset_data",
        )

class Clip(models.Model):
    id = models.CharField(primary_key=True, max_length=100, unique=True)
    url = models.URLField(null=True)
    embed_url = models.URLField(null=True)
    broadcaster_id = models.CharField(null=True, max_length=100)
    broadcaster_name = models.CharField(null=True, max_length=100)
    creator_id = models.CharField(null=True, max_length=100)
    creator_name = models.CharField(null=True, max_length=100)
    video_id = models.CharField(null=True, max_length=100)
    game_id = models.CharField(null=True, max_length=100)
    title = models.CharField(null=True, max_length=200)
    view_count = models.IntegerField(null=True)
    created_at = models.DateTimeField(null=True)
    thumbnail_url = models.URLField(null=True)
    duration = models.FloatField(null=True)
    vod_offset = models.IntegerField(null=True)
    date_added = models.DateTimeField(null=True)
    account = models.ForeignKey(User, on_delete=models.CASCADE)
    rank = models.IntegerField(null=True)


from sys import argv

def process(lines):
    cmds = []
    for line in lines:
        cmds.append('noop')
        if line.strip() != 'noop':
            cmds.append(line.strip())
    return cmds

lines = []
with open(argv[1], "r") as f:
    lines = f.readlines()

cmds = process(lines)

X = 1
cycle = 1
pixels = []

for cmd in cmds:
    pixel = (cycle - 1) % 40
    if abs(X - pixel) <= 1:
        pixels.append('#')
    else:
        pixels.append('.')

    c = cmd.split(' ')
    if c[0] == 'addx':
        X += int(c[1])
    cycle += 1

for i in range(0,len(pixels), 40):
    line = ''.join(pixels[i:i+40])
    print(line)


import requests
import argparse
from bs4 import BeautifulSoup as bs
import os

def bigkinds(page_num):
    '''
    page_num : 페이지 번호
    '''

    cookies = {
        '_ga': 'GA1.3.1160311499.1678260565',
        'Bigkinds': 'DDF5FF973D02637109DE48B1AB337692',
        '_gid': 'GA1.3.187155468.1678889505',
        '_gat': '1',
    }

    headers = {
        'Accept': 'application/json, text/javascript, */*; q=0.01',
        'Accept-Language': 'en-US,en;q=0.9,ko;q=0.8,de;q=0.7',
        'Connection': 'keep-alive',
        'Content-Type': 'application/json;charset=UTF-8',
        'Origin': 'https://www.bigkinds.or.kr',
        'Referer': 'https://www.bigkinds.or.kr/v2/news/index.do',
        'Sec-Fetch-Dest': 'empty',
        'Sec-Fetch-Mode': 'cors',
        'Sec-Fetch-Site': 'same-origin',
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36',
        'X-Requested-With': 'XMLHttpRequest',
        'sec-ch-ua': '"Chromium";v="110", "Not A(Brand";v="24", "Google Chrome";v="110"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"macOS"',
    }

    json_data = {
        'indexName': 'news',
        'searchKey': '',
        'searchKeys': [
            {},
        ],
        'byLine': '',
        'searchFilterType': '1',
        'searchScopeType': '1',
        'searchSortType': 'date',
        'sortMethod': 'date',
        'mainTodayPersonYn': '',
        'startDate': '2022-12-15',
        'endDate': '2023-03-15',
        'newsIds': None,
        'categoryCodes': [],
        'providerCodes': [],
        'incidentCodes': [],
        'networkNodeType': '',
        'topicOrigin': '',
        'dateCodes': [],
        'editorialIs': False,
        'startNo': f'{page_num}',
        'resultNumber': '100',
        'isTmUsable': False,
        'isNotTmUsable': False,
    }

    response = requests.post('https://www.bigkinds.or.kr/api/news/search.do', cookies=cookies, headers=headers, json=json_data)
    results = response.json()
    for result in results['resultList']:
        reporter = result['BYLINE']
        category = bs(result['CATEGORY_NAMES'], 'html.parser').text
        title = result['TITLE']
        content = bs(result['CONTENT'], 'html.parser').text
        with open('comments/contents.tsv', 'a', encoding='utf-8')as f:
            f.write(f'{title}\t{content}\t{reporter}\t{category}\n')

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("-s", "--start", default=1)
    parser.add_argument("-e", "--end", default=10)
    args = parser.parse_args()

    if not os.path.exists("comments"):
        os.mkdir("comments")

    for page_num in range(args.start, args.end, 1):
        bigkinds(page_num)


import time
from utils.py_utils import run_loop
from utils.light_utils import make_multi_grad
from PixelGroup.PixelGroupChain import PixelGroupChain
from consts import REDIS_PORT, LED_CONFIG, LED_COUNT
from collections import namedtuple
import logging
import os
import redis
import json

db = redis.Redis(
	host="localhost",
	port=REDIS_PORT,
	decode_responses=True
)

def from_db():
	chain = PixelGroupChain(LED_CONFIG)

	def read_write_time():
		write_time = float(db.get("lastWrite") or 0)

		if not write_time:
			logging.warn("Could not read lastWrite, using default 0")
			write_time = 0

		return write_time

	def read_colors():
		color_data = json.loads(db.get("solidColor") or "{\"type\":\"solidColor\",\"color\":[0,0,0]}")

		return [color_data["color"]]

	def render_pixels(colors):
		chain.fade_to_all(make_multi_grad(colors, LED_COUNT), 0.5)

	render_pixels(read_colors())
	last_write_time = read_write_time()

	def loop():
		nonlocal last_write_time

		write_time = read_write_time()

		if write_time > last_write_time:
			render_pixels(read_colors())
			last_write_time = write_time

		time.sleep(1)

	run_loop(loop)


'''
Codé par : RONGERE Julien et Rodde Théophile
Date : 05/12/202
Version : 1.0
Description : Class des aliens desquelles vont découlés les autres aliens
'''
import tkinter as tk
import threading
import time
import missile
from pygame import mixer
class alien:
    def __init__(self,master,canvas,fenetre,pv,vitesse,position,temps_recharge,etat) -> None:

        self.master=master
        self.canvas=canvas
        self.fenetre=fenetre

        self.pv = pv
        self.vitesse = vitesse
        self.temps_recharge = temps_recharge
        self.etat = etat #mort ou vivant

        self.display_bbox_bool = False
        self.bbox_rect = None

        self.position = position

        self.missiles = []

        self.nom = self.__class__.__name__ #type de l'alien
        self.image = tk.PhotoImage(file=f"images/aliens/{self.nom}.png")
        self.bruitages = {"explosion":mixer.Sound("musiques/bruitages/explosion_alien.mp3")}

        self.a_spawn = False # l'alien a t-il spawn ou non

    def collision_missile(self):
        #fonction qui gere la collision entre les missiles et les aliens

        if self.etat == "mort":
            return

        for missile in self.master.vaisseau.missiles:
            missile.nettoyage(self.master.vaisseau) #on profite de la boucle pour nettoyer les missiles qui sont en dehors du canvas
            if missile.etat == "mort":
                continue
            if missile.collision(self):
                self.pv -= 1
                missile.supprimer(self.master.vaisseau)

                score = self.master.score.get()
                self.master.score.set(score+self.score*self.master.niveau.score_multiplieur)

                if self.pv == 0:
                    self.supprimer()
                    break

        self.fenetre.after(50,self.collision_missile)

    def get_bbox(self):
        #retourne les coordonnees de la bbox de l'alien (hitbox)

        return self.canvas.bbox(self.item)

    def supprimer(self):
        #supprime l'alien en activant les bruitages et les effets visuels

        self.fenetre.after(0,self.bruitages["explosion"].play) #joue le bruitage de l'explosion
        self.etat = "mort"
        self.master.aliens.remove(self)
        self.canvas.delete(self.item)
        self.exploser()

    def exploser(self):
        #explose l'alien

        image_explosion = tk.PhotoImage(file="images/aliens/explosion.png")
        image_explosion.img = image_explosion #garde une reference a l'image pour ne pas qu'elle soit supprimée par le garbage collector

        explosion = self.canvas.create_image(self.position[0],self.position[1],image=image_explosion)
        self.canvas.itemconfig(explosion)

        self.fenetre.after(300,lambda: self.canvas.delete(explosion))

    def display_bbox(self):
        #affiche la bbox de l'alien
        if self.display_bbox_bool == False:
            return
        if self.bbox_rectangle != None:
            self.canvas.delete(self.bbox_rectangle)
        bbox = self.get_bbox()
        self.bbox_rectangle = self.canvas.create_rectangle(bbox[0],bbox[1],bbox[2],bbox[3],outline="red")
        self.fenetre.after(50,self.display_bbox)


# -*- coding: utf-8 -*-
# @Author  : ydf
# @Time    : 2022/8/20 0008 12:12

import os

if os.name == 'nt':
    """
    为了保险起见，这样做一下,设置一下path，否则anaconda安装的python可能出现 ImportError: DLL load failed while importing cimpl: 找不到指定的模块。
    多设置没事，少设置了才麻烦。
    """
    from pathlib import Path
    import sys

    # print(sys.executable)  #F:\minicondadir\Miniconda2\envs\py38\python.exe
    # print(os.getenv('path'))
    python_install_path = Path(sys.executable).parent.absolute()
    kafka_libs_path = python_install_path / Path(r'.\Lib\site-packages\confluent_kafka.libs')
    dlls_path = python_install_path / Path(r'.\DLLs')
    library_bin_path = python_install_path / Path(r'.\Library\bin')
    # print(library_bin_path)
    path_env = os.getenv('path')
    os.environ['path'] = f'''{path_env};{kafka_libs_path};{dlls_path};{library_bin_path};'''

import atexit
import time
# noinspection PyPackageRequirements
from kafka import KafkaProducer, KafkaAdminClient
# noinspection PyPackageRequirements
from kafka.admin import NewTopic
# noinspection PyPackageRequirements
from kafka.errors import TopicAlreadyExistsError

from funboost import funboost_config_deafult
from funboost.publishers.base_publisher import AbstractPublisher

class ConfluentKafkaPublisher(AbstractPublisher, ):
    """
    使用kafka作为中间件，这个confluent_kafka包的性能远强于 kafka-pyhton
    """

    # noinspection PyAttributeOutsideInit
    def custom_init(self):
        from confluent_kafka import Producer as ConfluentProducer  # 这个包不好安装，用户用这个中间件的时候自己再想办法安装。win用户需要安装c++ 14.0以上环境。
        # self._producer = KafkaProducer(bootstrap_servers=funboost_config_deafult.KAFKA_BOOTSTRAP_SERVERS)
        try:
            admin_client = KafkaAdminClient(bootstrap_servers=funboost_config_deafult.KAFKA_BOOTSTRAP_SERVERS)
            admin_client.create_topics([NewTopic(self._queue_name, 10, 1)])
            # admin_client.create_partitions({self._queue_name: NewPartitions(total_count=16)})
        except TopicAlreadyExistsError:
            pass
        except BaseException as e:
            self.logger.exception(e)
        atexit.register(self.close)  # 程序退出前不主动关闭，会报错。
        self._confluent_producer = ConfluentProducer({'bootstrap.servers': ','.join(funboost_config_deafult.KAFKA_BOOTSTRAP_SERVERS)})
        self._recent_produce_time = time.time()

    # noinspection PyAttributeOutsideInit
    def concrete_realization_of_publish(self, msg):
        # noinspection PyTypeChecker
        # self.logger.debug(msg)
        self._confluent_producer.produce(self._queue_name, msg.encode(), )
        if time.time() - self._recent_produce_time > 1:
            self._confluent_producer.flush()
            self._recent_produce_time = time.time()

    def clear(self):
        self.logger.warning('还没开始实现 kafka 清空 消息')
        # self._consumer.seek_to_end()
        # self.logger.warning(f'将kafka offset 重置到最后位置')

    def get_message_count(self):
        return -1  # 还没找到获取所有分区未消费数量的方法。

    def close(self):
        pass
        # self._confluent_producer.

    def _at_exit(self):
        # self._producer.flush()
        self._confluent_producer.flush()
        super()._at_exit()


import functools
import time
import psutil

from rptest.services.redpanda import RedpandaService
from ducktape.mark.resource import ClusterUseMetadata
from ducktape.mark._mark import Mark

def cluster(log_allow_list=None,
            check_allowed_error_logs=True,
            check_for_storage_usage_inconsistencies=True,
            **kwargs):
    """
    Drop-in replacement for Ducktape `cluster` that imposes additional
    redpanda-specific checks and defaults.

    These go into a decorator rather than setUp/tearDown methods
    because they may raise errors that we would like to expose
    as test failures.
    """
    def all_redpandas(test):
        """
        Most tests have a single RedpandaService at self.redpanda, but
        it is legal to create multiple instances, e.g. for read replica tests.

        We find all replicas by traversing ducktape's internal service registry.
        """
        yield test.redpanda

        for svc in test.test_context.services:
            if isinstance(svc, RedpandaService) and svc is not test.redpanda:
                yield svc

    def log_local_load(test_name, logger, t_initial, initial_disk_stats):
        """
        Log indicators of system load on the machine running ducktape tests.  When
        running tests in a single-node docker environment, this is useful to help
        diagnose whether slow-running/flaky tests are the victim of an overloaded
        node.
        """
        load = psutil.getloadavg()
        memory = psutil.virtual_memory()
        swap = psutil.swap_memory()
        disk_stats = psutil.disk_io_counters()
        disk_deltas = {}
        disk_rates = {}
        runtime = time.time() - t_initial
        for f in disk_stats._fields:
            a = getattr(initial_disk_stats, f)
            b = getattr(disk_stats, f)
            disk_deltas[f] = b - a
            disk_rates[f] = (b - a) / runtime

        logger.info(f"Load average after {test_name}: {load}")
        logger.info(f"Memory after {test_name}: {memory}")
        logger.info(f"Swap after {test_name}: {swap}")
        logger.info(f"Disk activity during {test_name}: {disk_deltas}")
        logger.info(f"Disk rates during {test_name}: {disk_rates}")

    def cluster_use_metadata_adder(f):
        Mark.mark(f, ClusterUseMetadata(**kwargs))

        @functools.wraps(f)
        def wrapped(self, *args, **kwargs):
            # This decorator will only work on test classes that have a RedpandaService,
            # such as RedpandaTest subclasses
            assert hasattr(self, 'redpanda')

            t_initial = time.time()
            disk_stats_initial = psutil.disk_io_counters()
            try:
                r = f(self, *args, **kwargs)
            except:
                if not hasattr(self, 'redpanda') or self.redpanda is None:
                    # We failed so early there isn't even a RedpandaService instantiated
                    raise

                log_local_load(self.test_context.test_name,
                               self.redpanda.logger, t_initial,
                               disk_stats_initial)

                for redpanda in all_redpandas(self):
                    redpanda.logger.exception(
                        f"Test failed, doing failure checks on {redpanda.who_am_i()}..."
                    )

                    # Disabled to avoid addr2line hangs
                    # (https://github.com/redpanda-data/redpanda/issues/5004)
                    # self.redpanda.decode_backtraces()

                    redpanda.cloud_storage_diagnostics()

                    redpanda.raise_on_crash(log_allow_list=log_allow_list)

                raise
            else:
                if not hasattr(self, 'redpanda') or self.redpanda is None:
                    # We passed without instantiating a RedpandaService, for example
                    # in a skipped test
                    return r

                log_local_load(self.test_context.test_name,
                               self.redpanda.logger, t_initial,
                               disk_stats_initial)

                # In debug mode, any test writing too much traffic will impose too much
                # load on the system and destabilize other tests.  Detect this with a
                # post-test check for total bytes written.
                debug_mode_data_limit = 64 * 1024 * 1024
                if hasattr(self, 'debug_mode') and self.debug_mode is True:
                    bytes_written = self.redpanda.estimate_bytes_written()
                    if bytes_written is not None:
                        self.redpanda.logger.info(
                            f"Estimated bytes written: {bytes_written}")
                        if bytes_written > debug_mode_data_limit:
                            self.redpanda.logger.error(
                                f"Debug-mode test wrote too much data ({int(bytes_written) // (1024 * 1024)}MiB)"
                            )

                for redpanda in all_redpandas(self):
                    redpanda.logger.info(
                        f"Test passed, doing log checks on {redpanda.who_am_i()}..."
                    )
                    if check_allowed_error_logs:
                        # Only do log inspections on tests that are otherwise
                        # successful.  This executes *before* the end-of-test
                        # shutdown, thereby avoiding having to add the various
                        # gate_closed etc errors to our allow list.
                        # TODO: extend this to cover shutdown logging too, and
                        # clean up redpanda to not log so many errors on shutdown.
                        try:
                            redpanda.raise_on_bad_logs(
                                allow_list=log_allow_list)
                        except:
                            redpanda.cloud_storage_diagnostics()
                            raise

                    if check_for_storage_usage_inconsistencies:
                        try:
                            redpanda.raise_on_storage_usage_inconsistency()
                        except:
                            redpanda.cloud_storage_diagnostics()
                            raise

                self.redpanda.validate_controller_log()

                if self.redpanda.si_settings is not None:
                    try:
                        self.redpanda.stop_and_scrub_object_storage()
                    except:
                        self.redpanda.cloud_storage_diagnostics()
                        raise

                # Finally, if the test passed and all post-test checks
                # also passed, we may trim the logs to INFO level to
                # save space.
                for redpanda in all_redpandas(self):
                    redpanda.trim_logs()

                return r

        # Propagate ducktape markers (e.g. parameterize) to our function
        # wrapper
        wrapped.marks = f.marks
        wrapped.mark_names = f.mark_names

        return wrapped

    return cluster_use_metadata_adder


import unittest

import numpy as np

from dezero import Variable
from steps.stage3.step29 import f, gx2

class TestStep29(unittest.TestCase):
    def test_check(self):
        x0 = Variable(np.array(2.0))
        iters = 10

        for i in range(iters):
            print(x0)
            y = f(x0)
            x0.clear_grad()
            y.backward()

            x0._data -= x0.grad / gx2(x0.data)

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


import logging
from pprint import pformat
from typing import Optional

import tensorflow as tf

from mlpp_lib.callbacks import TimeHistory, EnsembleMetrics
from mlpp_lib.datasets import DataLoader, DataModule

from mlpp_lib.utils import (
    get_callback,
    get_loss,
    get_metric,
    get_model,
    get_optimizer,
    process_out_bias_init,
)

LOGGER = logging.getLogger(__name__)

def get_log_params(param_run: dict) -> dict:
    """Extract a selection of parameters for pretty logging"""
    log_params = {}
    for dimension in param_run["data_partitioning"].keys():
        params = {
            f"partitioning_{dimension}_{name}": value
            for name, value in param_run["data_partitioning"][dimension].items()
        }
        log_params.update(params)
    # log_params["features_names"] = param_run["features"]
    # Note to future self: the list of features can easily exceed the maximum length for
    # a logged parameter, so we excluded it. Instead, this is logged as an artifact
    # together with the input run parameters.
    log_params["targets_names"] = param_run["targets"]
    log_params["sample_weights_names"] = param_run.get("sample_weights")
    log_params["event_dims"] = param_run["batching"]["event_dims"]
    log_params["thinning"] = param_run.get("thinning")
    log_params["model_name"] = list(param_run["model"])[0]
    log_params.update(param_run["model"][log_params["model_name"]])
    log_params["loss"] = param_run["loss"]
    return log_params

def train(
    cfg: dict,
    datamodule: DataModule,
    callbacks: Optional[list] = None,
) -> tuple:

    LOGGER.debug(f"run params:\n{pformat(cfg)}")

    datamodule.setup("fit")
    model_config = cfg["model"]
    loss_config = cfg["loss"]

    # prepare model
    event_dims = list(set(datamodule.x.dims) - set(datamodule.batch_dims))
    out_bias_init = process_out_bias_init(
        datamodule.train.x, cfg.get("out_bias_init", "zeros"), event_dims
    )
    model_config[list(model_config)[0]].update({"out_bias_init": out_bias_init})
    input_shape = datamodule.train.x.shape[1:]
    output_shape = datamodule.train.y.shape[1:]
    model = get_model(input_shape, output_shape, model_config)
    loss = get_loss(loss_config)
    metrics = [get_metric(metric) for metric in cfg.get("metrics", [])]
    optimizer = get_optimizer(cfg.get("optimizer", "Adam"))
    model.compile(optimizer=optimizer, loss=loss, metrics=metrics)
    model.summary(print_fn=LOGGER.info)

    # callbacks
    if callbacks is None:
        callbacks = []

    for callback in cfg.get("callbacks", []):
        callback_instance = get_callback(callback)

        if isinstance(callback_instance, EnsembleMetrics):
            callback_instance.add_validation_data((datamodule.val.x, datamodule.val.y))

        callbacks.append(callback_instance)

    time_callback = TimeHistory()
    callbacks.append(time_callback)

    batch_size = cfg.get("batch_size", 1024)
    if datamodule.group_samples is not None:
        block_size = list(datamodule.group_samples.values())[0]
    else:
        block_size = 1
    # modify batch_size so that it becomes a multiple of block_size
    batch_size = (batch_size // block_size) * block_size

    train_dataloader = DataLoader(
        datamodule.train,
        batch_size=batch_size,
        shuffle=cfg.get("shuffle", True),
        block_size=block_size,
    )
    val_dataloader = DataLoader(
        datamodule.val,
        batch_size=batch_size,
        shuffle=False,
        block_size=block_size,
    )

    LOGGER.info("Start training.")
    res = model.fit(
        train_dataloader,
        epochs=cfg.get("epochs", 1),
        validation_data=val_dataloader,
        callbacks=callbacks,
        steps_per_epoch=cfg.get("steps_per_epoch", None),
        verbose=2,
    )
    LOGGER.info("Done! \U0001F40D")

    # we don't need to export loss and metric functions for deployments
    model.compile(optimizer=optimizer, loss=None, metrics=None)

    custom_objects = tf.keras.layers.serialize(model)

    history = res.history
    # for some reasons, 'lr' is provided as float32
    # and needs to be casted in order to be serialized
    for k in history:
        history[k] = list(map(float, history[k]))

    return model, custom_objects, datamodule.standardizer, history


from odoo import models

class PurchaseOrder(models.Model):
    _inherit = "purchase.order"

    def _prepare_sale_order_data(
            self, name, partner, dest_company, direct_delivery_address):
        result = super(PurchaseOrder, self)._prepare_sale_order_data(
            name, partner, dest_company, direct_delivery_address)
        if self.saca_line_id:
            result.update({"saca_line_id": self.saca_line_id.id})
            if self.saca_line_id.breeding_id.location_id.warehouse_id:
                result.update({"warehouse_id": (
                    self.saca_line_id.breeding_id.location_id.warehouse_id.id)}
                )
        return result


f = open('k7-100.txt', 'r').read()
kmax = 1 #заведомо ложное число
kt = 1
for i in range(len(f)-1):
    if f[i] == 'C' and f[i + 1] == 'C':
        kt += 1
        if kmax < kt:
            kmax = kt
    else:
        kt = 1
print(kmax)