import torch
import torchvision
import torch.nn as nn
from torch.nn import init

from torch.autograd import Variable
import torch.nn.functional as F
import torchvision.models as models
from collections import namedtuple
import torchvision.utils as vutils
import time

###########################################
##   Layers and Blocks
#------------------------------------------

class InstanceNorm(nn.Module):
    def __init__(self, epsilon=1e-8, style_num=1):
        """
            @notice: avoid in-place ops.
            https://discuss.pytorch.org/t/encounter-the-runtimeerror-one-of-the-variables-needed-for-gradient-computation-has-been-modified-by-an-inplace-operation/836/3
        """
        super(InstanceNorm, self).__init__()
        self.epsilon = epsilon

        self.style_num = style_num

        self.x_max = [None for x in range(self.style_num)]
        self.x_min = [None for x in range(self.style_num)]

        self.saved_mean = [None for x in range(self.style_num)]
        self.saved_std = [None for x in range(self.style_num)]

    def forward(self, x, style_weight=[1.]):
        tmp_saved_mean = 0.
        tmp_saved_std = 0.
        tmp_x_min = 0.
        tmp_x_max = 0.

        for style_id in range(self.style_num):
            tmp_saved_mean += self.saved_mean[style_id] * style_weight[style_id]
            tmp_saved_std += self.saved_std[style_id] * style_weight[style_id]
            tmp_x_min += self.x_min[style_id] * style_weight[style_id]
            tmp_x_max += self.x_max[style_id] * style_weight[style_id]

        x = x - tmp_saved_mean
        x = x * tmp_saved_std

        x = torch.max(tmp_x_min, x)
        x = torch.min(tmp_x_max, x)

        return x

    def compute_norm(self, x, style_id):
        ## mean and std
        self.saved_mean[style_id] = torch.mean(x, (0, 2, 3), True)
        x = x - self.saved_mean[style_id]
        tmp = torch.mul(x, x)
        self.saved_std[style_id] = torch.rsqrt(torch.mean(tmp, (0, 2, 3), True) + self.epsilon)
        x = x * self.saved_std[style_id]

        ## max and min
        tmp_max, _ = torch.max(x, 2, True)
        tmp_max, _ = torch.max(tmp_max, 0, True)
        self.x_max[style_id], _ = torch.max(tmp_max, 3, True)

        tmp_min, _ = torch.min(x, 2, True)
        tmp_min, _ = torch.min(tmp_min, 0, True)
        self.x_min[style_id], _ = torch.min(tmp_min, 3, True)
        return x

    def clean(self):
        self.x_max = [None for x in range(self.style_num)]
        self.x_min = [None for x in range(self.style_num)]

        self.saved_mean = [None for x in range(self.style_num)]
        self.saved_std = [None for x in range(self.style_num)]

class ResidualBlock(nn.Module):
    def __init__(self, input_channel, output_channel, upsample=True, style_num=1):
        super(ResidualBlock, self).__init__()
        self.conv1 = nn.Conv2d(input_channel, output_channel, kernel_size=3, padding=1)
        self.conv2 = nn.Conv2d(output_channel, output_channel, kernel_size=3, padding=1)
        self.conv_shortcut = nn.Conv2d(input_channel, output_channel, kernel_size=1, bias=False)
        self.relu = nn.LeakyReLU(0.2)
        self.norm1 = InstanceNorm(style_num=style_num)
        self.norm2 = InstanceNorm(style_num=style_num)
        self.upsample = upsample
        self.style_num = style_num

    def forward(self, x, style_weight=[1.]):
        if self.upsample:
            x = F.interpolate(x, mode='nearest', scale_factor=2)
        x_s = self.conv_shortcut(x)

        x = self.conv1(x)
        x = self.relu(x)
        x = self.norm1(x, style_weight)
        x = self.conv2(x)
        x = self.relu(x)
        x = self.norm2(x, style_weight)
        return x_s + x

    def compute_norm(self, x, style_id=1):
        if self.upsample:
            x = F.interpolate(x, mode='nearest', scale_factor=2)
        x_s = self.conv_shortcut(x)

        x = self.conv1(x)
        x = self.relu(x)
        x = self.norm1.compute_norm(x, style_id)
        x = self.conv2(x)
        x = self.relu(x)
        x = self.norm2.compute_norm(x, style_id)
        return x_s + x

    def clean(self):
        self.norm1.clean()
        self.norm2.clean()

class FilterPredictor(nn.Module):
    def __init__(self, vgg_channel=512, inner_channel=32, style_num=1):
        super(FilterPredictor, self).__init__()
        self.down_sample = nn.Sequential(
                        nn.Conv2d(vgg_channel, inner_channel, kernel_size=3, padding=1),
                    )
        self.inner_channel = inner_channel
        self.FC = nn.Linear(inner_channel*2,inner_channel*inner_channel)
        self.style_num = style_num
        self.filter = [None for x in range(self.style_num)]

    def forward(self, style_weight=[1.]):
        tmp_filter = 0.
        for style_id in range(self.style_num):
            tmp_filter += self.filter[style_id] * style_weight[style_id]
        return tmp_filter

    def compute(self, content, style, style_id):
        content = self.down_sample(content)
        content = torch.mean(content.view(content.size(0),content.size(1), -1), dim=2)
        content = torch.mean(content, dim=0).unsqueeze(0)

        style = self.down_sample(style)
        style = torch.mean(style.view(style.size(0), style.size(1), -1), dim=2)

        filter = self.FC(torch.cat([content, style],1))
        filter = filter.view(-1, self.inner_channel, self.inner_channel).unsqueeze(3)
        self.filter[style_id] = filter
        return filter

    def clean(self):
        self.filter = [None for x in range(self.style_num)]

class KernelFilter(nn.Module):
    def __init__(self, vgg_channel=512, inner_channel=32, style_num=1):
        super(KernelFilter, self).__init__()
        self.down_sample = nn.Sequential(
                        nn.Conv2d(vgg_channel, inner_channel, kernel_size=3, padding=1),
                    )

        self.upsample = nn.Sequential(
                        nn.Conv2d(inner_channel, vgg_channel, kernel_size=3, padding=1),
                    )

        self.F1 = FilterPredictor(vgg_channel, inner_channel, style_num)
        self.F2 = FilterPredictor(vgg_channel, inner_channel, style_num)

        self.relu = nn.LeakyReLU(0.2)

        self.style_num = style_num

    def apply_filter(self, input_, filter_):
        ''' input_: [B,inC,H,W], filter_: [B,inC,outC,1]
        '''
        B = input_.shape[0]
        input_chunk = torch.chunk(input_, B, dim=0)
        filter_chunt = torch.chunk(filter_, B, dim=0)

        results = []

        for input, filter_ in zip(input_chunk, filter_chunt):
            input = F.conv2d(input, filter_.permute(1,2,0,3), groups=1)
            results.append(input)

        return torch.cat(results,0)

    def forward(self, content, style_weight=[1.]):
        content_ = self.down_sample(content)

        content_ = self.apply_filter(content_, self.F1(style_weight))
        content_ = self.relu(content_)
        content_ = self.apply_filter(content_, self.F2(style_weight))

        return content + self.upsample(content_)

    def clean(self):
        self.F1.clean()
        self.F2.clean()

    def compute(self, content, style, style_id):
        content_ = self.down_sample(content)

        content_ = self.apply_filter(content_, self.F1.compute(content, style, style_id))
        content_ = self.relu(content_)
        content_ = self.apply_filter(content_, self.F2.compute(content, style, style_id))

        return content + self.upsample(content_)

###########################################
##   Networks
#------------------------------------------

class Vgg19(nn.Module):
    def __init__(self, requires_grad=False):
        super(Vgg19, self).__init__()
        vgg_pretrained_features = models.vgg19(pretrained=False).features
        self.slice1 = nn.Sequential()
        self.slice2 = nn.Sequential()
        self.slice3 = nn.Sequential()
        self.slice4 = nn.Sequential()
        for x in range(2):
            self.slice1.add_module(str(x), vgg_pretrained_features[x])
        for x in range(2, 7):
            self.slice2.add_module(str(x), vgg_pretrained_features[x])
        for x in range(7, 12):
            self.slice3.add_module(str(x), vgg_pretrained_features[x])
        for x in range(12, 21):
            self.slice4.add_module(str(x), vgg_pretrained_features[x])
        if not requires_grad:
            for param in self.parameters():
                param.requires_grad = False

    def forward(self, X):
        h = self.slice1(X)
        h_relu1_1 = h
        h = self.slice2(h)
        h_relu2_1 = h
        h = self.slice3(h)
        h_relu3_1 = h
        h = self.slice4(h)
        h_relu4_1 = h
        vgg_outputs = namedtuple("VggOutputs", ['relu1_1', 'relu2_1', 'relu3_1', 'relu4_1'])
        out = vgg_outputs(h_relu1_1, h_relu2_1, h_relu3_1, h_relu4_1)
        return out

class Encoder(nn.Module):
    def __init__(self):
        super(Encoder, self).__init__()
        ## VGG
        vgg_pretrained_features = models.vgg19(pretrained=False).features
        self.slice = nn.Sequential()
        for x in range(21):
            self.slice.add_module(str(x), vgg_pretrained_features[x])

    def forward(self, cur_frame):
        return self.slice(cur_frame)

