import pygame

from config import HEIGHT, WIDTH
from entities.option_menu import OptionMenu
from repository.image_loader import ImageLoader
from utils import root_path

class Menu(pygame.Surface):
    orange = (219, 200, 54)
    white = (255, 255, 255)
    arrow_alpha_increment = 1

    y = 0

    def __init__(self, width):
        pygame.Surface.__init__(self, (width, HEIGHT), pygame.SRCALPHA, 32)
        start = OptionMenu("Manual", x=(WIDTH / 2), y=(HEIGHT / 3))
        self.menu_options = {"Manual": start}
        self.select_option = "Manual"
        self.set_header((width / 2))
        image_loader = ImageLoader()
        self.arrow = image_loader.get_image("arrow.png").convert_alpha()
        self.blit(start, (start.x, start.y))
        self.blit(self.arrow, ((start.x - self.arrow.get_width() - 15), (start.y + (self.arrow.get_height() / 2))),
                  (0, 0, self.arrow.get_width(), self.arrow.get_height()))

        self.arrow.get_rect()

    def set_header(self, center_x):
        font = pygame.font.Font(root_path + '/assets/flappy_bird_font.ttf', 90)
        header, header_rect = self.text_objects("Flappy Bird 0 ML", font, self.orange)
        header_rect.center = (center_x, (HEIGHT / 5))
        self.blit(header, header_rect)

    def text_objects(self, text, font, color):
        textSurface = font.render(text, True, color)
        return textSurface, textSurface.get_rect()

    def increase_alpha(self):
        if self.arrow.get_alpha() >= 255:
            self.arrow_alpha_increment = -1
        elif self.arrow.get_alpha() <= 30:
            self.arrow_alpha_increment = 1
        self.arrow.set_alpha(self.arrow.get_alpha() + self.arrow_alpha_increment)
        self.arrow.convert()

    def next(self):

        self.increase_alpha()
        option = self.menu_options[self.select_option]
        self.blit(self.arrow,
                  ((option.x - self.arrow.get_width() - 15), (self.y + option.y + (self.arrow.get_height() / 2))),
                  (0, 0, self.arrow.get_width(), self.arrow.get_height()))


from ..database.models import Retailer as RetailerModel, RetailerProfile, UserTrans, CustomStyle, Category, Card, PromoConfig
from sqlalchemy import and_
from sqlalchemy.orm.exc import NoResultFound
from ..utils import response
import requests, time, json
from ..config import EGC_SPOTON_GROUP_API, EGC_PAYMENT_TOKEN_KEY_API, EGC_DEFAULT_GROUPID

class Retailer:
    def __init__(self, context):
        self.session = context["session"]
        self.referer = context["referer"]

    def __args(self, *keys):
        return [self.args[key] for key in keys]

    def __retailer(self, groupid, merchantid):
        try:
            retailer = self.session.query(RetailerModel).filter(
                and_(RetailerModel.groupid == groupid, RetailerModel.merchantid == merchantid)
            ).one()
            return retailer
        except NoResultFound:
            return None

    def __find_retailer(self, groupid, merchantid):
        retailer = self.__retailer(groupid, merchantid)
        if not retailer:
            retailer = self.__retailer(groupid, None)
        if not retailer:
            retailer = self.__retailer(EGC_DEFAULT_GROUPID, None)
        return retailer

    def __custom_style(self, groupid, merchantid):
        custom_style = self.session.query(CustomStyle).filter(
            and_(CustomStyle.groupid == groupid, CustomStyle.merchantid == merchantid)
        ).first()
        return custom_style

    def __find_custom_style(self, groupid, merchantid):
        custom_style = self.__custom_style(groupid, merchantid)
        if not custom_style:
            custom_style = self.__custom_style(groupid, None)
        if not custom_style:
            custom_style = self.__custom_style(EGC_DEFAULT_GROUPID, None)
        return custom_style

    def __create_user_trans(self, retailer, merchantid):
        merchant = {
            "groupId": retailer.groupid,
            "merchantId": merchantid,
            "retailerName": retailer.retailername,
            "retailerLogo": retailer.retailer_logo,
        }
        user_trans = UserTrans(
            utdate=round(time.time() * 1000),
            utipaddr="",
            retailerid=retailer.retailerid,
            utrefererurl=self.referer or "",
            merchantid=json.dumps(merchant),
        )
        try:
            self.session.add(user_trans)
            self.session.commit()
            return user_trans.usertransid
        except Exception:
            self.session.rollback()
            raise

    def __promo_config(self, groupid, merchantid):
        promo_config = self.session.query(PromoConfig).filter(
            and_(PromoConfig.groupid == groupid, PromoConfig.merchantid == merchantid, PromoConfig.active == True)
        ).first()
        return promo_config

    def __find_promo_config(self, groupid, merchantid):
        promo_config = self.__promo_config(groupid, merchantid)
        if not promo_config:
            promo_config = self.__promo_config(groupid, None)
        if not promo_config:
            promo_config = self.__promo_config(EGC_DEFAULT_GROUPID, None)
        return promo_config

    def get_retailer(self, groupid, merchantid):
        try:
            # find retailer by merchantid or groupid
            retailer = self.__find_retailer(groupid, merchantid)
            retailer.merchant_id = merchantid
            # get merchant data from spoton api
            # merchant_data = requests.get(EGC_SPOTON_GROUP_API + f"?merchantId={merchantid}").json()
            # retailer.retailer_logo = merchant_data["logoUrl"]
            retailer.retailer_logo = ""
            # add entry in usertrans table
            retailer.trans_id = self.__create_user_trans(retailer, merchantid)
            # get token key from payment api
            token_key = requests.get(EGC_PAYMENT_TOKEN_KEY_API + merchantid + f"?json_only").json()
            retailer.token_key = token_key["nmi_tokenization_key"]
            # find style info by merchantid or groupid
            retailer.custom_style = self.__find_custom_style(groupid, merchantid)
            # find promo config by merchantid or groupid
            promo_config = self.__find_promo_config(groupid, merchantid)
            retailer.banner_name = promo_config.bannername if promo_config else None
            return response(retailer, True, "Success")
        except Exception as error:
            print(f"Error inside find_retailer: {error}")
            return response(RetailerModel(), False, "Failed to fetch retailer")


import collections

def bfs():
    q = collections.deque()
    q.append((s, 0))
    while q:
        now, cnt = q.popleft()
        if now == g:
            print(cnt)
            return
        for i in [u, -d]:
            next = now + i
            if next < 1 or next > f:
                continue
            if visit[next] == 0:
                q.append((next, cnt + 1))
                visit[next] = 1
    print('use the stairs')
    return

f, s, g, u, d = map(int, input().split())
visit = [0] * (f + 1)
bfs()


"""
265. Paint House II
Hard

647

26

Add to List

Share
There are a row of n houses, each house can be painted with one of the k colors. The cost of painting each house with a certain color is different. You have to paint all the houses such that no two adjacent houses have the same color.

The cost of painting each house with a certain color is represented by an n x k cost matrix costs.

For example, costs[0][0] is the cost of painting house 0 with color 0; costs[1][2] is the cost of painting house 1 with color 2, and so on...
Return the minimum cost to paint all houses.

Example 1:

Input: costs = [[1,5,3],[2,9,4]]
Output: 5
Explanation:
Paint house 0 into color 0, paint house 1 into color 2. Minimum cost: 1 + 4 = 5;
Or paint house 0 into color 2, paint house 1 into color 0. Minimum cost: 3 + 2 = 5.
Example 2:

Input: costs = [[1,3],[2,4]]
Output: 5

Constraints:

costs.length == n
costs[i].length == k
1 <= n <= 100
1 <= k <= 20
1 <= costs[i][j] <= 20

Follow up: Could you solve it in O(nk) runtime?
"""
from typing import List

"""
DP

dp[i][j] := cost after painting row i with color j

dp[i+1][j] = min(costs[i][j]+dp[i-1][k] for k != j)

time O(N*K^2)
space O(N*K) - can simplify into O(N) space by using 1-d array for dp

follow up:
1. optimize time: since dp[i+1][j] is only dependent on the minimum (and second minimum since the one with same j cannot be derived from the item with same column j from previous row) from previous row, thus if we keep track of these two values from previous row, we can reduce time to O(N*K).

mistakes:
1. dp[i+1][j] = min(costs[i][j]+dp[i-1][k] for k != j)

"""

class Solution:
    def minCostII(self, costs: List[List[int]]) -> int:
        # dp[i][prev_color]
        m, n = len(costs), len(costs[0])

        dp = [[0 for _ in range(n)] for _ in range(m)]

        for j in range(n):
            dp[0][j] = costs[0][j]

        for i in range(1, m):
            for j in range(n):
                dp[i][j] = min([costs[i][j] + dp[i - 1][k] for k in range(n) if k != j])

        return min(dp[m - 1])

def main():
    sol = Solution()

    assert sol.minCostII(costs = [[1,5,3],[2,9,4]]) == 5, 'fails'

    assert sol.minCostII(costs = [[1,3],[2,4]]) == 5, 'fails'

if __name__ == '__main__':
   main()


import os

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

from backbone import EfficientNet as EffNet

def open_model(model, modelname):
    """Open model parameters from checkpoint"""
    sd = torch.load(os.path.join(os.getcwd(), 'trained_model', modelname) , map_location='cpu')
    model.load_state_dict(sd)

    return model