class EncoderStyle(nn.Module):
    def __init__(self):
        super(EncoderStyle, self).__init__()
        ## VGG
        vgg_pretrained_features = models.vgg19(pretrained=False).features

        self.slice1 = nn.Sequential()
        self.slice2 = nn.Sequential()
        self.slice3 = nn.Sequential()
        self.slice4 = nn.Sequential()

        for x in range(2):
            self.slice1.add_module(str(x), vgg_pretrained_features[x])
        for x in range(2, 7):
            self.slice2.add_module(str(x), vgg_pretrained_features[x])
        for x in range(7, 12):
            self.slice3.add_module(str(x), vgg_pretrained_features[x])
        for x in range(12, 21):
            self.slice4.add_module(str(x), vgg_pretrained_features[x])

    def cal_mean_std(self, feat, eps=1e-5):
        ## eps is a small value added to the variance to avoid divide-by-zero.
        size = feat.size()
        N, C = size[:2]
        feat_var = feat.view(N, C, -1).var(dim=2) + eps
        feat_std = feat_var.sqrt().view(N, C, 1, 1)
        feat_mean = feat.view(N, C, -1).mean(dim=2).view(N, C, 1, 1)

        mean_std = namedtuple("mean_std", ['mean','std'])
        out = mean_std(feat_mean, feat_std)

        return out

    def forward(self, style):
        h = self.slice1(style)
        h_relu1_1 = self.cal_mean_std(h)

        h = self.slice2(h)
        h_relu2_1 = self.cal_mean_std(h)

        h = self.slice3(h)
        h_relu3_1 = self.cal_mean_std(h)

        h = self.slice4(h)
        h_relu4_1 = self.cal_mean_std(h)

        vgg_outputs = namedtuple("VggOutputs", ['map','relu1_1', 'relu2_1', 'relu3_1', 'relu4_1'])
        out = vgg_outputs(h, h_relu1_1, h_relu2_1, h_relu3_1, h_relu4_1)

        return out

class Decoder(nn.Module):
    def __init__(self, style_num=1):
        super(Decoder, self).__init__()

        self.slice4 = ResidualBlock(512, 256, style_num=style_num)
        self.slice3 = ResidualBlock(256, 128, style_num=style_num)
        self.slice2 = ResidualBlock(128, 64, style_num=style_num)
        self.slice1 = nn.Conv2d(64, 3, kernel_size=3, padding=1)

        self.Filter1 = KernelFilter(style_num=style_num)
        self.Filter2 = KernelFilter(style_num=style_num)
        self.Filter3 = KernelFilter(style_num=style_num)

        self.norm = [InstanceNorm(style_num=style_num),
                     InstanceNorm(style_num=style_num),
                     InstanceNorm(style_num=style_num),
                     InstanceNorm(style_num=style_num),
                     InstanceNorm(style_num=style_num)]

        self.style_num = style_num

        self.style_means = [None]
        self.style_stds = [None]

        for layer in range(1,5):
            self.style_means.append([None for i in range(style_num)])
            self.style_stds.append([None for i in range(style_num)])

    #############################
    # For forward Transfer
    # ---------------------------
    def AdaIN(self, content_feat, norm_id, style_weight=[1.]):
        normalized_feat = self.norm[norm_id](content_feat, style_weight)

        style_mean = 0.
        style_std = 0.

        for style_id in range(self.style_num):
            style_mean += self.style_means[norm_id][style_id] * style_weight[style_id]
            style_std += self.style_stds[norm_id][style_id] * style_weight[style_id]

        result =  normalized_feat * style_std + style_mean

        return result

    def AdaIN_filter(self, content_feat, style_weight=[1.]):
        normalized_content = self.norm[0](content_feat, style_weight)
        results = self.Filter1(normalized_content, style_weight)
        results = self.Filter2(results, style_weight)
        results = self.Filter3(results, style_weight)
        return results

    ##########################################
    # For memory-based pre-processing
    # ----------------------------------------

    def AdaIN_compute_norm(self, content_feat, style_feat, norm_id, style_id):
        style_mean = style_feat.mean
        style_std = style_feat.std

        self.style_means[norm_id][style_id] = style_mean
        self.style_stds[norm_id][style_id] = style_std

        normalized_feat = self.norm[norm_id].compute_norm(content_feat, style_id)
        return normalized_feat * style_std + style_mean

    def AdaIN_filter_compute_norm(self, content_feat, style_feat, style_map, style_id):
        style_mean = style_feat.mean
        style_std = style_feat.std

        normalized_content = self.norm[0].compute_norm(content_feat, style_id)
        normalized_style = (style_map - style_mean) / style_std

        results = self.Filter1.compute(normalized_content, normalized_style, style_id)
        results = self.Filter2.compute(results, normalized_style, style_id)
        results = self.Filter3.compute(results, normalized_style, style_id)
        return results

    #############
    # Others
    # -----------

    def clean(self):
        for norm in self.norm:
            norm.clean()

        self.slice4.clean()
        self.slice3.clean()
        self.slice2.clean()

        self.Filter1.clean()
        self.Filter2.clean()
        self.Filter3.clean()

    ##################
    # Processing
    # ----------------

    def compute_norm(self, x, style_features=None):
        for style_id, style_feature in enumerate(style_features):
            h = self.AdaIN_filter_compute_norm(x, style_feature.relu4_1, style_feature.map, style_id)

            h = self.AdaIN_compute_norm(h, style_feature.relu4_1, 1, style_id)
            h = self.slice4.compute_norm(h, style_id)

            h = self.AdaIN_compute_norm(h, style_feature.relu3_1, 2, style_id)
            h = self.slice3.compute_norm(h, style_id)

            h = self.AdaIN_compute_norm(h, style_feature.relu2_1, 3, style_id)
            h = self.slice2.compute_norm(h, style_id)

            h = self.AdaIN_compute_norm(h, style_feature.relu1_1, 4, style_id)

        del h

    def forward(self, x, style_weight=[1.]):
        start = time.time()
        h = self.AdaIN_filter(x, style_weight)

        start = time.time()
        h = self.AdaIN(h, 1, style_weight)

        start = time.time()
        h = self.slice4(h, style_weight)

        start = time.time()
        h = self.AdaIN(h, 2, style_weight)

        start = time.time()
        h = self.slice3(h, style_weight)

        start = time.time()
        h = self.AdaIN(h, 3, style_weight)

        start = time.time()
        h = self.slice2(h, style_weight)

        start = time.time()
        h = self.AdaIN(h, 4, style_weight)

        start = time.time()
        h = self.slice1(h)

        return h

class TransformerNet(nn.Module):
    def __init__(self, style_num=1):
        super(TransformerNet, self).__init__()
        self.Decoder = Decoder(style_num)
        self.Encoder = Encoder()
        self.EncoderStyle = EncoderStyle()
        self.Vgg19 = Vgg19()
        self.have_delete_vgg = False
        self.F_patches = []
        self.F_style = [None for x in range(style_num)]

    def generate_style_features(self, style, style_id):
        self.F_style[style_id] = self.EncoderStyle(style)

    def forward(self, F_content, style_weight=[1.]):
        ## -------------------------------
        ## Stylization

        start = time.time()
        styled_pre_frame = self.Decoder(F_content, style_weight)
        return styled_pre_frame

    def generate_content_features(self, content):
        return self.Encoder(self.RGB2Gray(content))

    def add_patch(self, F_patch):
        self.F_patches.append(F_patch)

    def compute_norm(self):
        self.Decoder.compute_norm(torch.cat(self.F_patches, dim=0), self.F_style)
        self.F_patches = []

    def clean(self):
        self.Decoder.clean()

    def RGB2Gray(self, image):
        mean = image.new_tensor([0.485, 0.456, 0.406]).view(-1, 1, 1)
        std = image.new_tensor([0.229, 0.224, 0.225]).view(-1, 1, 1)

        image = (image*std+mean)

        gray = image[:,2:3,:,:]*0.299 + image[:,1:2,:,:]*0.587 + image[:,0:1,:,:]*0.114
        gray = gray.expand(image.size())

        gray = (gray-mean)/std
        return gray


import pygame
import random
from os import path

img_dir = path.join(path.dirname(__file__), 'img')

WIDTH = 500
HEIGHT = 750
FPS = 60

# define colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

# initialize pygame and create window
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("SHOOT THEM DOWN")
clock = pygame.time.Clock()

font_name = pygame.font.match_font("arial")

def draw_text(surf, text, size, x,y):
    font = pygame.font.Font(font_name, size)
    text_surface = font.render(text, True, WHITE)
    text_rect = text_surface.get_rect()
    text_rect.midtop = (x, y)
    surf.blit(text_surface, text_rect)

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.transform.scale(joueur_image, (80, 68))
        self.image.set_colorkey(BLACK)
        self.rect = self.image.get_rect()
        self.rect.centerx = WIDTH / 2
        self.rect.bottom = HEIGHT - 10
        self.speedx = 0

    #update sert aux mouvement du joueur et bloquer les murs pour ne pas passer a travers

    def update(self):
        self.speedx = 0
        clavier = pygame.key.get_pressed()
        if clavier[pygame.K_LEFT]:
            self.speedx = -6
        if clavier[pygame.K_RIGHT]:
            self.speedx = 6
        self.rect.x += self.speedx
        if self.rect.right > WIDTH:
            self.rect.right = WIDTH
        if self.rect.left < 0:
            self.rect.left = 0

    def shoot(self):
        balle = Projectils(self.rect.centerx, self.rect.top)
        all_sprites.add(balle)
        balles.add(balle)

class Ennemis(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.transform.scale(ennemis_image, (80, 68))
        self.image.set_colorkey(BLACK)
        self.rect = self.image.get_rect()
        self.rect.x = random.randrange(WIDTH - self.rect.width)
        self.rect.y = random.randrange(-100, -40)
        self.speedy = random.randrange(1, 8)
        self.speedx = random.randrange(-3, 3)

    # fais bouger les ennemies et les renvois en haut quand ils sont tout en bas

    def update(self):
        self.rect.x += self.speedx
        self.rect.y += self.speedy
        if self.rect.top > HEIGHT + 10 or self.rect.left < - 20 or self.rect.right > WIDTH:
            self.rect.x = random.randrange(WIDTH - self.rect.width)
            self.rect.y = random.randrange(-100, -40)
            self.speedy = random.randrange(2, 9)

def show_gameover_screen():
    screen.blit(background, background_rect)
    draw_text(screen, "Shootzemup", 64, WIDTH / 2, HEIGHT /4)
    draw_text(screen, "Appuyez sur entrée pour commencer !", 18, WIDTH / 2, HEIGHT / 2)
    pygame.display.flip()
    waiting = True
    while waiting:
        clock.tick(FPS)
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RETURN:
                    waiting = False

class Projectils(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((10, 20))
        self.image.fill(WHITE)
        self.rect = self.image.get_rect()
        self.rect.bottom = y
        self.rect.centerx = x
        self.speedy = -10

    def update(self):
        self.rect.y += self.speedy
        #supprime la balle si elle sort de l'ecran
        if self.rect.bottom < 0:
            self.kill()

#images pour le jeu

background = pygame.image.load(path.join(img_dir, "background.jpg")).convert()
background_rect = background.get_rect()
joueur_image = pygame.image.load(path.join(img_dir, "vaisseau.png")).convert()
ennemis_image = pygame.image.load(path.join(img_dir, "ennemis.png")).convert()

# tous les évenement liés aux touches
game_over = True
running = True

while running:
    if game_over:
        show_gameover_screen()
        game_over = False
        all_sprites = pygame.sprite.Group()
        mobs = pygame.sprite.Group()
        balles = pygame.sprite.Group()
        player1 = Player()
        all_sprites.add(player1)
        for i in range(9):
            enmi1 = Ennemis()
            all_sprites.add(enmi1)
            mobs.add(enmi1)
    # keep loop running at the right speed
    clock.tick(FPS)
    # Process input (events)
    for event in pygame.event.get():
        # check for closing window
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                player1.shoot()
    # Update
    all_sprites.update()
    # voir si une balle touche un ennemi et le supprime si oui
    touche = pygame.sprite.groupcollide(mobs, balles, True, True)
    for touche1 in touche:
        enmi1 = Ennemis()
        all_sprites.add(enmi1)
        mobs.add(enmi1)

    #voir si l'ennemis a touché le vaisseau (colisions) touche = liste et si elle est rempli ça veut dire qu'on a touché

    touche = pygame.sprite.spritecollide(player1, mobs, False)
    if touche:
        game_over = True
    # Draw / render
    screen.fill(BLACK)
    screen.blit(background, background_rect)
    all_sprites.draw(screen)
    # *after* drawing everything, flip the display
    pygame.display.flip()

pygame.quit()


#!/usr/bin/env python3
# coding: utf-8

# Standard imports
from typing import Optional, Tuple
from functools import reduce
import operator

# External imports
import torch
import torch.nn as nn

def conv_bn_leakyrelu(in_channels, out_channels):
    """
    Conv(3x3, same) - BN - LeakyRelu(0.2)
    """
    ks = 3
    return [
        nn.Conv2d(
            in_channels,
            out_channels,
            kernel_size=ks,
            stride=1,
            padding=int((ks - 1) / 2),
            bias=False,
        ),
        nn.BatchNorm2d(out_channels),
        nn.LeakyReLU(negative_slope=0.2),
    ]

def conv_downsampling(channels):
    """
    Conv(3x3, s2) - LeakyRelu(0.2)
    """
    ks = 3
    return [
        nn.Conv2d(
            channels,
            channels,
            kernel_size=ks,
            stride=2,
            padding=int((ks - 1) / 2),
            bias=True,
        ),
        nn.LeakyReLU(negative_slope=0.2),
    ]

class Discriminator(nn.Module):
    """
    The discriminator network tells if the input image is real or not
    The output logit is supposed to be high(-ly positive) for real images
    and low (highly negative) for fake images
    """

    def __init__(
        self, img_shape: Tuple[int, int, int], dropout: float, base_c: int
    ) -> None:
        """
        Args:
            img_shape : (C, H, W) image shapes
            dropout (float) the probability of zeroing before the FC layer
            base_c (int): The base number of channels for the discriminator
        """
        super(Discriminator, self).__init__()
        self.img_shape = img_shape

        in_C = img_shape[0]
        ######################
        # START CODING HERE ##
        ######################
        # Definition of the convolutional part of the classifier
        # Hint : conv_bn_leakyrelu() and conv_downsampling() can
        #        be usefull
        # @TEMPL@self.cnn = None
        # @SOL
        # Note: the output receptive field size is 36 x 36
        #       the output representation size is 3 x 3
        self.cnn = nn.Sequential(
            *conv_bn_leakyrelu(in_C, base_c),
            *conv_bn_leakyrelu(base_c, base_c),
            *conv_downsampling(base_c),
            nn.Dropout2d(dropout),
            *conv_bn_leakyrelu(base_c, base_c * 2),
            *conv_bn_leakyrelu(base_c * 2, base_c * 2),
            *conv_downsampling(base_c * 2),
            nn.Dropout2d(dropout),
            *conv_bn_leakyrelu(base_c * 2, base_c * 3),
            *conv_bn_leakyrelu(base_c * 3, base_c * 3),
            *conv_downsampling(base_c * 3),
            nn.Dropout2d(dropout),
        )
        # SOL@
        ####################
        # END CODING HERE ##
        ####################

        # Compute the size of the representation by forward propagating
        # a fake tensor; This can be cpu tensor as the model is not yet
        # built and therefore not yet transfered to the GPU
        fake_input = torch.zeros((1, *img_shape))
        out_cnn = self.cnn(fake_input)
        print(
            f"The output shape of the convolutional part of the "
            f"discriminator is {out_cnn.shape}"
        )
        num_features = reduce(operator.mul, out_cnn.shape[1:])

        ######################
        # START CODING HERE ##
        ######################
        # The fully connected part of the classifier
        # @TEMPL@self.classif = None
        # @SOL
        self.classif = nn.Sequential(nn.Linear(num_features, 1))
        # SOL@
        ####################
        # END CODING HERE ##
        ####################

        # Run the initialization script
        self.apply(self.init_weights)

    def init_weights(self, m):
        """
        Initialize the weights of the convolutional layers
        """

        with torch.no_grad():
            if isinstance(m, nn.Conv2d):
                torch.nn.init.normal_(m.weight, 0.0, 0.02)
                if m.bias is not None:
                    m.bias.fill_(0.0)

    def forward(self, X: torch.Tensor) -> torch.Tensor:
        """
        Forward pass of the discriminator
        Args:
            X(torch.Tensor (B, C, H, W)) : The images to classify

        Returns:
            Logits (torch.Tensor (B, )) : The logits
        """

        ######################
        # START CODING HERE ##
        ######################
        # Step 1 - Forward pass through the CNN part
        # @TEMPL@out_cnn = None
        out_cnn = self.cnn(X)  # @SOL@

        # Step 2 - "Reshape" the 4D tensor to a 2D tensor
        #  Hint : Tensor.view can be of help
        # @TEMPL@input_classif = None
        input_classif = out_cnn.view((out_cnn.shape[0], -1))  # @SOL@

        # Step 3 - Forward pass through the fully connected layers
        # @TEMPL@out_classif = None
        out_classif = self.classif(input_classif)  # @SOL@
        ####################
        # END CODING HERE ##
        ####################
        return out_classif.squeeze()

def up_conv_bn_relu(in_channels, out_channels):
    """
    Upsampling with Upsample - Conv
    UpSample(x2) - Conv(3x3) - BN - Relu - Conv(3x3) - BN - Relu
    """
    ks = 3
    return [
        nn.Upsample(scale_factor=2),
        nn.Conv2d(
            in_channels,
            out_channels,
            kernel_size=ks,
            stride=1,
            padding=int((ks - 1) / 2),
            bias=False,
        ),
        nn.BatchNorm2d(out_channels),
        nn.ReLU(),
        nn.Conv2d(
            out_channels,
            out_channels,
            kernel_size=ks,
            stride=1,
            padding=int((ks - 1) / 2),
            bias=False,
        ),
        nn.BatchNorm2d(out_channels),
        nn.ReLU(),
    ]

def tconv_bn_relu(in_channels, out_channels, ksize, stride, pad, opad):
    """
    Upsampling with transposed convolutions
    TConv2D - BN - LeakyRelu(0.2)
    """
    return [
        nn.ConvTranspose2d(
            in_channels,
            out_channels,
            kernel_size=ksize,
            stride=stride,
            padding=pad,
            output_padding=opad,
        ),
        nn.BatchNorm2d(out_channels),
        nn.LeakyReLU(negative_slope=0.2),
    ]

class Generator(nn.Module):
    """
    The generator network generates image from random inputs
    """

    def __init__(
        self, img_shape: Tuple[int, int, int], latent_size: int, base_c: int
    ) -> None:
        """
        Args:
            img_shape : (C, H, W) image shapes
            latent_size (int) : The dimension of the latent space
            base_c (int) : The base number of channels
        """
        super(Generator, self).__init__()
        self.img_shape = img_shape
        self.latent_size = latent_size
        self.base_c = base_c

        H, W = img_shape[1:]
        ######################
        # START CODING HERE ##
        ######################
        # Step 1 - Build the feedforward upscaling network
        # @TEMPL@self.upscale = nn.Sequential()
        # @SOL
        print(
            f"Linear with {self.latent_size} -> {H // 4 * W // 4 * self.base_c * 4}, H = {H}, W= {W}, base = {self.base_c}"
        )
        self.upscale = nn.Sequential(
            nn.Linear(self.latent_size, H // 4 * W // 4 * self.base_c * 4, bias=False),
            nn.BatchNorm1d(H // 4 * W // 4 * self.base_c * 4),
            nn.ReLU(),
        )
        # SOL@

        # Step 2 - Build the convolutional upscaling network
        # Hint : up_conv_bn_relu() might be useful
        # @TEMPL@self.model = nn.Sequential()
        # @SOL
        self.model = nn.Sequential(
            *up_conv_bn_relu(self.base_c * 4, self.base_c * 2),
            *up_conv_bn_relu(self.base_c * 2, self.base_c),
            nn.Conv2d(
                self.base_c,
                self.img_shape[0],
                kernel_size=1,
                stride=1,
                padding=0,
                bias=True,
            ),
            nn.Tanh(),
        )
        # SOL@
        ####################
        # END CODING HERE ##
        ####################

        # @SOL
        # Note : size, stride, pad, opad
        # self.model = nn.Sequential(
        #     *tconv_bn_relu2(base_c*4, base_c*2, 5, 1, 2, 0),
        #     # nn.Dropout2d(0.3),
        #     *tconv_bn_relu2(base_c*2, base_c, 5, 2, 2, 1),
        #     # nn.Dropout2d(0.3),
        #     nn.ConvTranspose2d(base_c, 1, 5, 2, 2, 1),
        #     nn.Tanh()  # as suggested by [Radford, 2016]
        # )
        # SOL@

        # Initialize the convolutional layers
        self.apply(self.init_weights)

    def init_weights(self, m):
        with torch.no_grad():
            if isinstance(m, nn.Conv2d):
                torch.nn.init.normal_(m.weight, 0.0, 0.02)
                if m.bias is not None:
                    m.bias.fill_(0.0)

    def forward(
        self, X: Optional[torch.Tensor] = None, batch_size: Optional[float] = None
    ) -> torch.Tensor:
        """
        Forward pass of the generator. You can either provide a noise
        input vector or specify the batch_size to let it generate the input

        Args:
            X (torch.Tensor, optional): The input noise batch
            batch_size (int, optional): The number of samples to generate
        """
        # X is expected to be a 2D tensor (B, L)
        if X is None:
            assert batch_size is not None
            device = next(self.parameters()).device
            X = torch.randn(batch_size, self.latent_size).to(device)
        else:
            if len(X.shape) != 2:
                raise RuntimeError(
                    "Expected a 2D tensor as input to the "
                    f" generator got a {len(X.shape)}D tensor."
                )

        ######################
        # START CODING HERE ##
        ######################
        # Step 1 - Forward pass through the first linear layers
        #          to generate the seed image
        # @TEMPL@upscaled = None
        upscaled = self.upscale(X)  # @SOL@

        # Step 2 - "Reshape" the upscaled image as a 4D tensor
        #  Hint : use the view method
        # @TEMPL@reshaped = None
        reshaped = upscaled.view(
            -1, self.base_c * 4, self.img_shape[1] // 4, self.img_shape[2] // 4
        )  # @SOL@

        # Step 3 : Forward pass through the last convolutional part
        #          to generate the image
        # @TEMPL@out = None
        out = self.model(reshaped)  # @SOL@
        ####################
        # END CODING HERE ##
        ####################

        return out

class GAN(nn.Module):
    def __init__(
        self,
        img_shape: Tuple[int, int, int],
        dropout: float,
        discriminator_base_c: int,
        latent_size: int,
        generator_base_c: int,
    ) -> None:
        """
        Args:
            img_shape : (C, H, W) image shapes
            dropout (float): The probability of zeroing before the FC layers
            discriminator_base_c (int) : The base number of channels for
                                         the discriminator
            latent_size (int) : The size of the latent space for the generator
            generator_base_c (int) : The base number of channels for the
                                     generator
        """
        super(GAN, self).__init__()
        self.img_shape = img_shape
        self.discriminator = Discriminator(img_shape, dropout, discriminator_base_c)
        self.generator = Generator(img_shape, latent_size, generator_base_c)

    def forward(self, X: Optional[torch.Tensor], batch_size: Optional[float]):
        """
        Given true images, returns the generated tensors
        and the logits of the discriminator for both the generated tensors
        and the true tensors

        Args:
            X (torch.Tensor) : a real image or None if we just
                               want the logits for the generated images
            batch_size (int) : the batch to consider when generating
                               fake images
        """

        if X is None and batch_size is None:
            raise RuntimeError("Not both X and batch_size can be None")
        if X is not None and batch_size is not None:
            raise RuntimeError("Not both X and batch_size can be not None")

        if X is not None:
            ######################
            # START CODING HERE ##
            ######################
            # An input tensor of real images is provided
            # we compute its logits
            # 1 line
            # @TEMPL@real_logits = None
            real_logits = self.discriminator(X)  # @SOL@
            ####################
            # END CODING HERE ##
            ####################
            return real_logits, X
        else:
            ######################
            # START CODING HERE ##
            ######################
            # No input tensor is provided. We generate batch_size fake images
            # and evaluate its logits
            # 2 lines
            # @TEMPL@fake_images = None
            # @TEMPL@fake_logits = None
            # @SOL
            fake_images = self.generator(X=None, batch_size=batch_size)
            fake_logits = self.discriminator(fake_images)
            # SOL@
            ####################
            # END CODING HERE ##
            ####################

            return fake_logits, fake_images

# @SOL
def test_tconv():
    layers = nn.Sequential(nn.Conv2d(20, 10, kernel_size=3, stride=1, padding=2))
    print(layers)
    inputs = torch.zeros((1, 20, 2, 2))
    outputs = layers(inputs)
    print(outputs.shape)

    imagify = nn.Linear(100, 7 * 7 * 10)
    conv1 = nn.ConvTranspose2d(10, 10, kernel_size=5, stride=1, padding=2)
    conv2 = nn.ConvTranspose2d(
        10, 10, kernel_size=5, stride=2, padding=2, output_padding=1
    )
    conv3 = nn.ConvTranspose2d(
        10, 1, kernel_size=5, stride=2, padding=2, output_padding=1
    )

    X = torch.randn(64, 100)
    X = imagify(X).view(-1, 10, 7, 7)
    print("--")
    print(X.shape)
    X = conv1(X)
    print(X.shape)
    X = conv2(X)
    print(X.shape)
    X = conv3(X)
    print(X.shape)

# SOL@

def test_discriminator():
    critic = Discriminator((1, 28, 28), 0.3, 32)
    X = torch.randn(64, 1, 28, 28)
    out = critic(X)
    assert out.shape == torch.Size([64])

def test_generator():
    generator = Generator((1, 28, 28), 100, 64)
    X = torch.randn(64, 100)
    out = generator(X, None)
    assert out.shape == torch.Size([64, 1, 28, 28])
    out = generator(None, 64)
    assert out.shape == torch.Size([64, 1, 28, 28])

if __name__ == "__main__":
    test_tconv()  # @SOL@
    test_discriminator()
    test_generator()


import pygame
from pygame.locals import *
import sys, subprocess, time

def main():
    pygame.init()
    screen = pygame.display.set_mode((640, 480))
    pygame.display.set_caption("Side-scrolling Multiplayer Online Platformer")
    clock = pygame.time.Clock()
    font = pygame.font.Font("./font/cour.ttf", 50)
    hotkey_font = pygame.font.Font("./font/cour.ttf",20,bold=pygame.font.Font.bold)
    hotkey_info_surface = hotkey_font.render("ESC : Back  ENTER : Select",True,(255,255,255))

    buttons = ["JOIN GAME", "HOST GAME", "ADDRESS BOOK", "BACK"]
    menu_item = [0,1,2,3]
    current_item = 0

    screen.fill('Black')
    menu_item[0] = font.render(buttons[0], True, "Black")
    menu_item[1] = font.render(buttons[1], True, "White")
    menu_item[2] = font.render(buttons[2], True, "White")
    menu_item[3] = font.render(buttons[3], True, "White")
    pointer = font.render(">", True, "White")
    highlight = pygame.Surface((400, 60))
    highlight.fill('White')

    pointer_y = 100

    screen.blit(highlight,(140,100+(60*current_item)))

    ## loop to check for mouse action and its position ##
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_DOWN:
                    if pointer_y < 280:
                        screen.fill('Black')
                        pointer_y += 60
                        current_item += 1
                        screen.blit(highlight,(140,100+(60*current_item)))
                        menu_item[current_item] = font.render(buttons[current_item], True, "Black")
                        menu_item[current_item-1] = font.render(buttons[current_item-1], True, "White")

                if event.key == pygame.K_RETURN:
                    if current_item == 2:
                        print("Selected ADDRESS BOOK")
                        import ip_config
                        ip_config.main()

                    if current_item == 1:
                        print("Selected HOST GAME")
                        subprocess.Popen(["py","-3","server.py","127.0.0.1"])
                        time.sleep(1)
                        import game
                        game.main("127.0.0.1")

                    if current_item == 3:
                        print("Selected BACK")
                        import menu
                        menu.main()

                    if current_item == 0:
                        print("Selected JOIN GAME")
                        import join_game
                        join_game.main()

                if event.key == pygame.K_ESCAPE:
                    import menu
                    menu.main()

            if event.type == pygame.KEYUP:
                if event.key == pygame.K_UP:
                    if pointer_y > 100:
                        screen.fill('Black')
                        pointer_y -= 60
                        current_item -= 1
                        screen.blit(highlight,(140,100+(60*current_item)))
                        menu_item[current_item+1] = font.render(buttons[current_item+1], True, "White")
                        menu_item[current_item] = font.render(buttons[current_item], True, "Black")

        screen.blit(menu_item[0],(150,100+(60*0)))
        screen.blit(menu_item[1],(150,100+(60*1)))
        screen.blit(menu_item[2],(150,100+(60*2)))
        screen.blit(menu_item[3],(150,100+(60*3)))
        screen.blit(pointer,(100,pointer_y))
        screen.blit(hotkey_info_surface,(10,450))

        pygame.display.update()
        clock.tick(60)


from cmath import inf
import sys
from itertools import accumulate as ac
input = sys.stdin.readline

N, M = map(int, input().split())
nums = [list(map(int, input().split())) for _ in range(N)]

sum_r = []
for num in nums:
    sum_r.append(list(ac(num)))

sum_c = []
for num in zip(*nums):
    sum_c.append(list(ac(num)))

#행을 먼저 검사
Mx = max(sum_r[0][-1], sum_r[-1][-1])
mx = inf
for i in range(1, N-1):
    mx = min(mx, sum_r[i])

#열도 검사
My = max(sum_c[0][-1], sum_c[-1][-1])


from RPI_Operant.hardware.box import Box
import time
import random
from pathlib import Path
experiment_name = Path(__file__).stem
RUNTIME_DICT = {'vole':000, 'day':1, 'experiment':experiment_name, 'side':1}
USER_HARDWARE_CONFIG_PATH = '/home/pi/RPI_Operant2/RPI_Operant/default_setup_files/default_cooperant_hardware.yaml'
USER_SOFTWARE_CONFIG_PATH = '/home/pi/RPI_Operant2/RPI_Operant/default_setup_files/cooperant_magazine.yaml'

box = Box()

def run():
    box.setup(run_dict=RUNTIME_DICT,
              user_hardware_config_file_path=USER_HARDWARE_CONFIG_PATH,
              user_software_config_file_path=USER_SOFTWARE_CONFIG_PATH,
              start_now=True, simulated = True)

    time.sleep(0.5)

    if RUNTIME_DICT['side'] == 1:
        lever = box.levers.lever_1
        speaker = box.speakers.speaker_1
        dispenser = box.port_dispensers.dispenser_1
    elif RUNTIME_DICT['side'] == 2:
        lever = box.levers.lever_2
        speaker = box.speakers.speaker_2
        dispenser = box.port_dispensers.dispenser_2

    for i in range(1,box.software_config['values']['rounds']+1, 1):

        '''vvvvvvvvvvvvv simulation test stuff vvvvvvvvvvv'''
        r1 = random.random()
        if r1 < 0.8:
            sim_press = True
            press_time = random.random()*(2)
            round_start_for_sim = time.time()

        else:
            sim_press = False

        r2 = random.random()
        if r2 < 0.90:
            sim_retrieve = True
        else:
            sim_retrieve = False

        box.timing.new_round(length = box.software_config['values']['round_length'])
        lever_phase = box.timing.new_phase(f'lever_out', length = box.software_config['values']['lever_out_time'])
        press_timeout = box.timing.new_timeout(length = box.software_config['values']['lever_out_to_dispense_time'])

        press_latency = lever.extend()
        lever.wait_for_n_presses(n=1, latency_obj = press_latency)
        test_phase = box.timing.new_phase('format testing', length = 20)
        while press_timeout.active() and lever_phase.active():

            if sim_press:
                if round_start_for_sim + press_time < time.time():
                    lever.simulate_lever_press()
                    time.sleep(0.05)

            if lever.presses_reached:

                lever.retract()
                lever_phase.end_phase()
                speaker.play_tone(tone_name = 'pellet_tone')
                dispenser.dispense()

        if not lever.presses_reached:
            speaker.play_tone(tone_name = 'pellet_tone')
            dispenser.dispense()

        if sim_retrieve:
            retrieve_time = 3 * random.random()
            retrieve_start = time.time()

        while lever_phase.active():
            ''''''
            if sim_retrieve:
                if retrieve_start + retrieve_time > time.time():
                    dispenser.simulate_retrieved()
                    sim_retrieve = False

        phase = box.timing.new_phase(name ='ITI', length = box.timing.round_time_remaining())
        if not lever.presses_reached:
            lever.retract()

        while not box.timing.round_over():
            ''''''
            if sim_retrieve:
                if retrieve_start + retrieve_time < time.time():
                    dispenser.simulate_retrieved()
                    sim_retrieve = False

        phase.end_phase()

    box.shutdown()

if __name__ == '__main__':
    run()


from django import template
from home.models import Evento,Comentario,Usuario

register = template.Library()

@register.inclusion_tag('comentarios/comentarios.html',takes_context=True)
def coments(context,evento):
    request = context['request']
    evento=Evento.objects.get(pk=evento)
    comentarios=evento.Comentarios.all()
    return {'comentarios':comentarios,'usr':request.user}


# Correct Spellings using Python

from spellchecker import SpellChecker

corrector = SpellChecker()

word = input('Enter a word: ')

if word in corrector:
    print('Correct Spelling')
else:
    word = corrector.correction(word)
    print('Right Spelling is :', word)


import dlib
import numpy as np
import cv2
from matplotlib import pyplot as plt

# create VideoCapture object
cap = cv2.VideoCapture('./video/try1.mp4')

# get original size of frame // 取得原影片畫面尺寸
w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# get Frames, fps, code type
fps = cap.get(cv2.CAP_PROP_FPS)  # get Frame Per Second
F_Count = cap.get(cv2.CAP_PROP_FRAME_COUNT)  # get total frames count

# get Frames, fps, code type
fourcc = cv2.VideoWriter_fourcc(*'XVID')  # use FOUR Character Code // 使用 XVID 編碼(MPEG-4)

# create VideoWriter Object // 輸出影片至 output.avi
out = cv2.VideoWriter('./video/test_out.mp4', fourcc, fps, (w, h))

# ------initial settings-------
ag = 0  # frame angle
fsize = 0.1  # frame size
fw = 0  # frame weight

# create kernel // 濾波用矩陣
k = np.ones((7, 7), np.uint8)

# addition for addWeighted
epic = 0

# create Dlib face detector object  # Dlib 的人臉偵測器
detector = dlib.get_frontal_face_detector()

# set the location of Region Of Interest(ROI) // 指定 ROI 座標位置
RECT = ((480, 20), (610, 230))
(left, top), (right, bottom) = RECT

# function for ROI operation
def roiarea(frame):  # 取出 ROI 子畫面
    return frame[top:bottom, left:right]

def replaceroi(frame, roi):  # 將 ROI 區域貼回到原畫面
    frame[top:bottom, left:right] = roi
    return frame

# start playing
while cap.isOpened():
    # read success or not & read frame // ret 讀取成功與否; frame為讀取出來的每一個frame
    ret, frame = cap.read()

    # break if not readable // 未讀取成功則跳出
    if not ret:
        break
    # fixed background // 創建固定背景
    gc = np.full((h, w, 3), 0, dtype='uint8')

    # show basic info of the video(cap)  //  顯示影片基本資訊
    cv2.putText(gc, f'{cap.get(cv2.CAP_PROP_POS_FRAMES)} frames, {cap.get(cv2.CAP_PROP_POS_MSEC):.0f} ms',
                (10, 20), cv2.FONT_HERSHEY_SIMPLEX, .4, (123, 245, 12), 0, cv2.LINE_AA)

    # SHOW TIME !
    # 1.rotate&fade-in
    if cap.get(cv2.CAP_PROP_POS_FRAMES) < 80:
        # control angle and size // 旋轉角度和尺寸控制
        M1 = cv2.getRotationMatrix2D((w / 2, h / 2), ag, fsize)
        frame = cv2.warpAffine(frame, M1, (w, h))
        cv2.putText(gc, "1.rotate & fade-in", (400, 360), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 1,
                    cv2.LINE_AA)
        if ag < 360:
            ag = ag + 360 / 80  # rotate
        if fsize < 1.0:
            fsize = fsize + 0.9 / 80  # increase size
        if cap.get(cv2.CAP_PROP_POS_FRAMES) < 80 / 2 and fw < 1.00:
            fw = fw + 0.01  # add frame weight
        elif cap.get(cv2.CAP_PROP_POS_FRAMES) > 80 / 2 and fw < 1.00:
            fw = fw + 0.04  # add MORE frame weight

    # 2.Split\Merge & Star
    elif 100 <= cap.get(cv2.CAP_PROP_POS_FRAMES) < 120:
        star = cv2.xfeatures2d.StarDetector_create()  # create STAR object // 初始化STAR檢測器
        kp = star.detect(frame, None)  # get feature by STAR // 使用STAR尋找特徵點
        frame = cv2.drawKeypoints(frame, kp, None, color=-1)
        cv2.putText(gc, "2.Split&Merge&Star", (400, 360), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 0,
                    cv2.LINE_AA)
    elif 120 <= cap.get(cv2.CAP_PROP_POS_FRAMES) < 140:
        b, g, r = cv2.split(frame)
        frame = cv2.merge([r, g, b])
        cv2.putText(gc, "2.Split&Merge&Star", (400, 360), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 0,
                    cv2.LINE_AA)
    elif 140 <= cap.get(cv2.CAP_PROP_POS_FRAMES) < 160:
        star = cv2.xfeatures2d.StarDetector_create()  # create STAR object // 初始化STAR檢測器
        kp = star.detect(frame, None)  # get feature by STAR // 使用STAR尋找特徵點
        frame = cv2.drawKeypoints(frame, kp, None, color=-1)
        cv2.putText(gc, "2.Split&Merge&Star", (400, 360), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 0,
                    cv2.LINE_AA)
    elif 160 <= cap.get(cv2.CAP_PROP_POS_FRAMES) < 180:
        b, g, r = cv2.split(frame)
        frame = cv2.merge([r, b, g])
        cv2.putText(gc, "2.Split&Merge&Star", (400, 360), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 0,
                    cv2.LINE_AA)
    elif 180 <= cap.get(cv2.CAP_PROP_POS_FRAMES) < 200:
        star = cv2.xfeatures2d.StarDetector_create()  # create STAR object // 初始化STAR檢測器
        kp = star.detect(frame, None)  # get feature by STAR // 使用STAR尋找特徵點
        frame = cv2.drawKeypoints(frame, kp, None, color=-1)
        cv2.putText(gc, "2.Split&Merge&Star", (400, 360), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 0,
                    cv2.LINE_AA)
    elif 200 <= cap.get(cv2.CAP_PROP_POS_FRAMES) < 220:
        b, g, r = cv2.split(frame)
        frame = cv2.merge([g, r, b])
        cv2.putText(gc, "2.Split&Merge&Star", (400, 360), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 0,
                    cv2.LINE_AA)
    elif 220 <= cap.get(cv2.CAP_PROP_POS_FRAMES) < 240:
        star = cv2.xfeatures2d.StarDetector_create()  # 初始化STAR檢測器
        kp = star.detect(frame, None)  # 使用STAR尋找特徵點
        frame = cv2.drawKeypoints(frame, kp, None, color=-1)
        cv2.putText(gc, "2.Split&Merge&Star", (400, 360), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 0,
                    cv2.LINE_AA)

    # 3.DLib Face Detect
    elif 240 <= cap.get(cv2.CAP_PROP_POS_FRAMES) < 320:
        face_rects, scores, idx = detector.run(frame, 0)  # detect the face // 偵測人臉

        for i, d in enumerate(face_rects):  # get output //  取出所有偵測的結果
            x1 = d.left();
            y1 = d.top();
            x2 = d.right();
            y2 = d.bottom()
            text = f'{scores[i]:.2f}, ({idx[i]:0.0f})'

            cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 4, cv2.LINE_AA)  # 以方框標示偵測的人臉
            cv2.putText(frame, text, (x1, y1), cv2.FONT_HERSHEY_DUPLEX,  # 標示分數
                        0.7, (255, 255, 255), 1, cv2.LINE_AA)
        cv2.putText(gc, "3.DLib Face Detect", (400, 360), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 0,
                    cv2.LINE_AA)

    # 4.HSV
    elif 320 <= cap.get(cv2.CAP_PROP_POS_FRAMES) < 400:
        frame = cv2.cvtColor(frame, cv2.COLOR_HSV2BGR)
        cv2.putText(gc, "4.HSV", (400, 360), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 0, cv2.LINE_AA)

    # 5.Canny & ROI
    elif 400 <= cap.get(cv2.CAP_PROP_POS_FRAMES) < 480:
        frame = cv2.Canny(frame, 120, 250)
        frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2BGR)
        roi = roiarea(frame)  # 取出子畫面
        roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)  # BGR to HSV
        frame = replaceroi(frame, roi)  # 將處理完的子畫面貼回到原本畫面中
        cv2.rectangle(frame, RECT[0], RECT[1], (0, 0, 255), 2)  # 在 ROI 範圍處畫個框
        cv2.putText(gc, "5.Canny & ROI", (400, 360), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 0, cv2.LINE_AA)

    # 6.Dilate
    elif 480 <= cap.get(cv2.CAP_PROP_POS_FRAMES) < 560:
        frame = cv2.dilate(frame, k, iterations=2)
        cv2.putText(gc, "6.Dilate", (400, 360), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 0, cv2.LINE_AA)

    # 7.Gradient
    elif 560 <= cap.get(cv2.CAP_PROP_POS_FRAMES) < 640:
        frame = cv2.morphologyEx(frame, cv2.MORPH_GRADIENT, k)
        cv2.putText(gc, "7.Gradient", (400, 360), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 0, cv2.LINE_AA)

    # 8.Erode
    elif 640 <= cap.get(cv2.CAP_PROP_POS_FRAMES) < 720:
        frame = cv2.erode(frame, k, iterations=1)
        cv2.putText(gc, "8.Erode", (400, 360), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 0, cv2.LINE_AA)

    # 9.DoG
    elif 720 <= cap.get(cv2.CAP_PROP_POS_FRAMES) < 800:
        img_G0 = cv2.GaussianBlur(frame, (3, 3), 0)
        img_G1 = cv2.GaussianBlur(frame, (5, 5), 0)
        frame = img_G0 - img_G1
        cv2.putText(gc, "9.DoG", (400, 360), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 0, cv2.LINE_AA)

    # 10.Fadeout
    elif 800 <= cap.get(cv2.CAP_PROP_POS_FRAMES) < 833:
        cv2.putText(gc, "10.fade-out", (400, 360), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 0), 0, cv2.LINE_AA)
        epic = epic + 10

    # -------- needed --------------------
    c = cv2.waitKey(25)  # wait 25 ms

    if c == 27:  # key escape
        break

    result = cv2.addWeighted(gc, 1, frame, fw, epic)
    cv2.imshow('result', result)
    out.write(result)  # 寫入影格