class R_ASPP_module(nn.Module):
    """Reduced Atrous Spatial Pyramid Pooling Lite Segmentation Head.
    Args:
        in_channels_x: Number of channels originating from the feature extractor
        in_channels_f: Number of channels originating from the skip channel
        num_classes: number of output channels. PLEASE NOTE, the OUTPUT is a concatenation of featuremaps and should be divisible by 2.
    References:
        [1] https://arxiv.org/pdf/1802.02611.pdf  (Encoder-Decoder with Atrous Separable Convolution for Semantic Image Segmentation)
        [2] https://arxiv.org/abs/1905.02244 (MobileNet v3)
    """
    def __init__(self, in_channels_x, in_channels_f, num_classes):
        super(R_ASPP_module, self).__init__()

        assert not num_classes % 2

        self.layer1 = nn.Sequential(
            nn.Conv2d(in_channels_x, 128, kernel_size=1, stride=1),
            nn.BatchNorm2d(128),
        )

        self._act = nn.ReLU6()

        self.avgpool = nn.AdaptiveAvgPool2d(1)
        self.layer2 = nn.Conv2d(in_channels_x, 128, kernel_size=1, stride=1)

        self.out_conv1 = nn.Conv2d(128, num_classes//2, kernel_size=1, stride=1)
        self.out_conv2 = nn.Conv2d(in_channels_f, num_classes//2, kernel_size=1, stride=1)

        self.hsigmoid = nn.Hardsigmoid()

        self._init_weight()

    def forward(self, x, feature):

        x_temp1 = self._act(self.layer1(x))

        # Squeeze and excitation module for Segmentation head
        x_temp2 = self.avgpool(x)
        x_temp2 = self.layer2(x_temp2)

        x_temp2_weight = self.hsigmoid(x_temp2) # sigmoid function is replaced with the Hardsigmoid function.
        x_temp2_weight = F.interpolate(x_temp2_weight, x_temp1.size()[2:], mode='bilinear', align_corners=False)

        out = x_temp2_weight * x_temp1
        out = F.interpolate(out, feature.size()[2:], mode='bilinear', align_corners=False)

        # Compress feature maps to number of classes
        out = self.out_conv1(out)
        feature = self.out_conv2(feature)

        # Small modification from the original paper, was:
        # out = out + feature
        out = torch.cat((out, feature), dim=1)

        return out

    def _init_weight(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                torch.nn.init.kaiming_normal_(m.weight)
            elif isinstance(m, nn.BatchNorm2d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()

class EfficientNet(nn.Module):
    #### INITIALIZATION OF THE EFFICIENTNET-LITE ENCODER
    ### We remove the classification head of the network, since we do not need it.
    ### For further details we refer to the backbone.py code.

    def __init__(self, backbone):
        super(EfficientNet, self).__init__()
        model = EffNet.from_name(backbone)

        del model._bn1
        del model._avg_pooling
        del model._dropout
        del model._fc

        self.model = model

    def forward(self, x):
        x = self.model._act(self.model._bn0(self.model._conv_stem(x)))
        feature_maps = []
        for idx, block in enumerate(self.model._blocks):
            drop_connect_rate = self.model._global_params.drop_connect_rate
            if drop_connect_rate:
                drop_connect_rate *= float(idx) / len(self.model._blocks)
            x = block(x, drop_connect_rate=drop_connect_rate)
            if block._depthwise_conv.stride == [2, 2]:
                feature_maps.append(x)

        return feature_maps

class MalignancyDetector(nn.Module):
    #### INITIALIZATION OF THE WHOLE MODEL EFFICIENTNET-LITE + R-ASSP-LITE
    def __init__(self, backbone='efficientnet-lite1', num_classes=2, dropout=0.1):
        super(MalignancyDetector, self).__init__()

        ### DEFINE THE BACKBONE (ENCODER)
        self.base_forward = EfficientNet(backbone)

        ### COMPRESS THE FEATURES FROM THE BACKBONE
        self._conv_head = nn.Sequential(
            nn.Conv2d(192, 96, kernel_size=1, stride=1, bias=False),
            nn.BatchNorm2d(96)
            )

        ### INITIALIZE THE SEGMENTATION HEAD
        self.r_aspp = R_ASPP_module(in_channels_x=96, in_channels_f=40, num_classes=38)

        ### INITIALIZE THE FINAL CONVOLUTIONAL LAYER
        self.last_conv = nn.Sequential(
            nn.Dropout2d(dropout, False),
            nn.Conv2d(38, num_classes, kernel_size=1, stride=1)
        )

        self._act = nn.ReLU6()

        self._init_weight()

    def forward(self, x):
        _, c2, _, c4 = self.base_forward(x)

        out = self._act(self._conv_head(c4))

        out = self.r_aspp(out, c2)

        out = self.last_conv(out)

        mask = F.interpolate(out, size=x.size()[2:], mode='bilinear', align_corners=True)

        return mask

    def _init_weight(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                torch.nn.init.kaiming_normal_(m.weight)
            elif isinstance(m, nn.BatchNorm2d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()

if __name__ == '__main__':
    ## If "python model.py" is run, this part of the code is executed, and tests the inference speed of the model.
    import time

    def count_parameters(model):
        return sum(p.numel() for p in model.parameters() if p.requires_grad)

    # Define Parameters
    device = torch.device("cpu")
    imsize = 224

    # Load  trained Model
    model = MalignancyDetector(backbone='efficientnet-lite1', num_classes=2, dropout=0.).to(device)
    model = open_model(model, 'final.pth')
    model.eval()

    print ('Total trainable parameters: ', count_parameters(model))
    time_total = 0.

    #Test inference speed over 500 randomly generated pixels
    for idx in range(500):

        with torch.no_grad():
            time_start = time.time()
            input = torch.rand((1, 3, imsize, imsize), dtype=torch.float32, device=device)
            segmentation = model(input)

            time_stop = time.time()

        time_total += time_stop - time_start

    print('FPS: ', 500/time_total)


import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
import numpy as np
import scipy
import colorsys
import random
import torchvision.models as models
from model.utils.config import cfg
#from model.roi_crop.functions.roi_crop import RoICropFunction
import cv2
import pdb

def save_net(fname, net):
    import h5py
    h5f = h5py.File(fname, mode='w')
    for k, v in net.state_dict().items():
        h5f.create_dataset(k, data=v.cpu().numpy())

def load_net(fname, net):
    import h5py
    h5f = h5py.File(fname, mode='r')
    for k, v in net.state_dict().items():
        param = torch.from_numpy(np.asarray(h5f[k]))
        v.copy_(param)

def weights_normal_init(model, dev=0.01):
    if isinstance(model, list):
        for m in model:
            weights_normal_init(m, dev)
    else:
        for m in model.modules():
            if isinstance(m, nn.Conv2d):
                m.weight.data.normal_(0.0, dev)
            elif isinstance(m, nn.Linear):
                m.weight.data.normal_(0.0, dev)

def clip_gradient(model, clip_norm):
    """Computes a gradient clipping coefficient based on gradient norm."""
    totalnorm = 0
    for p in model.parameters():
        if p.requires_grad:
            modulenorm = p.grad.data.norm()
            totalnorm += modulenorm ** 2
    totalnorm = np.sqrt(totalnorm)

    norm = clip_norm / max(totalnorm, clip_norm)
    for p in model.parameters():
        if p.requires_grad:
            p.grad.mul_(norm)

def vis_detections(im, class_name, dets, thresh=0.8):
    """Visual debugging of detections.
    第一个参数：img是原图
    第二个参数：（x，y）是矩阵的左上点坐标
    第三个参数：（x+w，y+h）是矩阵的右下点坐标
    第四个参数：（0,255,0）是画线对应的rgb颜色
    第五个参数：2是所画的线的宽度
    """
    # for i in range(np.minimum(10, dets.shape[0])):
    for i in range(dets.shape[0]):
        bbox = tuple(int(np.round(x)) for x in dets[i, :4])
        score = dets[i, -1]
        if score > thresh:
            if class_name == "star":
                cv2.rectangle(im, bbox[0:2], bbox[2:4], (0, 204, 0), 1)
                # cv2.putText(im, '%s: %.3f' % (class_name, score), (bbox[0], bbox[1] + 15), cv2.FONT_HERSHEY_PLAIN,
                #                 #             1.0, (0, 204, 0), thickness=1)
            else:
                cv2.rectangle(im, bbox[0:2], bbox[2:4], (0, 0, 255), 1)
                # cv2.putText(im, '%s: %.3f' % (class_name, score), (bbox[0], bbox[1] + 15), cv2.FONT_HERSHEY_PLAIN,
                #             1.0, (0, 0, 255), thickness=1)
    return im,all

# Borrow from matterport mask R-CNN implementation
def unmold_mask(mask, bbox, image_shape):
    """Converts a mask generated by the neural network into a format similar
    to it's original shape.
    mask: [height, width] of type float. A small, typically 28x28 mask.
    bbox: [y1, x1, y2, x2]. The box to fit the mask in.
    Returns a binary mask with the same size as the original image.
    """
    threshold = 0.1
    x1, y1, x2, y2 = bbox
    if x2 == x1 or y2==y1:
        return np.zeros(image_shape[:2], dtype=np.uint8)

    mask = scipy.misc.imresize(
        mask, (y2 - y1, x2 - x1), interp='bilinear').astype(np.float32) / 255.0
    mask = np.where(mask >= threshold, 1, 0).astype(np.uint8)

    # Put the mask in the right location.
    full_mask = np.zeros(image_shape[:2], dtype=np.uint8)
    full_mask[y1:y2, x1:x2] = mask
    return full_mask

# Borrowed from matterport mask R-CNN implementation

def apply_mask(image, mask, nomask, color, alpha=0.5):
    """Apply the given mask to the image.
    """
    mask[nomask != 0] = 0
    for c in range(3):
        image[:, :, c] = np.where(mask == 1,
                                  image[:, :, c] *
                                  (1 - alpha) + alpha * color[c] * 255,
                                  image[:, :, c])
    return image

def random_colors(N, bright=True):

    """
    Generate random colors.
    To get visually distinct colors, generate them in HSV space then
    convert to RGB.
    """
    brightness = 1.0 if bright else 0.7
    hsv = np.random.rand(N, 3)
    hsv[:, 1] = 1
    hsv[:, 2] = brightness
    # hsv = [(i / N, 1, brightness) for i in range(N)]
    colors = list(map(lambda c: colorsys.hsv_to_rgb(*c), hsv))
    random.shuffle(colors)
    return colors

def vis_det_and_mask(im, class_name, dets, masks, thresh=0.8):
    """Visual debugging of detections."""
    num_dets = np.minimum(10, dets.shape[0])
    colors_mask = random_colors(num_dets)
    colors_bbox = np.round(np.random.rand(num_dets, 3) * 255)
    # sort rois according to the coordinates, draw upper bbox first
    draw_mask = np.zeros(im.shape[:2], dtype=np.uint8)

    for i in range(1):
        bbox = tuple(int(np.round(x)) for x in dets[i, :4])
        mask = masks[i, :, :]
        full_mask = unmold_mask(mask, bbox, im.shape)

        score = dets[i, -1]
        if score > thresh:
            word_width = len(class_name)
            cv2.rectangle(im, bbox[0:2], bbox[2:4], colors_bbox[i], 2)
            cv2.rectangle(im, bbox[0:2], (bbox[0] + 18 + word_width*8, bbox[1]+15), colors_bbox[i], thickness=cv2.FILLED)
            apply_mask(im, full_mask, draw_mask, colors_mask[i], 0.5)
            draw_mask += full_mask
            cv2.putText(im, '%s' % (class_name), (bbox[0]+5, bbox[1] + 12), cv2.FONT_HERSHEY_PLAIN,
								1.0, (255,255,255), thickness=1)
    return im

def adjust_learning_rate(optimizer, decay=0.1):
    """Sets the learning rate to the initial LR decayed by 0.5 every 20 epochs"""
    for param_group in optimizer.param_groups:
        param_group['lr'] = decay * param_group['lr']

def save_checkpoint(state, filename):
    torch.save(state, filename)

def _smooth_l1_loss(bbox_pred, bbox_targets, bbox_inside_weights, bbox_outside_weights, sigma=1.0, dim=[1]):

    sigma_2 = sigma ** 2
    box_diff = bbox_pred - bbox_targets
    in_box_diff = bbox_inside_weights * box_diff
    abs_in_box_diff = torch.abs(in_box_diff)
    smoothL1_sign = (abs_in_box_diff < 1. / sigma_2).detach().float()
    in_loss_box = torch.pow(in_box_diff, 2) * (sigma_2 / 2.) * smoothL1_sign \
                  + (abs_in_box_diff - (0.5 / sigma_2)) * (1. - smoothL1_sign)
    out_loss_box = bbox_outside_weights * in_loss_box
    loss_box = out_loss_box

    s = loss_box.size(0)
    loss_box = loss_box.view(s, -1).sum(1).mean()
    # for i in sorted(dim, reverse=True):
    #   loss_box = loss_box.sum(i)
    # loss_box = loss_box.mean()
    return loss_box

def _crop_pool_layer(bottom, rois, max_pool=True):
    # code modified from
    # https://github.com/ruotianluo/pytorch-faster-rcnn
    # implement it using stn
    # box to affine
    # input (x1,y1,x2,y2)
    """
    [  x2-x1             x1 + x2 - W + 1  ]
    [  -----      0      ---------------  ]
    [  W - 1                  W - 1       ]
    [                                     ]
    [           y2-y1    y1 + y2 - H + 1  ]
    [    0      -----    ---------------  ]
    [           H - 1         H - 1      ]
    """
    rois = rois.detach()
    batch_size = bottom.size(0)
    D = bottom.size(1)
    H = bottom.size(2)
    W = bottom.size(3)
    roi_per_batch = rois.size(0) / batch_size
    x1 = rois[:, 1::4] / 16.0
    y1 = rois[:, 2::4] / 16.0
    x2 = rois[:, 3::4] / 16.0
    y2 = rois[:, 4::4] / 16.0

    height = bottom.size(2)
    width = bottom.size(3)

    # affine theta
    zero = Variable(rois.data.new(rois.size(0), 1).zero_())
    theta = torch.cat([\
      (x2 - x1) / (width - 1),
      zero,
      (x1 + x2 - width + 1) / (width - 1),
      zero,
      (y2 - y1) / (height - 1),
      (y1 + y2 - height + 1) / (height - 1)], 1).view(-1, 2, 3)

    if max_pool:
      pre_pool_size = cfg.POOLING_SIZE * 2
      grid = F.affine_grid(theta, torch.Size((rois.size(0), 1, pre_pool_size, pre_pool_size)))
      bottom = bottom.view(1, batch_size, D, H, W).contiguous().expand(roi_per_batch, batch_size, D, H, W)\
                                                                .contiguous().view(-1, D, H, W)
      crops = F.grid_sample(bottom, grid)
      crops = F.max_pool2d(crops, 2, 2)
    else:
      grid = F.affine_grid(theta, torch.Size((rois.size(0), 1, cfg.POOLING_SIZE, cfg.POOLING_SIZE)))
      bottom = bottom.view(1, batch_size, D, H, W).contiguous().expand(roi_per_batch, batch_size, D, H, W)\
                                                                .contiguous().view(-1, D, H, W)
      crops = F.grid_sample(bottom, grid)

    return crops, grid

def _affine_grid_gen(rois, input_size, grid_size):

    rois = rois.detach()
    x1 = rois[:, 1::4] / 16.0
    y1 = rois[:, 2::4] / 16.0
    x2 = rois[:, 3::4] / 16.0
    y2 = rois[:, 4::4] / 16.0

    height = input_size[0]
    width = input_size[1]

    zero = Variable(rois.data.new(rois.size(0), 1).zero_())
    theta = torch.cat([\
      (x2 - x1) / (width - 1),
      zero,
      (x1 + x2 - width + 1) / (width - 1),
      zero,
      (y2 - y1) / (height - 1),
      (y1 + y2 - height + 1) / (height - 1)], 1).view(-1, 2, 3)

    grid = F.affine_grid(theta, torch.Size((rois.size(0), 1, grid_size, grid_size)))

    return grid

def _affine_theta(rois, input_size):

    rois = rois.detach()
    x1 = rois[:, 1::4] / 16.0
    y1 = rois[:, 2::4] / 16.0
    x2 = rois[:, 3::4] / 16.0
    y2 = rois[:, 4::4] / 16.0

    height = input_size[0]
    width = input_size[1]

    zero = Variable(rois.data.new(rois.size(0), 1).zero_())

    theta = torch.cat([\
      (y2 - y1) / (height - 1),
      zero,
      (y1 + y2 - height + 1) / (height - 1),
      zero,
      (x2 - x1) / (width - 1),
      (x1 + x2 - width + 1) / (width - 1)], 1).view(-1, 2, 3)

    return theta

def compare_grid_sample():
    # do gradcheck
    N = random.randint(1, 8)
    C = 2 # random.randint(1, 8)
    H = 5 # random.randint(1, 8)
    W = 4 # random.randint(1, 8)
    input = Variable(torch.randn(N, C, H, W).cuda(), requires_grad=True)
    input_p = input.clone().data.contiguous()

    grid = Variable(torch.randn(N, H, W, 2).cuda(), requires_grad=True)
    grid_clone = grid.clone().contiguous()

    out_offcial = F.grid_sample(input, grid)
    grad_outputs = Variable(torch.rand(out_offcial.size()).cuda())
    grad_outputs_clone = grad_outputs.clone().contiguous()
    grad_inputs = torch.autograd.grad(out_offcial, (input, grid), grad_outputs.contiguous())
    grad_input_off = grad_inputs[0]

    crf = RoICropFunction()
    grid_yx = torch.stack([grid_clone.data[:,:,:,1], grid_clone.data[:,:,:,0]], 3).contiguous().cuda()
    out_stn = crf.forward(input_p, grid_yx)
    grad_inputs = crf.backward(grad_outputs_clone.data)
    grad_input_stn = grad_inputs[0]
    pdb.set_trace()

    delta = (grad_input_off.data - grad_input_stn).sum()

##  add by lq
class FocalLoss(nn.Module):
    r"""
        This criterion is a implemenation of Focal Loss, which is proposed in
        Focal Loss for Dense Object Detection.

            Loss(x, class) = - \alpha (1-softmax(x)[class])^gamma \log(softmax(x)[class])

        The losses are averaged across observations for each minibatch.
        Args:
            alpha(1D Tensor, Variable) : the scalar factor for this criterion
            gamma(float, double) : gamma > 0; reduces the relative loss for well-classiﬁed examples (p > .5),
                                   putting more focus on hard, misclassiﬁed examples
            size_average(bool): size_average(bool): By default, the losses are averaged over observations for each minibatch.
                                However, if the field size_average is set to False, the losses are
                                instead summed for each minibatch.
    """

    def __init__(self, class_num, alpha=0.25, gamma=2, size_average=True):
        super(FocalLoss, self).__init__()
        if alpha is None:
            self.alpha = Variable(torch.ones(class_num, 1))
        else:
            if isinstance(alpha, Variable):
                self.alpha = alpha
            else:
                alpha = np.array([alpha,alpha,alpha],dtype= float).reshape(class_num,1)
                alpha = torch.DoubleTensor(alpha)
                self.alpha = Variable(alpha)
        self.gamma = gamma
        self.class_num = class_num
        self.size_average = size_average

    def forward(self, inputs, targets):
        N = inputs.size(0)
        C = inputs.size(1)
        P = F.softmax(inputs, dim=1)

        class_mask = inputs.data.new(N, C).fill_(0)
        class_mask = Variable(class_mask)
        ids = targets.view(-1, 1)
        class_mask.scatter_(1, ids.data, 1.)
        # print(class_mask)

        if inputs.is_cuda and not self.alpha.is_cuda:
            self.alpha = self.alpha.cuda()
        alpha = self.alpha[ids.data.view(-1)]
        probs = (P * class_mask).sum(1).view(-1, 1).type(torch.DoubleTensor).cuda()
        log_p = probs.log().type(torch.DoubleTensor).cuda()

        batch_loss = -alpha * (torch.pow((1 - probs), self.gamma)) * log_p

        if self.size_average:
            loss = batch_loss.mean()
        else:
            loss = batch_loss.sum()
        return loss


import unittest
from collections import deque

def get_path(graph, start_node, end_node):

    # Find the shortest route in the network between the two users
    if start_node not in graph or end_node not in graph:
        raise Exception("Invalid params")

    q = deque()
    q.append(([], start_node))
    seen = set()
    while q:
        path, node = q.popleft()
        path.append(node)
        if node == end_node:
            return path

        seen.add(node)
        for neighbor in graph[node]:
            if neighbor not in seen:
                q.append((path[:], neighbor))
    return None

#     queue = deque()
#     visited = set()
#     if not graph or not start_node or not end_node:
#         return None
#     visited.add(start_node)
#     for neighbor in graph[start_node]:
#         queue.append(([start_node], neighbor))
#         visited.add(neighbor)
#     while queue:
#         current_route, node = queue.popleft()
#         current_route.append(node)
#         if node == end_node:
#             return current_route
#         else:
#             for neighbor in graph[node]:
#                 if neighbor not in visited:
#                     visited.add(neighbor)
#                     queue.append((current_route, neighbor))

#     return None

# def process_node(queue):

# Tests

class Test(unittest.TestCase):

    def setUp(self):
        self.graph = {
            'a': ['b', 'c', 'd'],
            'b': ['a', 'd'],
            'c': ['a', 'e'],
            'd': ['a', 'b'],
            'e': ['c'],
            'f': ['g'],
            'g': ['f'],
        }

    def test_two_hop_path_1(self):
        actual = get_path(self.graph, 'a', 'e')
        expected = ['a', 'c', 'e']
        self.assertEqual(actual, expected)

    def test_two_hop_path_2(self):
        actual = get_path(self.graph, 'd', 'c')
        expected = ['d', 'a', 'c']
        self.assertEqual(actual, expected)

    def test_one_hop_path_1(self):
        actual = get_path(self.graph, 'a', 'c')
        expected = ['a', 'c']
        self.assertEqual(actual, expected)

    def test_one_hop_path_2(self):
        actual = get_path(self.graph, 'f', 'g')
        expected = ['f', 'g']
        self.assertEqual(actual, expected)

    def test_one_hop_path_3(self):
        actual = get_path(self.graph, 'g', 'f')
        expected = ['g', 'f']
        self.assertEqual(actual, expected)

    def test_zero_hop_path(self):
        actual = get_path(self.graph, 'a', 'a')
        expected = ['a']
        self.assertEqual(actual, expected)

    def test_no_path(self):
        actual = get_path(self.graph, 'a', 'f')
        expected = None
        self.assertEqual(actual, expected)

    def test_start_node_not_present(self):
        with self.assertRaises(Exception):
            get_path(self.graph, 'h', 'a')

    def test_end_node_not_present(self):
        with self.assertRaises(Exception):
            get_path(self.graph, 'a', 'h')

unittest.main(verbosity=2)


from collections import deque
from sys import stdin

read = lambda: stdin.readline().rstrip()

n, m = map(int, read().split())
g = [[] for i in range(n + 1)]
r = [[] for i in range(n + 1)]

for i in range(m):
    a, b, c = map(int, read().split())
    g[a].append([b, -c])
    r[b].append(a)

q = deque()
visited = [False] * (n + 1)
visited[n] = True
q.append(n)

while q:
    cur = q.popleft()

    for j in r[cur]:
        if not visited[j]:
            visited[j] = True
            q.append(j)

INF = 1e9
dist = [INF] * (n + 1)
prev = [0] * (n + 1)
dist[1] = 0

for i in range(1, n + 1):
    for j in range(1, n + 1):
        for cur, d in g[j]:
            if dist[cur] > dist[j] + d:
                if i == (n - 1) and visited[cur]:
                    print(-1)
                    exit()

                dist[cur] = dist[j] + d
                prev[cur] = j

if dist[n] >= INF:
    print(-1)
else:
    res = [n]
    c = n

    for i in range(1, n + 1):
        if prev[c] == 0: continue
        res.append(prev[c])
        c = prev[c]

    print(' '.join(map(str, reversed(res))))


from multiprocessing import Process,Pipe
import time

def f(conn):
    seq = (i for i in range(10))
    for i in range(10):
        time.sleep(2)
        # print("send:", i)
        conn.send([i, 'test', None])
    # print(conn.recv())
    conn.close()

if __name__ == "__main__":
    left, right = Pipe() #产生两个返回对象，一个是管道这一头，一个是另一头
    p = Process(target=f, args=(right,))
    p.start()

    while True:
        print ("rev:", left.recv())
        time.sleep(1)

    # parent_conn.send('father test')

    p.join()


import logging

# logging.basicConfig(filename="F:\\pythonPjo\\testExcelCase\\log\\test.log", filemode="w", format="%(asctime)s %(name)s:%(levelname)s:%(message)s", datefmt="%d-%M-%Y %H:%M:%S", level=logging.DEBUG)
# logging.warning('this is warning')
# logging.info('this is info')

def get_logger(filename):
    logger_obj = logging.getLogger("mylogger")  #创建logger对象
    logger_obj.setLevel(logging.DEBUG)  #设置日志级别

    fh = logging.FileHandler(filename, encoding="UTF-8")  #创建handler输出到日志
    fh.setLevel(logging.DEBUG)

    ch = logging.StreamHandler()  #创建handler输出到控制台
    ch.setLevel(logging.DEBUG)

    # 定义输出格式
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    fh.setFormatter(formatter)
    ch.setFormatter(formatter)

    # 给logger对象添加handler
    logger_obj.addHandler(fh)
    logger_obj.addHandler(ch)
    return logger_obj

# logger_obj=get_logger("F:\\pythonPjo\\testExcelCase\\log\\logtest.txt")
# logger_obj.info("info")
# logger_obj.error("error")
# logger_obj.warning("warning")
# logger_obj.debug("debug")
# logger_obj.critical("critical")


import requests
import csv
from bs4 import BeautifulSoup

reqLinks=[]

with open('test.csv') as csv_file:
    csv_reader = csv.reader(csv_file,delimiter=',')
    for row in csv_reader:
        reqLinks = row

# req = requests.get('https://www.1mg.com/drugs/cipladine-ointment-137489')
# req = requests.get('https://www.1mg.com/drugs/ciplar-la-20-tablet-342850')

csvFile = open('data.csv','w')
row=["Name","Benifits","Manufacturer","Contains"]

writer = csv.writer(csvFile)
writer.writerow(row)

for rowItem in row:
    row[row.index(rowItem)]="No Data"

for reqLink in reqLinks:
    req = requests.get(reqLink)
    soup = BeautifulSoup(req.content,"html.parser")
    row[0]=soup.title.get_text()
    print('Extracting Data From '+ soup.title.get_text())
    for fileObj in soup.findAll('script'):
        if ("\"benefits\":[{" in fileObj.get_text()):
            # print("IN Benifits")
            # fileText = open('data.json','wb')
            textFile = '{'+ fileObj.get_text().split("\"benefits\":[{")[1].split('}]}]}')[0] +'}]}'
            # fileText.write(textFile.encode('utf-8'))
            row[1]=textFile

        if ("\"header\":\"Manufacturer\"" in fileObj.get_text()):
            # print("IN Manufacturer")
            # fileText = open('data.txt','wb')
            textFile = fileObj.get_text().split("\"header\":\"Manufacturer\",")[1].split("\"}")[0].split('>')[1]
            # fileText.write(textFile.encode('utf-8'))
            row[2]=textFile

        if ("\"header\":\"Contains\"" in fileObj.get_text()):
            # print("IN Contains")
            # fileText = open('data3.txt','wb')
            textFile = fileObj.get_text().split("\"header\":\"Contains\"")[1].split("\"}")[0].split('>')[1]
            # fileText.write(textFile.encode('utf-8'))
            row[3]=textFile

    for rowItem in row:
        if rowItem == '':
            row[row.index(rowItem)]="No Data"

    writer.writerow(row)
    for rowItem in row:
        row[row.index(rowItem)]="No Data"

# print(soup.prettify())
# print(soup.findAll('script')[2])

# res=soup.find("çlass='DrugOverview__content___22ZBX'")
# print(soup.html['id'])


#!/usr/bin/env python3
import sys,os,math
import tree_reader
import scipy.stats
import subprocess
import node
import seq
import tree_utils
import gzip
import argparse
from sink_tree import sink_tree

remove_intermediate_files = True

class Bipart:
    def __init__ (self,lf,rt):
        self.left = lf
        self.right = rt

    def __str__(self):
        x = ",".join(list(self.left))
        y = ",".join(list(self.right))
        return x+" | "+y

    def conflict(self, inbp):
        if len(inbp.right.intersection(self.right)) > 0 and len(inbp.right.intersection(self.left)) > 0:
            if len(inbp.left.intersection(self.right)) > 0 and len(inbp.left.intersection(self.left)) > 0 :
                return True
        if len(inbp.left.intersection(self.left)) > 0 and len(inbp.left.intersection(self.right)) > 0:
            if len(inbp.right.intersection(self.left)) > 0 and len(inbp.right.intersection(self.right)) > 0:
                return True
        return False

    def same(self, inbp):
        if len(inbp.right) != len(self.right) and len(inbp.right) != len(self.left):
            return False
        if inbp.right == self.right and inbp.left == self.left:
            return True
        if inbp.right == self.left and inbp.left == self.right:
            return True
        return False

"""
return one bipart for the node
"""
def get_bipart(nd,rt):
    out = set(rt.lvsnms())
    right = set(nd.lvsnms())
    left = set(out-right)
    bp = Bipart(right,left)
    return bp

"""
get all the biparts for a tree
"""
def get_biparts(rt):
    bps = []
    out = set(rt.lvsnms())
    for i in rt.iternodes():
        if len(i.children) == 0:
            continue
        if i == rt:
            continue
        right = set(i.lvsnms())
        left = set(out-right)
        bp = Bipart(right,left)
        bps.append(bp)
    return bps

"""
basic iqtree run with alrt 1000 bb 10000
"""
def run_iqtree(fn, numthreads):
    #ORIGINAL
    #cmd = "iqtree -s "+fn+" -bb 1000 > log"
    cmd = "iqtree -nt "+str(numthreads)+" -m GTR+G -s "+fn+" -alrt 1000 -nm 10000 -bb 1000 -redo > log"
    os.system(cmd)
    sink_tree(fn+".treefile",fn+".treefile.sunk")
    otfs = [fn+".ckp.gz",fn+".bionj",fn+".log",fn+".iqtree",fn+".mldist",fn+".model.gz",fn+".contree",fn+".splits.nex"]
    for otf in otfs:
        if os.path.exists(otf):
            os.remove(otf)
    return fn+".treefile.sunk"

"""
make the iqtrees for an interval
"""
def make_trees(seqs,fn,a_len,sw,step,numthreads):
    #print mmcutoff
    num_trees = [] # range steps are the list and then sets are the values
    segs = []
    count = 0
    for i in range(0,a_len,step):
        j = a_len if i+sw > a_len else i+sw
        if (j-i)/float(sw) < .9:
            continue
        tfn = open(fn+"."+str(count),"w")
        print(" making tree ( range:",i,"-",j,")",file=sys.stderr)
        seqnames = [] #have to have 4 seqs
        for k in seqs:
            ts = k.seq[i:j]
            if len(ts)-(ts.count("-")+ts.upper().count("N")) < 300:
                continue
            else:
                tfn.write(">"+k.name+"\n"+ts+"\n")
                seqnames.append(k.name)
        tfn.close()
        if len(seqnames) < 4:
            ttf = open(fn+"."+str(count)+".treefile.sunk","w")
            ttf.write("("+",".join(seqnames)+");")
            ttf.close()
        else:
            run_iqtree(fn+"."+str(count),numthreads)
            if remove_intermediate_files:
                otf = fn+"."+str(count)
                if os.path.exists(otf):
                    os.remove(otf)
                otf = fn+"."+str(count)+".treefile"
                if os.path.exists(otf):
                    os.remove(otf)
        tfn = fn+"."+str(count)+".treefile.sunk"
        num_trees.append(tfn)
        segs.append((i,j))
        count += 1
        if j == a_len:
            break
    return num_trees,segs

"""
get the index in a list of biparts for a specific bipart
"""
def get_bp_ind(mlbps,bp):
    for i in range(len(mlbps)):
        if mlbps[i].same(bp):
            return i

"""
add a bipart to a set of biparts
  ignores same biparts
"""
def add_bp(inset,inbp):
    add = True
    for i in inset:
        if inbp.same(i):
            add = False
            break
    if add:
        inset.add(inbp)
    return inset

"""
write the rscript
"""
def write_r():
    s = """args <- commandArgs(trailingOnly = TRUE)
a = read.table(args[1],sep=" ",h=T)
library(gplots)
png(args[2])
heatmap.2(as.matrix(a),dendrogram = 'none',sepwidth=c(0.05,0.05), sepcolor="white",
          lhei = c(0.2,1),margins=c(9,10),main=args[3],key=F,colsep=c(1:10000),rowsep=(1:10000),
          Rowv=FALSE,Colv=FALSE,trace='none', cexRow=1.0,cexCol = 1,labRow="",
          breaks=seq(-1,1,length=4),col=c("red","white","blue"))
dev.off()
"""
    out = open("rplot.r","w")
    out.write(s)
    out.close()

"""
process the interval trees for whether there are conflicts
plots to r
"""
def run_bp_window(infn,tsegfiles,mltr,segc,outf):
    write_r()
    mlto = tree_reader.read_tree_file_iter(mltr).__next__()
    mlbps = get_biparts(mlto)
    segs = {}
    segslong = {}
    segstree = {}
    plotsegs = [] # each row is a seg, each column is a node
    conflictsegscount = []
    count = 0
    for i in range(len(tsegfiles)):
        conflictcount = 0
        segs[count] = []
        segslong[count] = set()
        plotsegs.append([0] * len(mlbps))
        cmd = "bp -c "+mltr+" -t "+tsegfiles[i]+" -tv"
        segstree[count] = open(tsegfiles[i],"r").readline()
        o = subprocess.check_output(cmd.split(" "),stderr=subprocess.STDOUT)
        keepo = str(o).split("\\n")
        cf = keepo[-8]
        cc = keepo[-7]
        cft = tree_reader.read_tree_string(cf)
        cct = tree_reader.read_tree_string(cc)
        for j,k in zip(cft.iternodes(),cct.iternodes()):
            if len(j.children) > 1:
                sbp = None
                inde = None
                if j.label != "" or k.label != "":
                    sbp =get_bipart(j,cft)
                    inde = get_bp_ind(mlbps,sbp)
                # conflict one
                if j.label != "":
                    if int(j.label) > 0:
                        conflictcount += 1
                        segs[count].append(sbp)
                        plotsegs[i][inde] = -1
                        # process the bp out from above to record the actual split that conflicts
                        start = False
                        for l in keepo:
                            if start:
                                if "  (" == l[0:3]:
                                    tttt = tree_reader.read_tree_string(l.strip().split(" ")[-1])
                                    segslong[count] = add_bp(segslong[count],get_biparts(tttt)[0])
                            if "read " == l[0:5]:
                                start = True
                            if "TREES " == l[0:6]:
                                break
                # concordant one
                if k.label != "":
                    if int(k.label) > 0:
                        plotsegs[i][inde] = 1
        if remove_intermediate_files:
            otf = tsegfiles[i]
            if os.path.exists(otf):
                os.remove(otf)
        conflictsegscount.append(conflictcount) #just a running tally of the conflicts per segment
        count += 1

    # print the number of conflicts per segment
    print(infn+" "+" ".join([str(k) for k in conflictsegscount]))

    # print the verbose stuff to the gzip
    detfile = gzip.open(outf+".details.gz","wt")
    for i,sc,sl,t in zip(segs,segc,segslong,segstree):
        detfile.write (str(i)+" "+"-".join([str(k) for k in list(sc)])+"\n")
        for j in segs[i]:
            detfile.write  (" conflicts with:"+str(j)+"\n")
        for j in segslong[i]:
            detfile.write  (" prefers:"+str(j)+"\n")
        detfile.write (" tree:"+segstree[t]+"\n")
    detfile.close()

    # write the plotting information
    ouf = open(outf,"w")
    first = True
    for sc in segc:
        if first == True:
            first = False
        else:
            ouf.write(" ")
        ouf.write("\""+"-".join([str(k) for k in list(sc)])+"\"")
    ouf.write("\n")
    for i in range(len(mlbps)):
        s = []
        for j in range(len(plotsegs)):
            s.append(str(plotsegs[j][i]))
        ouf.write(" ".join(s)+"\n")
    ouf.close()
    cmd = "Rscript rplot.r "+outf+" "+outf+".png "+infn[0:min(15,len(infn))]+" > rlog 2>&1"
    os.system(cmd)

if __name__ == "__main__":
    parser = argparse.ArgumentParser()

    parser.add_argument("-s", "--seqfile", help="sequence file",required=True)
    parser.add_argument("-w", "--sw", help="sliding window (e.g., length of segment)", type=int,required=True)
    parser.add_argument("-i", "--increment", help="increment (e.g., every i basepair)",type=int, required=True)
    parser.add_argument("-p", "--plot", help="should we plot or just make the trees (default = False)",
                        action="store_true", required=False, default=False)
    parser.add_argument("-t","--threads",help="how many threads for iqtree?",required=False,type=int,default=2)
    if len(sys.argv[1:]) == 0:
        sys.argv.append("-h")

    args = parser.parse_args()

    seqfile = args.seqfile
    print("running "+seqfile,file=sys.stderr)
    seqs = seq.read_fasta_file(seqfile)
    sw = args.sw #sliding window
    step = args.increment #steps
    numthreads = args.threads
    a_len = len(seqs[0].seq)
    if a_len < sw:
        print("sequence is less than "+str(args.sw),file=sys.stderr)
        sys.exit(0)
    if a_len < sw+step:
        print("wouldn't make more than one segment: "+str(a_len)+"<"+str(sw+step),file=sys.stderr)
        sys.exit(0)
    x,segc = make_trees(seqs,seqfile,a_len,sw,step,numthreads)
    y = run_iqtree(seqfile,numthreads)

    if args.plot == True:
        print(" writing outputs and figures",file=sys.stderr)
        run_bp_window(seqfile,x,y,segc,seqfile+".interval_plotdata")


import pygame
from mutagen.mp3 import MP3 as mp3
from pygame.locals import *
import sys
import numpy as np
import board as bd
import field as fie
import os
from os.path import join as pjoin

def main():
    screen = pygame.display.set_mode((720, 600)) # ウィンウサイズの指定
    next = ""
    while(True):
        if next == "":
            next = select_window(screen)
        elif next == "Battle":
            next = battle_window(screen)
        elif next == "Rule":
            next = Rule_window(screen)

def select_window(screen):
    myfont = pygame.font.SysFont(None,40)
    title = pygame.image.load(pjoin(os.getcwd(),pjoin("figure","title.png"))).convert_alpha()
    start = myfont.render("press S to start",True,(0,0,0))
    while(True):
        screen.fill((122,255,122))
        screen.blit(start,(200,400))
        screen.blit(title,(20,50))
        pygame.display.update() # 画面更新
        pygame.time.wait(20) # 更新間隔
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    pygame.quit()
                    sys.exit()
                elif event.key == K_s:
                    return "Rule"

def result_window(screen,winner,field):
    myfont = pygame.font.SysFont(None,40)

    if winner > 0:
        winner = "black"
        res = myfont.render("{} win!".format(winner),True,(220,30,30))
    elif winner < 0:
        winner = "white"
        res = myfont.render("{} win!".format(winner),True,(220,30,30))
    else:
        res = myfont.render("tie game!",True,(220,30,30))

    ret = myfont.render("press R to replay".format(winner),True,(220,30,30))
    while(True):
        screen.fill((122,255,122))
        field.draw(screen)
        screen.blit(res,(200,200))
        screen.blit(ret,(200,350))
        pygame.display.update() # 画面更新
        pygame.time.wait(20) # 更新間隔
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    pygame.quit()
                    sys.exit()
                elif event.key == K_r:
                    return

def battle_window(screen):
    myfont = pygame.font.SysFont(None,120)
    myfont2 = pygame.font.SysFont(None,80)
    winrect = screen.get_rect()
    f = fie.field((90,80))
    flag = 0
    mouseDown_flag = False
    isBattle = True

    while(isBattle):
        screen.fill((122,255,122))
        bnum,wnum = f.bw_num()
        leftturn = f.leftturn()
        screen.blit(myfont.render("{}".format(bnum),True,(0,0,0)),(0,0))
        screen.blit(myfont.render("{}".format(wnum),True,(255,255,255)),(600,0))
        screen.blit(myfont2.render("{} turns left".format(leftturn),True,(255,122,0)),(180,0))
        isBattle = f.draw(screen)
        if not isBattle:
            pygame.mixer.stop()
            winner = f.result()
            result_window(screen,winner,f)
            return ""

        if pygame.mouse.get_pressed()[0]:#押している間は牌を表示
            pos = pygame.mouse.get_pos()
            f.putdemo(pos,screen)
            mouseDown_flag = True

        pygame.display.update() # 画面更新
        pygame.time.wait(20) # 更新間隔

        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    pygame.quit()
                    sys.exit()
                elif event.key == K_p:
                    f.pass_turn()
            if event.type == MOUSEBUTTONUP and mouseDown_flag:
                pos = pygame.mouse.get_pos()
                f.put(pos)
                mouseDown_flag = False

def Rule_window(screen):
    myfont = pygame.font.SysFont(None,40)
    start = myfont.render("press S to start",True,(0,0,0))
    rule = pygame.image.load(pjoin(os.getcwd(),pjoin("figure","rulesetumei.png"))).convert_alpha()
    isRule = True

    while(isRule):
        screen.fill((122,255,122))
        screen.blit(start,(200,560))
        screen.blit(rule,(100,0))
        pygame.display.update() # 画面更新
        pygame.time.wait(20) # 更新間隔
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    pygame.quit()
                    sys.exit()
                elif event.key == K_s:
                    return "Battle"

if __name__ == "__main__":
    pygame.init() # 初期
    pygame.display.set_caption("reversi") # ウィンドウの上の方に出てくアレの指定
    main()


from sage.all import DiGraph
from collections import Counter

with open("input-10","r") as f:
    l = [int(s[:-1]) for s in f]
    m = max(l) + 3
    l.append(m)
    l.append(0)
    l = sorted(l)

    # Part 1
    d = [0,0,0,0]
    for i in range(1,len(l)):
        d[l[i]-l[i-1]] += 1
    print(d[1]*d[3])

    # Part 2
    d = DiGraph()
    for i in range(1,len(l)):
        for j in range(max(0,i-3),i):
            if l[i]-l[j] <= 3:
                d.add_edge(l[j], l[i])

    counter = Counter({0 : 1})
    todo = [0]
    visited = set()
    to_visit = {0}
    while todo:
        v = todo.pop()
        visited.add(v)
        neighbors = sorted(list(d.neighbors_out(v)))
        for u in neighbors:
            counter[u] += counter[v]
            if u not in to_visit:
                to_visit.add(u)
                todo = [u] + todo
    print(counter[m])


# Imports
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split

# Load the data
train_data = 'train.csv'
train = pd.read_csv(train_data)
test_data = '/test.csv'
test = pd.read_csv(test_data)

## EDA AND PREPROCESSING
########################
# Checking for missing values in train set
train.isnull().sum()
# Checking for missing values in test set
test.isnull().sum()
# Function to replace missing values with the median
def replace_with_median(df, column_name):
    median_value = df[column_name].median()
    df[column_name].fillna(median_value, inplace=True)
# Replacing empty strings with NaN in train
train.replace('', np.nan, inplace=True)
# Replacing empty strings with NaN in test
test.replace('', np.nan, inplace=True)
# Checking missing values in train set after replacing empty strings
train.isnull().sum()
# Replacing the missing 'Embarked' values with the most frequent 'S'
train["Embarked"].fillna("S", inplace=True)
test["Embarked"].fillna("S", inplace=True)
# Replacing missing values of 'Age' column with the median
replace_with_median(train, 'Age')
replace_with_median(test, 'Age')
# Dropping 'Cabin', 'Name', 'Ticket', and 'PassengerId' columns in train and test
train.drop(['Cabin', 'Name', 'Ticket', 'PassengerId'], axis=1, inplace=True)
test.drop(['Cabin', 'Name', 'Ticket', 'PassengerId'], axis=1, inplace=True)
# Replacing rows of 'Fare' column in test set where values are NaN with the median
replace_with_median(test, 'Fare')
# Replacing categorical values of 'Sex' column by dummy variables
train = pd.get_dummies(train, columns=['Sex'], drop_first=True)
test = pd.get_dummies(test, columns=['Sex'], drop_first=True)
# Replacing categorical values of 'Embarked' column by dummy variables
train = pd.get_dummies(train, columns=['Embarked'], prefix='Embarked', drop_first=True)
test = pd.get_dummies(test, columns=['Embarked'], prefix='Embarked', drop_first=True)
# Checking data types of all columns in train set
train_data_types = train.dtypes
print("\nData types in train set:")
print(train_data_types)
# Checking data types of all columns in test set
test_data_types = test.dtypes
print("\nData types in test set:")
print(test_data_types)

## SPLIT AND STANDARDIZE THE DATA
#################################
X_train = train.iloc[:,1:].values
y_train = train.iloc[:,0].values
X_test = test.iloc[:,:]
X_test.isnull().sum()
# Initialize the StandardScaler
sc = StandardScaler()
# Feature Scaling for the full X_train and X_test
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)
# Further split X_train into X_train_train and X_train_test for gaining more insights
X_train_train, X_train_test, y_train_train, y_train_test = train_test_split(X_train, y_train, test_size=0.25, random_state=42)

## BUILD THE FNN MODEL
######################
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
# Define the FNN model
class FNN(nn.Module):
    def __init__(self, input_size):
        super(FNN, self).__init__()
        self.fc1 = nn.Linear(input_size, 14)
        self.relu1 = nn.ReLU()
        self.fc2 = nn.Linear(14, 14)
        self.relu2 = nn.ReLU()
        self.fc3 = nn.Linear(14, 1)
        self.sigmoid = nn.Sigmoid()
    def forward(self, x):
        x = self.fc1(x)
        x = self.relu1(x)
        x = self.fc2(x)
        x = self.relu2(x)
        x = self.fc3(x)
        x = self.sigmoid(x)
        return x
# Initialize the FNN model
input_size = X_train_train.shape[1]
model = FNN(input_size)
# Define the optimizer
optimizer = optim.Adam(model.parameters(), lr=0.001)
# Define the loss function
criterion = nn.BCELoss()
# Training loop
n_epochs = 100
for epoch in range(n_epochs):
    optimizer.zero_grad()
    outputs = model(torch.tensor(X_train_train, dtype=torch.float32))
    loss = criterion(outputs, torch.tensor(y_train_train, dtype=torch.float32).view_as(outputs))
    loss.backward()
    optimizer.step()
# Predicting the training set results
with torch.no_grad():
    y_pred_train = model(torch.tensor(X_train_train, dtype=torch.float32))
    y_pred_train = (y_pred_train > 0.5)
# Convert predictions to a NumPy array
y_pred_train = y_pred_train.numpy()

## EVALUATION OF THE MODEL
# ########################

# Accuracy Score
from sklearn.metrics import accuracy_score
accuracy = accuracy_score(y_train_train, y_pred_train)
print("Accuracy of the model:", accuracy)
# Filter training data for male survivors
male_survivors = train[(train['Sex_male'] == 1) & (train['Survived'] == 1)]
# Filter training data for female survivors
female_survivors = train[(train['Sex_male'] == 0) & (train['Survived'] == 1)]
# Calculate the percentage of male survivors
percentage_male_survived = (len(male_survivors) / len(train[train['Sex_male'] == 1])) * 100
# Calculate the percentage of female survivors
percentage_female_survived = (len(female_survivors) / len(train[train['Sex_male'] == 0])) * 100

# RESULTS
# Accuracy of the model 0.74
# Percentage of male survivors: 18.89%
#Percentage of female survivors: 74.20%

Deep Learning/2. Feedforward Neural Network (FNN)/Script_Titanic.py


from datafs import DataAPI
from datafs.core.data_archive import DataArchive
from datafs.managers.manager_dynamo import DynamoDBManager
from fs.s3fs import S3FS
from fs.osfs import OSFS

import tempfile
import shutil

tmpdir = tempfile.mkdtemp()

class MyArchive(DataArchive):

    def delete(self):
        raise IOError('Data archives cannot be deleted')

class MyAPI(DataAPI):

    _ArchiveConstructor = MyArchive
    '''
    ``MyArchive`` objects will be created instead of ``DataArchive`` objects
    '''

    def __init__(self, AWS_ACCESS_KEY, AWS_SECRET_KEY, *args, **kwargs):
        super(MyAPI, self).__init__(*args, **kwargs)

        # pre-configure the API with your organization's setup

        manager = DynamoDBManager(
            table_name='project_data',
            session_args={
                'aws_access_key_id': AWS_ACCESS_KEY,
                'aws_secret_access_key': AWS_SECRET_KEY},
            resource_args={
                'endpoint_url': 'http://localhost:8000/',
                'region_name': 'us-east-1'})

        if 'project_data' in manager.table_names:
            manager.delete_table('project_data')

        manager.create_archive_table('project_data', raise_on_err=False)

        self.attach_manager(manager)

        # Prevent changes to the manager configuration
        self.lock_manager()

        s3_bucket1 = S3FS(
            'org-bucket-1',
            aws_access_key=AWS_ACCESS_KEY,
            aws_secret_key=AWS_SECRET_KEY)

        s3_bucket2 = S3FS(
            'org-bucket-2',
            aws_access_key=AWS_ACCESS_KEY,
            aws_secret_key=AWS_SECRET_KEY)

        network_storage = OSFS(tmpdir)

        self.attach_authority('s3-1', s3_bucket1)
        self.attach_authority('s3-2', s3_bucket2)
        self.attach_authority('NAT-1', network_storage)

        # Prevent changes to the set of authorities
        self.lock_authorities()

def teardown():
    shutil.rmtree(tmpdir)


import pytest

from .. import tasks
from ..models import ReleaseNote

pytestmark = pytest.mark.django_db(transaction=True)

def test_update_task(rn_testdata):
    initial_count = ReleaseNote.objects.count()
    assert initial_count == 52
    tasks.check_if_release_note_update_needed(
        override_file="looking_for_group/releasenotes/tests/test_changelog_updated.rst"
    )
    assert ReleaseNote.objects.count() - initial_count == 1


import os
import argparse

"""
Given keypoint annotation by open3d, this script transfer the annotation
to the required info used for training. The resultant yaml file is save to
the processed/ subdirectory for each scene.
"""
parser = argparse.ArgumentParser()
parser.add_argument('--log_root_path',
                    type=str, default='/home/wei/data/pdc/logs_proto',
                    help='The root path that contains lots of scene recorded at different time')
parser.add_argument('--scene_mesh_keypoint_path', type=str, default='keypoint.yaml',
                    help='The keypoint annotation input for each scene. '
                         'Note that this file will be relative to ${log_root_path}/2018-05-14.../processed/ folder')
parser.add_argument('--scene_image_keypoint_output_path', type=str, default='shoe_6_keypoint_image.yaml',
                    help='The image keypoint for each scene. '
                         'Note that this file will be relative to ${log_root_path}/2018-05-14.../processed/ folder')
args = parser.parse_args()

def main():
    # Get the exe file
    dir_path = os.path.dirname(os.path.realpath(__file__))
    bbox_exe_file = os.path.join(dir_path, 'bbox_from_mask_all.py')
    dir_path = os.path.abspath(os.path.join(dir_path, os.pardir))
    keypoint_exe_file = os.path.join(dir_path, 'keypoint_mesh2img.py')

    # the tmp file for keypoint image projection
    image_keypoint_tempfile = 'scene_bbox_keypoint_tmp.yaml'

    # Get the root keypoint
    log_root: str = args.log_root_path
    processed_counter = 0
    skip_counter = 0
    for folder in os.listdir(log_root):
        scene_log_path = os.path.join(log_root, folder)
        scene_processed_path = os.path.join(scene_log_path, 'processed')
        if os.path.isdir(scene_log_path):
            keypoint_yaml_path = os.path.join(scene_processed_path, args.scene_mesh_keypoint_path)
            output_yaml_path = os.path.join(scene_processed_path, image_keypoint_tempfile)
            if not os.path.exists(keypoint_yaml_path):
                print('Keypoint in %s is not founded!' % scene_log_path)
                skip_counter += 1
                continue

            # Run the python command
            command = 'python %s --keypoint_yaml_path %s --scene_log_path %s --output_yaml_path %s' \
                      % (keypoint_exe_file, keypoint_yaml_path, scene_log_path, output_yaml_path)
            print(command)
            os.system(command)
            processed_counter += 1

    # Also annotate the bounding box
    bbox_command = 'python %s --log_root_path %s --pose_yaml_filename %s --output_yaml_name %s' \
                   % (bbox_exe_file, log_root, image_keypoint_tempfile, args.scene_image_keypoint_output_path)
    print(bbox_command)
    os.system(bbox_command)

    # The cleanup
    for folder in os.listdir(log_root):
        scene_log_path = os.path.join(log_root, folder)
        scene_processed_path = os.path.join(scene_log_path, 'processed')
        if os.path.isdir(scene_log_path):
            tmp_yaml_path = os.path.join(scene_processed_path, image_keypoint_tempfile)
            if os.path.exists(tmp_yaml_path):
                os.remove(tmp_yaml_path)

    # Some info
    print('Processed logs (scenes) %d, while %d scene does not have keypoint.' % (processed_counter, skip_counter))

if __name__ == '__main__':
    main()


# initial_search_query.py
# By Anton A Rakos

# Can be ran with python3.7 initial_search_query.py

# This script houses the functions for processing an initial search query.

class Tokenize_search_query:

	def __init__(self, given_input):
		self.input_query = given_input
		self.all_links = []
		self.basic_search = []
		self.decoy1_search = []
		self.decoy2_search = []
		self.start_search_query()
		self.write_binary()

	def get_decoys(self, target):
		decoy1_search = []
		import wikipedia
		while len(decoy1_search) < target:
			try:
				decoy1 = wikipedia.page(wikipedia.random())
				decoy1_query = wikipedia.search(decoy1)

				for i in range(len(decoy1_query)):
					if len(decoy1_search) >= target:

						break
					else:
						try:
							member0 = wikipedia.page(decoy1_query[i])
							member0_list = member0.references
							for j in range(len(member0_list)):
								decoy1_search += [['00', member0_list[j]]]
								if len(decoy1_search) >= target:
									break

						except:
							continue

			except:
				continue

		return decoy1_search

	def start_search_query(self):
		import wikipedia

		wikipedia.set_lang("en")
		print(self.input_query)
		basic_query =  wikipedia.search(self.input_query)
		print(len(basic_query))
		print(basic_query)
		for i in range(len(basic_query)):
			if len(self.basic_search) >= 256:
				break
			try:
				member0 = wikipedia.page(basic_query[i])
				member0_list = member0.references
				go_0 = 1
				go_1 = 0
				go_2 = 0
				go_3 = 0
				go_4 = 0
				go_5 = 0
				go_6 = 0
				go_7 = 0
				go_8 = 0
				go_9 = 0
				go_10 = 0
				go_11 = 0
				go_12 = 0
				go_13 = 0
				go_14 = 0
				go_15 = 0
				for j in range(len(member0_list)):
					if(go_0 == 1):
						self.basic_search += [['01', member0_list[j]]]
						go_0 = 0
						go_1 = 1
					elif(go_1 == 1):
						self.basic_search += [['02', member0_list[j]]]
						go_1 = 0
						go_2 = 1
					elif(go_2 == 1):
						self.basic_search += [['03', member0_list[j]]]
						go_2 = 0
						go_3 = 1
					elif(go_3 == 1):
						self.basic_search += [['04', member0_list[j]]]
						go_3 = 0
						go_4 = 1
					elif(go_4 == 1):
						self.basic_search += [['05', member0_list[j]]]
						go_4 = 0
						go_5 = 1
					elif(go_5 == 1):
						self.basic_search += [['06', member0_list[j]]]
						go_5 = 0
						go_6 = 1
					elif(go_6 == 1):
						self.basic_search += [['07', member0_list[j]]]
						go_6 = 0
						go_7 = 1
					elif(go_7 == 1):
						self.basic_search += [['08', member0_list[j]]]
						go_7 = 0
						go_8 = 1
					elif(go_8 == 1):
						self.basic_search += [['09', member0_list[j]]]
						go_8 = 0
						go_9 = 1
					elif(go_9 == 1):
						self.basic_search += [['10', member0_list[j]]]
						go_9 = 0
						go_10 = 1
					elif(go_10 == 1):
						self.basic_search += [['11', member0_list[j]]]
						go_10 = 0
						go_11 = 1
					elif(go_11 == 1):
						self.basic_search += [['12', member0_list[j]]]
						go_11 = 0
						go_12 = 1
					elif(go_12 == 1):
						self.basic_search += [['13', member0_list[j]]]
						go_12 = 0
						go_13 = 1
					elif(go_13 == 1):
						self.basic_search += [['14', member0_list[j]]]
						go_13 = 0
						go_14 = 1
					elif(go_14 == 1):
						self.basic_search += [['15', member0_list[j]]]
						go_14 = 0
						go_15 = 1
					elif(go_15 == 1):
						self.basic_search += [['16', member0_list[j]]]
						go_15 = 0
						go_0 = 1

					if len(self.basic_search) >= 256:
						break
			except:
				continue

		self.decoy1_search = self.get_decoys(len(self.basic_search))
		self.decoy2_search = self.get_decoys(len(self.basic_search))

		print(self.basic_search)
		print(len(self.decoy1_search))
		print(len(self.decoy2_search))

	def write_binary(self):
		output_file = open("search_domain.txt", "w")

		for i in range(len(self.basic_search)):
			output_file.write(self.basic_search[i][0]+self.basic_search[i][1]+'\n')
			output_file.write(self.decoy1_search[i][0]+self.decoy1_search[i][1]+'\n')
			output_file.write(self.decoy2_search[i][0]+self.decoy2_search[i][1]+'\n')

		output_file.close()

import sys
import os

search_list = sys.argv[1:]
search_this = ' '.join(map(str,search_list ))
app = Tokenize_search_query(search_this)
os.system("rm logged*")
os.system("./runthisthread")
os.system("./runeval '"+search_this+"'")


from django.shortcuts import render, get_object_or_404
from django.views.generic import View,ListView, DetailView, CreateView, UpdateView, DeleteView, TemplateView, FormView
from .models import Topic, Reply
from Interactions.models import VoteContent, CommentContent
from Development.models import ContentCategory
from .forms import TopicCreateForm, TopicEditForm, TopicCommentForm, ReplyCreateForm, TopicCreateInCatForm, ReplyEditForm
from django.urls import reverse_lazy
from django.core.paginator import Paginator
from django.http import HttpResponseRedirect
from django.contrib.contenttypes.models import ContentType
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin

def get_category_path(cat, current_path=""):
    if cat.parent_category:
        new_path = " > "
        new_path += str(cat.title)
        new_path += current_path
        return get_category_path(cat.parent_category, current_path=new_path)

    else:
        new_path = str(cat.title)
        new_path += current_path
        return new_path

def TopicCategoryView(request, cat_id):
    category = ContentCategory.objects.get(id=cat_id)
    skill_area_topics = Topic.objects.filter(category=cat_id)
    paginator = Paginator(skill_area_topics, 5)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    return render(request, 'community_view_category.html', {"category": category,
                                                        "skill_area_topics": page_obj})

class CommunityHomeView(TemplateView):
    template_name = "community_home.html"
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        skill_topic_set = {}
        for category in ContentCategory.objects.filter(global_standard=True):
            filtered_results = (get_category_path(category), list(Topic.objects.filter(category=category.id).order_by('-publish_date', '-publish_time')[:5]))
            skill_topic_set[category] = filtered_results
        x = sorted(skill_topic_set.items(), key=lambda x: x[1][0])

        context["category_topics"] = {k:v for k,v in x}
        return context

###############################################################################################
### For viewing a topic, replying and making comments

def create_comment_lists_by_len(qs, l_len):

    pagi_comments = []
    pagi_builder = []
    for comment in qs:
        if len(pagi_builder) >= l_len:
            pagi_comments.append(pagi_builder)
            pagi_builder = []
        pagi_builder.append(comment)
    pagi_comments.append(pagi_builder)

    return pagi_comments

def TopicView(request, pk):

    topic = get_object_or_404(Topic,id=pk)#

    topic_comment_form = TopicCommentForm(request.POST or None)#
    reply_comment_form = TopicCommentForm(request.POST or None)#
    template_name = "topic_view.html"
    topic_comment_split_list = []
    reply_comment_split_list = []
    all_replies_and_comments = []
    topic_votes = []
    if request.method == "GET":
    ### FOR TOPIC COMMENTS
        topic_comments = CommentContent.objects.filter_by_instance(topic)
        topic_votes = VoteContent.objects.filter_by_instance_vote_counts(topic)
        if topic_comments:
            topic_comments_votes = []
            for comment in topic_comments:
                comment_votes = VoteContent.objects.filter_by_instance_vote_counts(comment)
                topic_comments_votes.append((comment, comment_votes))
            topic_comment_split_list = create_comment_lists_by_len(topic_comments_votes, 5)

    ### FOR TOPIC REPLIES
        #### Check is there are replies
        topic_replies = Reply.objects.filter(on_post=pk)
        if topic_replies:
        ### Loop through the replies
            for topic_reply in topic_replies:
####################################################################################################
#### GETS REPLIES, THERE COMMENTS, AND THE COMMENTS VOTE COUNTS
            #### Find any comments replated to an individual reply
                reply_votes = VoteContent.objects.filter_by_instance_vote_counts(topic_reply)

                reply_comments = CommentContentContent.objects.filter_by_instance(topic_reply)
                reply_comments_votes = []
                if reply_comments:
                    for comment in reply_comments:

                        comment_votes = VoteContent.objects.filter_by_instance_vote_counts(comment)
                        reply_comments_votes.append((comment, comment_votes))

                    reply_comment_split_list = create_comment_lists_by_len(reply_comments_votes, 5)
            ### Save a single reply and all its comments as a tuple to a list of every reply and comment
                    all_replies_and_comments.append(((topic_reply, reply_votes),reply_comment_split_list))

                else:
                    all_replies_and_comments.append((
                                                    (topic_reply,reply_votes),
                                                    ))

####################################################################################################
#### COMMENT POSTING

#### topic

    if request.method =="POST" and 'commentfortopic' in request.POST:
        if request.user:
            if topic_comment_form.is_valid():
                c_body = topic_comment_form.cleaned_data.get('content_body')
                new_comment = CommentContent(author=request.user, content_type=ContentType.objects.get_for_model(Topic),body=c_body, object_id=topic.id)
                new_comment.save()
                return HttpResponseRedirect(request.path)
            else:
                print("form isnt valid")
        else:

            messages.info(request, 'You must be logged in to commment')

            return HttpResponseRedirect(request.path)
#### reply
    if request.method =="POST" and 'commentforreply' in request.POST:
        if request.user:
            if reply_comment_form.is_valid():
                c_body = reply_comment_form.cleaned_data.get('content_body')
                new_comment = CommentContent(author=request.user, content_type=ContentType.objects.get_for_model(Reply),body=c_body, object_id=request.POST['object_id'])
                new_comment.save()
                return HttpResponseRedirect(request.path)
            else:
                print("form isnt valid")
        else:
            messages.info(request, 'You must be logged in to commment')
            return HttpResponseRedirect(request.path)

####################################################################################################
#### TOPIC VOTING

#### UP
    if request.method =="POST" and 'topic_vote_up' in request.POST:
        past_vote = VoteContent.objects.filter_by_instance(topic)
        if request.user:
            user_votes = past_vote.filter(votee=request.user)
            if user_votes:
                messages.info(request, 'You have already voted')
                return HttpResponseRedirect(f"{request.path}/1")
            new_vote = VoteContent(votee=request.user, content_type=ContentType.objects.get_for_model(Topic), object_id=topic.id, is_up_vote=True)
            new_vote.save()
            messages.success(request, 'Thankyou for your opinion - it might help others find what they need!')

            return HttpResponseRedirect(request.path)
        else:
            messages.info(request, 'You must be logged in to vote')
            return HttpResponseRedirect(request.path)

#### DOWN
    if request.method =="POST" and 'topic_vote_down' in request.POST:
        past_vote = VoteContent.objects.filter_by_instance(topic)
        if request.user:
            user_votes = past_vote.filter(votee=request.user)
            if user_votes:
                messages.info(request, 'You have already voted')
                return HttpResponseRedirect(request.path)
            else:
                new_vote = VoteContent(votee=request.user, content_type=ContentType.objects.get_for_model(Topic), object_id=topic.id, is_up_vote=False)
                new_vote.save()
                messages.success(request, 'Thankyou for your opinion - it might help others find what they need!')
                return HttpResponseRedirect(request.path)
        else:
            messages.info(request, 'You must be logged in to vote')
            return HttpResponseRedirect(request.path)

####################################################################################################
#### Comment voting

#### UP
    if request.method =="POST" and 'comment_vote_up' in request.POST:
        obj_id = request.POST["topic_comment_id_to_vote_up"]
        comment_instance = CommentContent.objects.get(id=obj_id)
        past_vote = VoteContent.objects.filter_by_instance(comment_instance)
        if request.user:
            user_votes = past_vote.filter(votee=request.user)
            if user_votes:
                messages.info(request, 'You have already voted')
                return HttpResponseRedirect(request.path)
            else:
                new_vote = VoteContent(votee=request.user, content_type=ContentType.objects.get_for_model(CommentContent), object_id=obj_id, is_up_vote=True)
                new_vote.save()
                messages.success(request, 'Thankyou for your opinion - it might help others find what they need!')
                return HttpResponseRedirect(request.path)
        else:
            messages.info(request, 'You must be logged in to vote')
            return HttpResponseRedirect(request.path)

#### DOWN
    if request.method =="POST" and 'comment_vote_down' in request.POST:
        obj_id = request.POST["topic_comment_id_to_vote_down"]
        comment_instance = CommentContent.objects.get(id=obj_id)
        past_vote = VoteContent.objects.filter_by_instance(comment_instance)
        if request.user:
            user_votes = past_vote.filter(votee=request.user)
            if user_votes:
                messages.info(request, 'You have already voted')
                return HttpResponseRedirect(request.path)
            else:
                x =request.POST["reply_id_to_vote"]
                new_vote = VoteContent(votee=request.user, content_type=ContentType.objects.get_for_model(CommentContent), object_id=obj_id, is_up_vote=False)
                new_vote.save()
                messages.success(request, 'Thankyou for your opinion - it might help others find what they need!')
                return HttpResponseRedirect(request.path)
        else:
            messages.info(request, 'You must be logged in to vote')
            return HttpResponseRedirect(request.path)

####################################################################################################
#### Reply voting

#### UP
    if request.method =="POST" and "reply_vote_up" in request.POST:
        obj_id = request.POST["reply_id_to_vote_up"]
        reply_instance = Reply.objects.get(id=obj_id)
        past_vote = VoteContent.objects.filter_by_instance(reply_instance)
        if request.user:
            user_votes = past_vote.filter(votee=request.user)
            if user_votes:
                messages.info(request, 'You have already voted')
                return HttpResponseRedirect(request.path)
            else:
                new_vote = VoteContent(votee=request.user, content_type=ContentType.objects.get_for_model(Reply), object_id=obj_id, is_up_vote=True)
                new_vote.save()
                messages.success(request, 'Thankyou for your opinion - it might help others find what they need!')
                return HttpResponseRedirect(request.path)
        else:
            messages.info(request, 'You must be logged in to vote')
            return HttpResponseRedirect(request.path)

#### Down
    if request.method =="POST" and 'reply_vote_down' in request.POST:
        obj_id = request.POST["reply_id_to_vote_down"]
        reply_instance = Reply.objects.get(id=obj_id)
        past_vote = VoteContent.objects.filter_by_instance(reply_instance)
        if request.user:
            user_votes = past_vote.filter(votee=request.user)
            if user_votes:
                messages.info(request, 'You have already voted')
                return HttpResponseRedirect(request.path)
            else:
                new_vote = VoteContent(votee=request.user, content_type=ContentType.objects.get_for_model(Reply), object_id=obj_id, is_up_vote=False)
                new_vote.save()
                messages.success(request, 'Thankyou for your opinion - it might help others find what they need!')
                return HttpResponseRedirect(request.path)
        else:
            messages.info(request, 'You must be logged in to vote')
            return HttpResponseRedirect(request.path)
####################################################################################################

####################################################################################################
#### Reply comment voting

#### UP
    if request.method =="POST" and "reply_comment_vote_up" in request.POST:
        obj_id = request.POST["reply_comment_id_to_vote_up"]
        reply_comment_instance = CommentContent.objects.get(id=obj_id)
        past_vote = VoteContent.objects.filter_by_instance(reply_comment_instance)
        if request.user:
            user_votes = past_vote.filter(votee=request.user)
            if user_votes:
                messages.info(request, 'You have already voted')
                return HttpResponseRedirect(request.path)
            else:
                new_vote = VoteContent(votee=request.user, content_type=ContentType.objects.get_for_model(CommentContent), object_id=obj_id, is_up_vote=True)
                new_vote.save()
                messages.success(request, 'Thankyou for your opinion - it might help others find what they need!')
                return HttpResponseRedirect(request.path)
        else:
            messages.info(request, 'You must be logged in to vote')
            return HttpResponseRedirect(request.path)

#### Down
    if request.method =="POST" and 'reply_comment_vote_down' in request.POST:
        obj_id = request.POST["reply_comment_id_to_vote_down"]
        reply_comment_instance = CommentContent.objects.get(id=obj_id)
        past_vote = VoteContent.objects.filter_by_instance(reply_comment_instance)
        if request.user:
            user_votes = past_vote.filter(votee=request.user)
            if user_votes:
                messages.info(request, 'You have already voted')
                return HttpResponseRedirect(request.path)
            else:
                new_vote = VoteContent(votee=request.user, content_type=ContentType.objects.get_for_model(CommentContent), object_id=obj_id, is_up_vote=False)
                new_vote.save()
                messages.success(request, 'Thankyou for your opinion - it might help others find what they need!')
                return HttpResponseRedirect(request.path)
        else:
            messages.info(request, 'You must be logged in to vote')
            return HttpResponseRedirect(request.path)
####################################################################################################

    context = {
                "topic": topic,
                "pagi_comments": topic_comment_split_list[:min(len(topic_comment_split_list), 6)],
                "topic_comment_form": topic_comment_form,
                "topic_replies": all_replies_and_comments,
                "reply_comment_form": reply_comment_form,
                "topic_votes": topic_votes,
                }

    return render(request, template_name, context)

class ReplyEdit(LoginRequiredMixin,UpdateView):
    login_url = '/login-or-register/'
    redirect_field_name = 'redirect_to'
    model = Reply
    form_class = ReplyEditForm
    template_name = "reply_edit.html"
###############################################################################################
### For viewing a topic, replying and making comments
class TopicCreate(LoginRequiredMixin,CreateView):
    login_url = '/login-or-register/'
    redirect_field_name = 'redirect_to'
    model = Topic
    form_class = TopicCreateForm
    template_name = "topic_create.html"

class ReplyCreate(LoginRequiredMixin,CreateView):
    login_url = '/login-or-register/'
    redirect_field_name = 'redirect_to'
    model = Reply
    form_class = ReplyCreateForm
    template_name = "reply_create.html"
    def get_success_url(self, **kwargs):
        return reverse_lazy('topic-view', args=(self.kwargs['pk'],))

    def get_context_data(self, **kwargs):
        self.reply_to = get_object_or_404(Topic, id=self.kwargs['pk'])
        kwargs['topic'] = self.reply_to
        return super().get_context_data(**kwargs)

    def form_valid(self, form):
        reply_to = get_object_or_404(Topic, id=self.kwargs['pk'])
        obj = form.save(commit=False)
        form.instance.author = self.request.user
        form.instance.on_post = reply_to
        messages.success(self.request, 'Your reply has been posted successfully')
        return super().form_valid(form)

class TopicCreateInCat(LoginRequiredMixin,CreateView):
    login_url = '/login-or-register/'
    redirect_field_name = 'redirect_to'
    model = Topic
    form_class = TopicCreateInCatForm
    template_name = "topic_create_in_cat.html"

    def get_success_url(self, **kwargs):
        return reverse_lazy('community-home')

    def get_context_data(self, **kwargs):
        on_cat = ContentCategory.objects.get(id=self.kwargs['cat_id'])
        kwargs['category'] = on_cat
        return super().get_context_data(**kwargs)

    def form_valid(self, form):
        form.instance.category = ContentCategory.objects.get(id=self.kwargs['cat_id'])
        form.instance.author = self.request.user
        messages.success(self.request, 'Your Topic has been posted successfully')
        return super().form_valid(form)

class TopicEdit(LoginRequiredMixin,UpdateView):
    login_url = '/login-or-register/'
    redirect_field_name = 'redirect_to'
    model= Topic
    form_class = TopicEditForm
    template_name = 'topic_edit.html'

class TopicDelete(LoginRequiredMixin,DeleteView):
    login_url = '/login-or-register/'
    redirect_field_name = 'redirect_to'
    model= Topic
    template_name = 'topic_delete.html'
    success_url = reverse_lazy('home')