# -------- code end --------------------
cap.release()
out.release()  # 輸出用
cv2.waitKey(0)
cv2.destroyAllWindows()


"""Contains form for myrm parametrs.
"""

from django.forms import ModelForm
from myrm_app.models import Parametrs

class ParametrsForm(ModelForm):
    """Form for myrm parametrs
    """
    class Meta():
        model = Parametrs
        fields = ['force', 'dryrun', 'auto_replace', 'allow_autoclean',
                  'trash_max_size', 'trash_max_count',
                   'autoclean_count', 'autoclean_size',
                   'autoclean_days', 'autoclean_same_count']


import cv2
from tkinter.filedialog import *

photo = askopenfilename()
img = cv2.imread(photo)

gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
inverted_gray_img = 255- gray_img
blurred_img = cv2.GaussianBlur(inverted_gray_img, (21,21), 0)
inverted_blurred_img = 255 - blurred_img

pencil_sketch_img = cv2.divide(gray_img, inverted_blurred_img, scale=256.0)

cv2.imshow('Original Image', img)
cv2.imshow('New Image', pencil_sketch_img)

cv2.waitKey(0)


import re
from collections import OrderedDict
from shutil import copy2
from os import makedirs
from os.path import exists, getsize
from os.path import getmtime
from os.path import join as join_path
from xml.etree import ElementTree
from xml.etree.ElementTree import ParseError

from . import BASE_DIR
from . import SYS_PATHS
from . import VM_PATHS
from . import VALID_VIDEO_EXT
from . import XML_FILES

class ProfileError(Exception):
    """Base Exception."""
    pass

class ProfileBlankNameError(ProfileError):
    """Exception for Profile Blank Name."""
    pass

class ProfileBlankPresetError(ProfileError):
    """Exception form Profile Blank Preset."""
    pass

class ProfileBlankParamsError(ProfileError):
    """Exception form Profile Blank Params."""
    pass

class ProfileExtensionError(ProfileError):
    """Exception form Profile Extension Error."""
    pass

class _XMLProfile:
    """Class to manage the xml profiles file."""

    def __init__(self):
        """Class initializer."""
        # Create xml files.
        self._xml_files = XML_FILES
        self._create_xml_files()

    def restore_default_profiles(self):
        """Restore default profiles."""
        self._copy_xml_file(file_name=self._xml_files.customized)

    def add_xml_profile(self, profile_name, preset, params, extension):
        """Add a conversion profile."""
        if not profile_name:
            raise ProfileBlankNameError

        profile_name = profile_name.upper()

        if not preset:
            raise ProfileBlankPresetError

        if not params:
            raise ProfileBlankParamsError

        if not extension.startswith('.') or extension not in VALID_VIDEO_EXT:
            raise ProfileExtensionError('Invalid video file extension')

        extension = extension.lower()

        xml_profile = ElementTree.Element(profile_name)

        xml_preset = self._create_xml_preset(preset, params, extension)

        self._insert_xml_elements(xml_profile=xml_profile,
                                  xml_preset=xml_preset,
                                  xml_root=self._get_xml_root(
                                      self._xml_files.customized))

    def export_xml_profiles(self, dst_dir):
        """Export a file with the conversion profiles."""
        # Raise PermissionError if user doesn't have write permission
        try:
            copy2(src=self._user_xml_file_path(
                file_name=self._xml_files.customized),
                  dst=dst_dir)
        except OSError:
            raise PermissionError

    def import_xml_profiles(self, src_file):
        """Import a conversion profile file."""
        try:
            dst_directory = self._user_xml_file_path(
                self._xml_files.customized)
            copy2(src=src_file, dst=dst_directory)
        except OSError:
            raise PermissionError

    def get_xml_profile_attr(self, target_quality, attr_name='preset_params'):
        """Return a param of ConversionProfile."""
        param_map = {'preset_name': 0,
                     'preset_params': 1,
                     'file_extension': 2,
                     'preset_name_es': 3}

        for xml_file in self._xml_files:
            for element in self._get_xml_root(xml_file_name=xml_file):
                for item in element:
                    if (item[0].text == target_quality or
                            item[3].text == target_quality):
                        return item[param_map[attr_name]].text

    def get_xml_profile_qualities(self, locale):
        """Return a list of available Qualities per conversion profile."""
        qualities_per_profile = OrderedDict()

        for xml_file in self._xml_files:
            for element in self._get_xml_root(xml_file):
                qualities = self._get_qualities(element, locale)
                if element.tag not in qualities_per_profile:
                    qualities_per_profile[element.tag] = qualities
                else:
                    qualities_per_profile[element.tag] += qualities

        return qualities_per_profile

    @staticmethod
    def _get_qualities(element, locale):
        qualities = []
        for item in element:
            if locale == 'es_ES':
                qualities.append(item[3].text)
            else:
                qualities.append(item[0].text)
        return qualities

    def _user_xml_file_path(self, file_name):
        """Return the path to the profiles file."""
        return join_path(self._user_xml_files_directory(), file_name)

    def _insert_xml_elements(self, xml_profile, xml_preset, xml_root):
        """Insert an xml element into an xml root."""
        for i, elem in enumerate(xml_root[:]):
            if elem.tag == xml_profile.tag:
                xml_root[i].insert(0, xml_preset)
                self._save_xml_tree(xml_tree=xml_root)
                break
        else:
            xml_profile.insert(0, xml_preset)
            xml_root.insert(0, xml_profile)
            self._save_xml_tree(xml_tree=xml_root)

    def _save_xml_tree(self, xml_tree):
        """Save the xml tree."""
        xml_profiles_path = self._user_xml_file_path(
            self._xml_files.customized)

        with open(xml_profiles_path, 'wb') as xml_file:
            xml_file.write(b'<?xml version="1.0"?>\n')
            ElementTree.ElementTree(xml_tree).write(xml_file, encoding='UTF-8')

    def _create_xml_files(self):
        """Create a xml file with the conversion profiles."""
        makedirs(self._user_xml_files_directory(), exist_ok=True)

        for xml_file in self._xml_files:
            if not self._xml_file_is_correct(xml_file):
                self._copy_xml_file(file_name=xml_file)

    def _copy_xml_file(self, file_name):
        """Copy profiles xml file."""
        xml_file_sys_path = self._sys_xml_file_path(file_name)
        xml_file_user_path = self._user_xml_file_path(file_name)

        copy2(src=xml_file_sys_path, dst=xml_file_user_path)

    def _xml_file_is_correct(self, file_name):
        """Validate xml files in user config directory."""
        xml_file_user_path = self._user_xml_file_path(file_name)
        xml_file_sys_path = self._sys_xml_file_path(file_name)

        if not exists(xml_file_user_path) or not getsize(xml_file_user_path):
            return False

        if getmtime(xml_file_sys_path) > getmtime(xml_file_user_path):
            return False

        return True

    def _get_xml_root(self, xml_file_name):
        """Return the xml root."""
        path = self._user_xml_file_path(file_name=xml_file_name)
        try:
            tree = ElementTree.parse(path)
        except ParseError:
            self.restore_default_profiles()
            tree = ElementTree.parse(path)
        return tree.getroot()

    @staticmethod
    def _user_xml_files_directory():
        """Return the user xml directory path."""
        return join_path(SYS_PATHS.config, 'profiles')

    @staticmethod
    def _sys_xml_file_path(file_name):
        """Return the path to xml profiles file in the system."""
        file_path = join_path(SYS_PATHS.profiles, file_name)
        if exists(file_path):
            # if VideoMorph is installed
            return file_path

        # if not installed
        return join_path(BASE_DIR, VM_PATHS.profiles, file_name)

    @staticmethod
    def _create_xml_preset(preset, params, extension):
        """Return a xml preset."""
        regexp = re.compile(r'[A-z][0-9]?')
        preset_tag = ''.join(regexp.findall(preset))
        xml_preset = ElementTree.Element(preset_tag)
        xml_preset_name = ElementTree.Element('preset_name')
        xml_preset_name.text = preset
        xml_params = ElementTree.Element('preset_params')
        xml_params.text = params
        xml_extension = ElementTree.Element('file_extension')
        xml_extension.text = extension
        xml_preset_name_es = ElementTree.Element('preset_name_es')
        xml_preset_name_es.text = preset

        for i, elem in enumerate([xml_preset_name, xml_params,
                                  xml_extension, xml_preset_name_es]):
            xml_preset.insert(i, elem)

        return xml_preset

class ConversionProfile:
    """Base class for a Conversion Profile."""

    def __init__(self, prober):
        """Class initializer."""
        self._xml_profile = _XMLProfile()
        self._quality = None
        self.prober = prober
        self.extension = None
        self.params = None

    def __getattr__(self, attr):
        """Delegate to manage the _XMLProfile object."""
        return getattr(self._xml_profile, attr)

    def update(self, new_quality):
        """Set the target Quality and other parameters needed to get it."""
        self._quality = new_quality
        # Update the params and extension when the target quality change
        self.params = self._xml_profile.get_xml_profile_attr(
            target_quality=self._quality,
            attr_name='preset_params')
        self.extension = self._xml_profile.get_xml_profile_attr(
            target_quality=self._quality,
            attr_name='file_extension')

    @property
    def quality_tag(self):
        """Generate a tag from profile quality string."""
        tag_regex = re.compile(r'[A-Z][0-9]?')
        tag = ''.join(tag_regex.findall(self._quality))

        if not tag:
            tag = ''.join(word[0] for word in self._quality.split()).upper()

        return '[' + tag + ']-'


from django.shortcuts import render, get_object_or_404
from django.http import JsonResponse
from .forms import UserRegistrationForm, UserEditForm, ProfileEditForm
from django.contrib.auth.decorators import login_required
from .models import Profile
from django.contrib.auth.models import User
from django.views.decorators.http import require_POST
from .models import Follow
from posts.models import Comment
from books.models import Book
import requests
import json

def register(request):
    if request.method == 'POST':
        user_form = UserRegistrationForm(request.POST)
        if user_form.is_valid():
            new_user = user_form.save(commit=False)
            new_user.set_password(user_form.cleaned_data['password'])
            new_user.save()
            # creating profile
            profile = Profile.objects.create(user=new_user)
            return render(request, 'account/register_done.html', {'new_user': new_user})
    else:
        user_form = UserRegistrationForm()
    return render(request, 'account/register.html', {'user_form': user_form})

@login_required
def edit(request):
    if request.method == 'POST':
        user_form = UserEditForm(instance=request.user, data=request.POST)
        profile_form = ProfileEditForm(instance=request.user.profile, data=request.POST, files=request.FILES)

        if user_form.is_valid() and profile_form.is_valid():
            user_form.save()
            profile_form.save()
    else:
        user_form = UserEditForm(instance=request.user)
        profile_form = ProfileEditForm(instance=request.user.profile)
    return render(request, 'account/edit.html', {'user_form': user_form, 'profile_form': profile_form})

@login_required
def user_detail(request, username):
    user = get_object_or_404(User, username=username)
    return render(request, 'account/user/user_detail.html', {'user': user})

@login_required
def user_comments(request, username):
    user = get_object_or_404(User, username=username)
    comments = Comment.objects.filter(author=user)
    return render(request, 'account/user/view_user_comments.html', {'user': user,
                                                                    'comments': comments})

@login_required
def user_books(request, username):
    user = get_object_or_404(User, username=username)
    get_books = Book.objects.filter(user=user)
    books = []
    for book in get_books:
        response = requests.get(f'https://api.itbook.store/1.0/books/{book.isbn}')
        single_book = response.json()
        books.append(single_book)
    return render(request, 'account/user/view_user_books.html', {'user': user,
                                                                 'books': books})

@login_required
def user_follow(request):
    is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
    if is_ajax:
        if request.method == 'POST':
            data = json.load(request)
            user_id = data.get('id')
            action = data.get('action')
            user = User.objects.get(id=user_id)
            if action == 'follow':
                Follow.objects.get_or_create(user_from=request.user, user_to=user)
                return JsonResponse({'status': 'followed'})
            else:
                Follow.objects.filter(user_from=request.user, user_to=user).delete()
                return JsonResponse({'status': 'unfollowed'})
        return JsonResponse({'status': 'error-1'})
    else:
        return JsonResponse({'status': 'error-2'})


import conllu
import pandas as pd
import random
# noinspection PyUnresolvedReferences
import swifter

from glob import glob
from tqdm import tqdm   # from tqdm.notebook import tqdm # notebook version sometimes fails. use plain tqdm instead :(

from helper_methods import is_enum, count_words, contains_num
from environment_constants import PATH, META_COLUMNS, SENTENCE_COLUMNS

def make_conllu_files_list() -> list[str]:
    """
    Returns
    -------
    a list of paths to all .conllu files
    """
    conllu_files_list = [file_name for file_name in glob(PATH + "\\*.conllu")]
    return conllu_files_list

def make_meta_files_list() -> list[str]:
    """
    Returns
    -------
    a list of paths to all -meta.tsv files
    """
    meta_files_list = [file_name for file_name in glob(PATH + "\\*-meta.tsv")]
    return meta_files_list

def get_meta_file_path(conllu_file_path: str) -> str:
    """

    Parameters
    ----------
    conllu_file_path: path of a conllu file

    Returns
    -------
    path of the corresponding -meta.tsv file
    """
    return conllu_file_path[:-len('.conllu')] + '-meta.tsv'

def sentences_and_meta_df(file_path: str,
                          remove_ghosts: bool = True,
                          min_sentence_length: int = 3,
                          remove_enum: bool = True,
                          only_with_nums: bool = True) \
        -> pd.DataFrame:
    """

    Parameters
    ----------
    file_path: path to a .conllu file

    remove_ghosts: whether utterances by ghost speakers will be removed
    min_sentence_length: sentences below the specified length will be removed
    remove_enum: whether utterances that only contain "1." and the like will be removed
    only_with_nums: whether utterances that do not contain any numbers will be removed

    Returns
    -------
    pandas DataFrame containing one line per sentence
    columns as defined in environment constant META_COLUMNS
    """

    def sentence_to_df_row(sentence: conllu.models.TokenList) -> pd.Series:
        """

        Parameters
        ----------
        sentence: single sentence from the conllu parser

        Returns
        -------
        pandas Series with columns:
            'sent_id' : e.g. '2015-01-05-commons.seg1.1'
            'sentence' : pd.DataFrame
            'utterance_id' :
                if the sentence is the first of utterance: utterance ID (e.g. ParlaMint-GB_2015-01-05-commons.u1)
                else: None (will be filled in later in outer function)
        """
        inner_dataframe = pd.DataFrame(sentence)[SENTENCE_COLUMNS]
        inner_dataframe['head'] = inner_dataframe['head'] - 1
        sentence_row = pd.Series({'sent_id': sentence.metadata['sent_id'][len('ParlaMint-GB_'):],
                                  'sentence': inner_dataframe.to_dict('list'),
                                  'utterance_id': sentence.metadata.get('newdoc id')
                                  })
        return sentence_row

    file = open(file_path, 'r', encoding='utf-8').read()
    sentences = conllu.parse(file)
    sentences_df = pd.concat((sentence_to_df_row(s) for s in sentences), axis=1).T

    # some sentences from sentence_to_df_row() do not come with utterance_ids
    # make them inherit the utterance_id of their predecessor with ffill
    sentences_df['utterance_id'] = sentences_df['utterance_id'].ffill()

    # === data cleaning ===

    # remove short sentences
    sentences_df = sentences_df[sentences_df['sentence']. \
                                    swifter.progress_bar(False).apply(count_words) >= min_sentence_length]

    # remove sentences of the form "2."
    if remove_enum and min_sentence_length < 3:
        sentences_df = sentences_df[sentences_df['sentence']. \
            swifter.progress_bar(False).apply(lambda cell: not is_enum(cell))]

    # remove sentences that do not contain any numbers
    if only_with_nums:
        sentences_df = sentences_df[sentences_df['sentence'].swifter.progress_bar(False).apply(contains_num)]

    # === combining sentence data and meta data ===

    # only load columns that contain valuable information
    meta_df = pd.read_csv(get_meta_file_path(file_path), sep='\t')[META_COLUMNS]

    # transform Party_status column:
    # Party_status -> is_coalition
    # Coalition -> True
    # Opposition -> False
    meta_df['is_coalition'] = meta_df['Party_status'].replace({'Coalition': True, 'Opposition': False}, inplace=False)
    meta_df['is_coalition'].fillna('n/a', inplace=True)
    meta_df.drop(columns=['Party_status'], inplace=True)

    # rename utterance_ID column to match sentences_df so the two dfs can be merged
    meta_df = meta_df.rename(columns={'ID': 'utterance_id'})

    sentences_df = sentences_df.merge(meta_df)

    # === data efficiency ===

    # clip off unnecessary letters
    sentences_df['utterance_id'] = \
        [utterance_id[len('ParlaMint-GB_'):] for utterance_id in sentences_df['utterance_id']]

    if remove_ghosts:
        # get rid of utterances by ghost speakers
        sentences_df = sentences_df[sentences_df['Speaker_type'] != '-']

        # compress data: binary datatype if removing ghosts makes category binary
        sentences_df['is_mp'] = (sentences_df['Speaker_type'] == 'MP')
        sentences_df['is_female'] = (sentences_df['Speaker_gender'] == 'F')
        sentences_df.drop(columns=['Speaker_type', 'Speaker_gender'], inplace=True)

    # compress data: binary datatype for binary categories
    sentences_df['is_upper_house'] = (sentences_df['House'] == 'Upper house')
    sentences_df['is_chairperson'] = (sentences_df['Speaker_role'] == 'Chairperson')
    sentences_df.drop(columns=['House', 'Speaker_role'], inplace=True)

    return sentences_df

def generate_sentences_and_meta_df_from_multiple_files(number_of_files: int = None,
                                                       random_seed: int = 0,
                                                       remove_ghosts: bool = True,
                                                       min_sentence_length: int = 3,
                                                       remove_enum: bool = True,
                                                       only_with_nums: bool = True) \
        -> pd.DataFrame:
    """
    number_of_files: how many .conllu files are used to generate the dataframe
    random_seed: seed used to pick the number_of_files files randomly.
        if random_seed==0, the first number_of_files files will be used
    remove_ghosts, min_sentence_length, remove_enum, only_with_nums: passed to sentences_and_meta_df

    Returns
    -------
    DataFrame containing info from the first n conllu files
    one line per sentence
    columns as defined in environment constant META_COLUMNS
    """
    path_list = make_conllu_files_list()
    if number_of_files is not None:
        if random_seed != 0:
            random.Random(random_seed).shuffle(path_list)
        path_list = path_list[:number_of_files]

    multiple_file_df = pd.concat(tqdm((sentences_and_meta_df(
        path,
        remove_ghosts=remove_ghosts,
        min_sentence_length=min_sentence_length,
        remove_enum=remove_enum,
        only_with_nums=only_with_nums
    ) for path in path_list), total=len(path_list), desc="Generating Dataframe"))

    # reset index so we can use swifter
    multiple_file_df = multiple_file_df.reset_index(drop=True)

    return multiple_file_df


#!/usr/bin/env python3

import json
import sys
import os
import time
import sys
import datetime

script_dir = sys.path[0]
data_dir = os.path.abspath(os.path.join(script_dir, "..", "..", "hourly"))
output_dir = os.path.abspath(os.path.join(script_dir, "..", "..", "current"))

planets = [
        'jupiter', 'mars', 'mercury', 'neptune',
        'pluto', 'saturn', 'uranus', 'venus'
        ]

current_time = int(time.time())

print(f"Running process for: {current_time}")

for planet in planets:
    print(f"Processing planet: {planet}")
    with open(f"{data_dir}/{planet}.json") as _json:
        data = json.load(_json)
        state = None
        for hour in data["retrograde"]:
            if current_time > hour[0]:
                state = hour[1]
            else:
                with open(f"{output_dir}/{planet}.json", "w") as _out:
                    output_data = {
                        "updated": datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S+00:00"),
                        "retrograde": state
                    }
                    json.dump(output_data, _out)
                break


# -*- coding: utf-8 -*-
"""
Created on Tue Jan 16 15:33:20 2018

@author: cscuser
"""

import geopandas as gpd
from shapely.geometry import Point, MultiPoint
from shapely.ops import nearest_points

def nearest(row, geom_union, df1, df2, geom1_col='geometry', geom2_col='geometry', src_column=None):
    """Find the nearest point and return the corresponding value from specified column."""
    # Find the geometry that is closest
    nearest = df2[geom2_col] == nearest_points(row[geom1_col], geom_union)[1]
    # Get the corresponding value from df2 (matching is based on the geometry)
    value = df2[nearest][src_column].get_values()[0]
    return value

pks_fp = r"C:\Users\cscuser\Desktop\TS\KML\PKS_suuralue.kml"
address_fp = r"C:\Users\cscuser\Desktop\TS\ADDRESSES\geocoded_addresses.shp"

pks = gpd.read_file(pks_fp)
address = gpd.read_file (address_fp)

address = address.dropna(subset=['geometry'])

unary = address.unary_union

#Calculate the centroids of the polygons
pks['centroid'] = pks.centroid

pks['nearest_id'] = pks.apply(nearest, geom_union=unary, df1=pks, df2=address, geom1_col='centroid',)


#!/usr/bin/env python

import time
import argparse

from bgcore import logging as bglogging
from fannsdb.db.sqlitedb import FannsSQLiteDb
from fannsdb.utils import hsize
from condel._DEPRECATED_.weights import load_weights

PREDICTOR_TRANSFORM = dict(
	SIFT=lambda v: 1.0 - v,
	MA=lambda v: (v / 12) + 0.5)

def main():
	parser = argparse.ArgumentParser(
		description="Calculate Condel score")

	parser.add_argument("db_path", metavar="DB_PATH",
						help="Functional scores database")

	parser.add_argument("weights_path", metavar="WEIGHTS",
						help="File containing the scores weights and cutoffs")

	parser.add_argument("-p", "--predictors", dest="predictors", metavar="PREDICTORS",
						help="Comma separated list of predictors")

	parser.add_argument("-u", "--updated-predictor", dest="updated_predictor", metavar="NAME",
						help="Updated predictor name")

	bglogging.add_logging_arguments(parser)

	args = parser.parse_args()

	bglogging.initialize(args)

	log = bglogging.get_logger("calculate")

	log.info("Opening functional scores database ...")

	db = FannsSQLiteDb(args.db_path)
	db.open()

	updated_predictor = args.updated_predictor or "CONDEL"

	predictors = set([p["id"] for p in db.predictors()])
	if updated_predictor not in predictors:
		log.info("  Creating predictor {} ...".format(updated_predictor))
		db.add_predictor(updated_predictor, FannsDb.CALCULATED_PREDICTOR_TYPE, source=predictors)

	log.info("Loading state ...")

	state = load_weights(args.weights_path)

	avail_predictors, precision, step, stats = [state[k] for k in ["predictor_names", "precision", "step", "stats"]]
	if args.predictors is not None:
		predictors = [p for p in [p.strip() for p in args.predictors.split(",")] if p in avail_predictors]
		if len(predictors) == 0:
			log.error("Unknown predictors: {}".format(args.predictors))
			log.error("Available predictor names are: {}".format(", ".join(avail_predictors)))
			exit(-1)
	else:
		predictors = avail_predictors

	log.info("Available predictors: {}".format(", ".join(avail_predictors)))
	log.info("Selected predictors: {}".format(", ".join(predictors)))

	log.info("Calculating ...")

	start_time = partial_start_time = time.time()
	try:
		for num_rows, row in enumerate(db.query_scores(predictors=predictors), start=1):
			scores = row["scores"]
			condel = wsum = 0
			for predictor, score in scores.items():
				if score is None:
					continue

				predictor_stats = stats[predictor]
				rmin, rmax, dim, size, cdp, cdn, cutoff = [predictor_stats[k] for k in [
																"rmin", "rmax", "dim", "size", "cdp", "cdn", "cutoff"]]

				if predictor in PREDICTOR_TRANSFORM:
					score = PREDICTOR_TRANSFORM[predictor](score)

				r = (score - rmin) / dim
				index = int(r * size) if score < rmax else size - 1

				if score < cutoff:
					w = 1 - cdn[index]
				else:
					w = 1 - cdp[index]

				wsum += w
				condel += w * score

				#log.info("{}={}, w={} -> {}".format(predictor_name, score, w, score * w))

			if wsum != 0:
				condel /= wsum

				d = {updated_predictor : condel}
				db.update_scores(row["id"], d)

				#log.info(">>> CONDEL={}".format(condel))
			else:
				log.warn("wsum = 0, condel={}, scores={}".format(condel, repr(scores)))

			partial_time = time.time() - partial_start_time
			if partial_time > 5.0:
				partial_start_time = time.time()
				elapsed_time = time.time() - start_time
				log.debug("  {} rows, {:.1f} rows/second".format(hsize(num_rows), num_rows / elapsed_time))

		log.info("Commit ...")
		db.commit()
	except KeyboardInterrupt:
		log.warn("Interrupted by Ctrl-C")
		db.rollback()
	except:
		db.rollback()
		raise
	finally:
		db.close()

if __name__ == "__main__":
	main()


#!/usr/bin/python3

import json
from collections import defaultdict
import sys
from os import system

with open('parent-genres.tsv', 'r') as f:
    parent_genres = {
        line.split('\t')[0]: line.split('\t')[1]
        for line in f.read().splitlines()
    }

def open_in_chrome(url):
    system('google-chrome "{0}" > /dev/null 2>&1'.format(url))

offset = -1
while offset < 0:
    try:
        offset = int(input('Enter offset: '))
    except ValueError:
        continue
    else:
        break

while True:
    print ('====================================')
    print('Parent genres:')
    for code, pg_string in sorted(parent_genres.items(), key=lambda t: t[0]):
        print('    ' + code + ' - ' + pg_string)
    with open('genre-map.json', 'r') as f:
        genre_map = defaultdict(lambda: [], json.loads(f.read()))
    print('Other options:')
    print('    q - quit')
    print('    ? - Search information about genre')
    print('There are {0} uncategorized genres.'.format(
        len(genre_map['u'])
    ))
    if not genre_map['u']:
        sys.exit(0)
    if offset >= len(genre_map['u']):
        print('Offset exceeds number of uncategorized genres.')
        print('Run this script again with a lower offset.')
        sys.exit(0)
    genre = genre_map['u'][offset]
    while True:
        pg_code = input('Enter code to categorize "{0}": '.format(
            genre
        ))
        if pg_code == 'q':
            sys.exit(0)
        elif pg_code == '?':
            open_in_chrome('http://everynoise.com/everynoise1d.cgi?root={0}&scope=all'.format(
                genre.replace(' ', '%20')
            ))
            open_in_chrome('http://google.com/search?q={0}+genre'.format(
                genre.replace(' ', '+')
            ))
        elif pg_code in parent_genres:
            break
    genre_map['u'].remove(genre)
    genre_map[pg_code].append(genre)
    with open('genre-map.json', 'w') as f:
        f.write(
            json.dumps(
                dict(genre_map),
                sort_keys=True,
                indent=4,
                separators=(',', ': '),
            )
        )
    print('Successfully categorized under "{0}".'.format(
        parent_genres[pg_code]
    ))