import os
import numpy as np
import matplotlib.pyplot as plt
import malmoenv
import argparse
from pathlib import Path
import time
from PIL import Image

from stable_baselines3.common import results_plotter
from stable_baselines3.common.monitor import Monitor
from stable_baselines3.common.results_plotter import load_results, ts2xy, plot_results
from stable_baselines3.common.noise import NormalActionNoise
from stable_baselines3.common.callbacks import BaseCallback
from stable_baselines3.common.env_checker import check_env

from stable_baselines3 import PPO

class SaveOnBestTrainingRewardCallback(BaseCallback):
    """
    Callback for saving a model (the check is done every ``check_freq`` steps)
    based on the training reward (in practice, we recommend using ``EvalCallback``).

    :param check_freq:
    :param log_dir: Path to the folder where the model will be saved.
      It must contains the file created by the ``Monitor`` wrapper.
    :param verbose: Verbosity level.
    """
    def __init__(self, check_freq: int, log_dir: str, verbose: int = 1):
        super(SaveOnBestTrainingRewardCallback, self).__init__(verbose)
        self.check_freq = check_freq
        self.log_dir = log_dir
        self.save_path = os.path.join(log_dir, 'best_model')
        self.best_mean_reward = -np.inf

    # def _init_callback(self) -> None:
    #     # # Create folder if needed
    #     # if self.save_path is not None:
    #     #     os.makedirs(self.save_path, exist_ok=True)

    def _on_step(self) -> bool:
        if self.n_calls % self.check_freq == 0:

          # Retrieve training reward
          x, y = ts2xy(load_results(self.log_dir), 'timesteps')
          if len(x) > 0:
              # Mean training reward over the last 100 episodes
              mean_reward = np.mean(y[-100:])
              if self.verbose > 0:
                print(f"Num timesteps: {self.num_timesteps}")
                print(f"Best mean reward: {self.best_mean_reward:.2f} - Last mean reward per episode: {mean_reward:.2f}")

              # New best model, you could save the agent here
              if mean_reward > self.best_mean_reward:
                  self.best_mean_reward = mean_reward
                  # Example for saving best model
                  if self.verbose > 0:
                    print(f"Saving new best model to {self.save_path}")
                  self.model.save(self.save_path)

        return True

log_dir = "tmp/"
os.makedirs(log_dir, exist_ok=True)

if __name__ == '__main__':

    parser = argparse.ArgumentParser(description='malmovnv test')
    parser.add_argument('--mission', type=str, default='missions/jumping.xml', help='the mission xml')
    parser.add_argument('--port', type=int, default=9000, help='the mission server port')
    parser.add_argument('--server', type=str, default='127.0.0.1', help='the mission server DNS or IP address')
    parser.add_argument('--port2', type=int, default=None, help="(Multi-agent) role N's mission port. Defaults to server port.")
    parser.add_argument('--server2', type=str, default=None, help="(Multi-agent) role N's server DNS or IP")
    parser.add_argument('--episodes', type=int, default=100, help='the number of resets to perform - default is 1')
    parser.add_argument('--episode', type=int, default=0, help='the start episode - default is 0')
    parser.add_argument('--role', type=int, default=0, help='the agent role - defaults to 0')
    parser.add_argument('--episodemaxsteps', type=int, default=100, help='max number of steps per episode')
    parser.add_argument('--saveimagesteps', type=int, default=0, help='save an image every N steps')
    parser.add_argument('--resync', type=int, default=0, help='exit and re-sync every N resets'
                                                              ' - default is 0 meaning never.')
    parser.add_argument('--experimentUniqueId', type=str, default='test1', help="the experiment's unique id.")
    args = parser.parse_args()
    if args.server2 is None:
        args.server2 = args.server

    xml = Path(args.mission).read_text()
    env = malmoenv.make()

    env.init(xml, args.port,
             server=args.server,
             server2=args.server2, port2=args.port2,
             role=args.role,
             exp_uid=args.experimentUniqueId,
             episode=args.episode, resync=args.resync)

    env = Monitor(env, log_dir)
    # print("checking env")
    check_env(env, True)
    s = SaveOnBestTrainingRewardCallback(2000, log_dir)
    # print("checked env")

    model = PPO("MlpPolicy", env, verbose=1, tensorboard_log="./ppo_test_tensorboard/")
    #model.load("tmp/best_model.zip")
    model.learn(total_timesteps=100000, callback=s, reset_num_timesteps=False)

    # print("trained and saved model")
    # for i in range(args.episodes):
    #     print("reset " + str(i))
    #     obs = env.reset()

    #     steps = 0
    #     done = False
    #     while not done and (args.episodemaxsteps <= 0 or steps < args.episodemaxsteps):
    #         # h, w, d = env.observation_space.shape
    #         # print(done)
    #         action, _states = model.predict(obs, deterministic=True)
    #         # action = env.action_space.sample()
    #         obs, reward, done, info = env.step(action)
    #         steps += 1
    #         # print("reward: " + str(reward))
    #         # print(obs)

    #         time.sleep(.05)

    env.close()


import os
import gc
import math
import numpy as np
import cv2
import imageio
import tensorflow as tf
import matplotlib.pyplot as plt

from PIL import Image
from random import choice
from tensorflow.keras.utils import Sequence
from tensorflow.keras import backend as K
from losses import psnr2 as psnr

class DataLoader(Sequence):
    def __init__(self, datapath, batch_size, height_hr, width_hr, scale, crops_per_image, media_type,channels=3,colorspace='RGB'):
        """
        :param string datapath: filepath to training images
        :param int height_hr: Height of high-resolution images
        :param int width_hr: Width of high-resolution images
        :param int height_hr: Height of low-resolution images
        :param int width_hr: Width of low-resolution images
        :param int scale: Upscaling factor
        """

        # Store the datapath
        self.datapath = datapath
        self.batch_size = batch_size
        self.height_hr = height_hr
        self.height_lr = int(height_hr / scale)
        self.width_hr = width_hr
        self.width_lr = int(width_hr / scale)
        self.channels = channels
        self.colorspace = colorspace
        self.scale = scale
        self.crops_per_image = crops_per_image
        self.media_type  = media_type
        self.total_imgs = None

        # Options for resizing
        self.options = [Image.NEAREST, Image.BILINEAR, Image.BICUBIC, Image.LANCZOS]

        # Check data source
        self.img_paths = []

        if os.path.isdir(self.datapath):
            self.get_paths()

    def get_paths(self):
        for dirpath, _, filenames in os.walk(self.datapath):
            for filename in [f for f in filenames if any(filetype in f.lower() for filetype in ['jpeg', 'png', 'jpg','mp4','264','webm','wma'])]:
                self.img_paths.append(os.path.join(dirpath, filename))
        self.total_imgs = len(self.img_paths)
        print(">> Found {} images in dataset".format(self.total_imgs))

    def random_crop(self, img, random_crop_size):
        # Note: image_data_format is 'channel_last'
        assert img.shape[2] == 3
        height, width = img.shape[0], img.shape[1]
        dy, dx = random_crop_size
        x = np.random.randint(0, width - dx + 1)
        y = np.random.randint(0, height - dy + 1)
        return img[y:(y+dy), x:(x+dx), :]

    @staticmethod
    def scale_lr_imgs(imgs):
        """Scale low-res images prior to passing to SRGAN"""
        return imgs / 255.

    @staticmethod
    def unscale_lr_imgs(imgs):
        """Un-Scale low-res images"""
        imgs = imgs * 255
        imgs = np.clip(imgs, 0., 255.)
        return imgs.astype('uint8')

    @staticmethod
    def scale_hr_imgs(imgs):
        """Scale high-res images prior to passing to SRGAN"""
        return imgs / 127.5 - 1

    @staticmethod
    def unscale_hr_imgs(imgs):
        """Un-Scale high-res images"""
        imgs = (imgs + 1.) * 127.5
        imgs = np.clip(imgs, 0., 255.)
        return imgs.astype('uint8')

    def count_frames(self,videopath):
        '''Count total frames in video'''
        cap = cv2.VideoCapture(videopath)
        if(not cap.isOpened()):
            print("Error to open video: ",videopath)
            return -1
        count=0
        while(cap.isOpened()):
            ret, frame = cap.read()
            if(ret):
                count +=1
            else:
                break
        cap.release()
        return count

    def get_random_frames(self,n_fms=1,videopath=None):
        """Get random number of video frames"""
        t_frames = self.count_frames(videopath)
        choiced_frames = np.random.randint(t_frames, size=n_fms)
        return choiced_frames

    @staticmethod
    def load_img(path,colorspace='YCbCr'):
        img = Image.open(path)
        if (colorspace ==  'YCbCr' and img.mode != 'YCbCr'):
            img = img.convert('YCbCr')
        if (colorspace ==  'RGB' and img.mode != 'RGB'):
            img = img.convert('RGB')
        return np.array(img)

    def load_frame(self,videopath):
        """Get n_imgs random frames from the video"""
        choiced_frame=self.get_random_frames(1,videopath)[0]
        #print("Frame no.: ",choiced_frame)
        cap = cv2.VideoCapture(videopath)
        cap.set(1,choiced_frame)
        ret, frame = cap.read()
        if not ret:
            print(">> Erro to access frames.")
            return -1
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        cap.release()
        return np.array(frame)

    # Every Sequence must implement the __getitem__ and the __len__ methods.
    def __len__(self):
        return int(self.total_imgs / float(self.batch_size))

    def __getitem__(self, idx):
        return self.load_batch(idx=idx)

    def load_batch(self,idx=0, img_paths=None, training=True, bicubic=False):
        """ Loads a batch of images or video"""
        if(self.media_type=='i'):
            #print("1. Media type image folder")
            imgs_lr, imgs_hr = self.load_batch_image(idx, img_paths=img_paths, training=training,bicubic=False)
        elif(self.media_type=='v' and os.path.isdir(self.datapath)):
            #print("2. Media type video folder")
            imgs_lr, imgs_hr = self.load_batch_video(idx, img_paths=None, training=training, bicubic=False)

        elif(self.media_type=='v' and not os.path.isdir(self.datapath)):
            #print("3. Media type single video")
            imgs_lr, imgs_hr = self.load_batch_video(idx, img_paths=self.datapath, training=training, bicubic=False)
        else:
            print("Error: type of media fail")
        return imgs_lr, imgs_hr

    def dowscale_image(self,img_hr,ksize=5):
        # For LR, do bicubic downsampling
        lr_shape = (int(img_hr.shape[1]/self.scale), int(img_hr.shape[0]/self.scale))
        img_lr = cv2.resize(cv2.GaussianBlur(img_hr,(ksize,ksize),0),lr_shape, interpolation = cv2.INTER_CUBIC)
        return img_lr

    def load_batch_video(self, idx=0, img_paths=None, training=True, bicubic=False):
        """Loads a batch of frames from videos folder"""
        # Starting index to look in
        cur_idx = 0
        if not img_paths:
            cur_idx = idx*self.batch_size
        #print('cur_idx:',cur_idx)

        # Scale and pre-process images
        imgs_hr, imgs_lr = [], []
        while True:

            # Check if done with batch
            if img_paths is None:
                if cur_idx >= self.total_imgs:
                    cur_idx = 0
                if len(imgs_hr) >= self.batch_size:
                    break
            if img_paths is not None and len(imgs_hr) == len(img_paths):
                break
            try:
                # Load image
                img_hr = None
                if img_paths:
                    #print('1. video: ',img_paths[cur_idx])
                    img_hr = self.load_frame(img_paths[cur_idx])
                    #print(img_hr.shape)
                else:
                    #print('2. video: ',self.img_paths[cur_idx])
                    img_hr = self.load_frame(self.img_paths[cur_idx])
                    #print(img_hr.shape)

                # Create HR images to go through
                img_crops = []
                if training:
                    for i in range(self.crops_per_image):
                        #print(idx, cur_idx, "Loading crop: ", i)
                        img_crops.append(self.random_crop(img_hr, (self.height_hr, self.width_hr)))
                else:
                    img_crops = [img_hr]

                # Downscale the HR images and save
                for img_hr in img_crops:

                    # TODO: Refactor this so it does not occur multiple times
                    if img_paths is None:
                        if cur_idx >= self.total_imgs:
                            cur_idx = 0
                        if len(imgs_hr) >= self.batch_size:
                            break
                    if img_paths is not None and len(imgs_hr) == len(img_paths):
                        break

                    # Downscale and insert gausian blur in LR image
                    img_lr = self.dowscale_image(img_hr)

                    # Scale color values
                    img_hr = self.scale_hr_imgs(img_hr)
                    img_lr = self.scale_lr_imgs(img_lr)

                    # Store images
                    #print(img_hr[:,:,:self.channels].shape,img_lr[:,:,:self.channels].shape)
                    imgs_hr.append(img_hr[:,:,:self.channels])
                    imgs_lr.append(img_lr[:,:,:self.channels])

            except Exception as e:

                print(e)
                pass
            finally:
                cur_idx += 1

        # Convert to numpy arrays when we are training
        # Note: all are cropped to same size, which is not the case when not training
        if training:
            imgs_hr = np.array(imgs_hr)
            imgs_lr = np.array(imgs_lr)

        # Return image batch
        return imgs_lr, imgs_hr

    def load_batch_image(self, idx=0, img_paths=None, training=True, bicubic=True):
        """Loads a batch of images from datapath folder"""

        # Starting index to look in
        cur_idx = 0

        if not img_paths:
            cur_idx = idx*self.batch_size

        # Scale and pre-process images
        imgs_hr, imgs_lr = [], []
        while True:

            # Check if done with batch
            if img_paths is None:
                if cur_idx >= self.total_imgs:
                    cur_idx = 0
                if len(imgs_hr) >= self.batch_size:
                    break
            if img_paths is not None and len(imgs_hr) == len(img_paths):
                break

            try:
                # Load image
                img_hr = None
                if img_paths:
                    img_hr = self.load_img(img_paths[cur_idx],self.colorspace)
                else:
                    img_hr = self.load_img(self.img_paths[cur_idx],self.colorspace)

                # Create HR images to go through
                img_crops = []
                if training:
                    for i in range(self.crops_per_image):
                        #print(idx, cur_idx, "Loading crop: ", i)
                        img_crops.append(self.random_crop(img_hr, (self.height_hr, self.width_hr)))
                else:
                    img_crops = [img_hr]

                # Downscale the HR images and save
                for img_hr in img_crops:

                    # TODO: Refactor this so it does not occur multiple times
                    if img_paths is None:
                        if cur_idx >= self.total_imgs:
                            cur_idx = 0
                        if len(imgs_hr) >= self.batch_size:
                            break
                    if img_paths is not None and len(imgs_hr) == len(img_paths):
                        break

                    # Downscale and insert gausian blur in LR image
                    img_lr = self.dowscale_image(img_hr)

                    # Scale color values
                    img_hr = self.scale_hr_imgs(img_hr)
                    img_lr = self.scale_lr_imgs(img_lr)

                    # Store images
                    #print(img_hr[:,:,:self.channels].shape,img_lr[:,:,:self.channels].shape)
                    imgs_hr.append(img_hr[:,:,:self.channels])
                    imgs_lr.append(img_lr[:,:,:self.channels])

            except Exception as e:
                print(e)
                pass
            finally:
                cur_idx += 1

        # Convert to numpy arrays when we are training
        # Note: all are cropped to same size, which is not the case when not training
        if training:
            imgs_hr = np.array(imgs_hr)
            imgs_lr = np.array(imgs_lr)

        # Return image batch
        return imgs_lr, imgs_hr

def plot_test_images(model, loader, datapath_test, test_output, epoch, name='SRGAN', channels = 3,colorspace='RGB'):

    try:
        # Get the location of test images
        test_images = [os.path.join(datapath_test, f) for f in os.listdir(datapath_test) if any(filetype in f.lower() for filetype in ['jpeg','mp4','264', 'png', 'jpg'])]

        # Load the images to perform test on images
        imgs_lr, imgs_hr = loader.load_batch(img_paths=test_images, training=False, bicubic=True)
        # Create super resolution and bicubic interpolation images
        imgs_sr = []
        imgs_bi = []
        srgan_psnr = []
        bi_psnr = []
        for i in range(len(test_images)):

            pre=np.squeeze(
                    model.predict(
                        np.expand_dims(imgs_lr[i], 0),
                        batch_size=1
                    ),
                    axis=0
                )
            imgs_sr.append(pre)

        # Unscale colors values
        if channels == 1:
            imgs_lr = [loader.unscale_lr_imgs(img[:,:,0]).astype(np.uint8) for img in imgs_lr]
            imgs_hr = [loader.unscale_hr_imgs(img[:,:,0]).astype(np.uint8) for img in imgs_hr]
            imgs_sr = [loader.unscale_hr_imgs(img[:,:,0]).astype(np.uint8) for img in imgs_sr]
        else:
            if(colorspace == 'YCbCr'):
                imgs_lr = [cv2.cvtColor(loader.unscale_lr_imgs(img).astype(np.uint8), cv2.COLOR_YCrCb2BGR) for img in imgs_lr]
                imgs_hr = [cv2.cvtColor(loader.unscale_hr_imgs(img).astype(np.uint8), cv2.COLOR_YCrCb2BGR) for img in imgs_hr]
                imgs_sr = [cv2.cvtColor(loader.unscale_hr_imgs(img).astype(np.uint8), cv2.COLOR_YCrCb2BGR) for img in imgs_sr]

            else:
                imgs_lr = [loader.unscale_lr_imgs(img).astype(np.uint8) for img in imgs_lr]
                imgs_hr = [loader.unscale_hr_imgs(img).astype(np.uint8) for img in imgs_hr]
                imgs_sr = [loader.unscale_hr_imgs(img).astype(np.uint8) for img in imgs_sr]

        # Loop through images
        for img_hr, img_lr, img_sr, img_path in zip(imgs_hr, imgs_lr, imgs_sr, test_images):
            # Get the filename
            filename = os.path.basename(img_path).split(".")[0]

            # Bicubic upscale
            hr_shape = (int(img_hr.shape[1]), int(img_hr.shape[0]))
            img_bi = cv2.resize(img_lr,hr_shape, interpolation = cv2.INTER_CUBIC)

            # Images and titles
            images = {
                'Low Resoluiton': [img_lr, img_hr],
                'Bicubic': [img_bi, img_hr],
                name: [img_sr, img_hr],
                'Original': [img_hr,img_hr]
            }
            srgan_psnr.append(psnr(img_sr,img_hr,255.))
            bi_psnr.append(psnr(img_bi,img_hr,255.))
            # Plot the images. Note: rescaling and using squeeze since we are getting batches of size 1
            fig, axes = plt.subplots(1, 4, figsize=(40, 10))
            for i, (title, img) in enumerate(images.items()):
                axes[i].imshow(img[0])
                axes[i].set_title("{} - {} {}".format(title+'_'+str(loader.scale)+'x', img[0].shape, ("- psnr: "+str(round(psnr(img[0],img[1],255.),2)) if (title == name or title == 'Bicubic' ) else " ")))
                #axes[i].set_title("{} - {}".format(title, img.shape))
                axes[i].axis('off')
            plt.suptitle('{} - Epoch: {}'.format(filename, epoch))

            # Save directory
            savefile = os.path.join(test_output, "{}-Epoch{}.png".format(filename, epoch))
            fig.savefig(savefile)
            plt.close()
            gc.collect()
        print('>> Test {} psnr: {} - test bi psnr: {}'.format(name,np.mean(srgan_psnr),np.mean(bi_psnr)))
    except Exception as e:
        print(e)


import pytest
from rhoknp import Morpheme

from kwja.utils.word_normalization import (
    MorphemeDenormalizer,
    MorphemeNormalizer,
    get_normalized,
    get_word_norm_op_tags,
)

wellformed_list = [
    ("なぁ", ["K", "S"], "なあ"),
    ("なー", ["K", "D"], "な"),
    ("な〜", ["K", "D"], "な"),
    ("おっ", ["K", "D"], "お"),
    ("さぁ", ["K", "S"], "さあ"),
    ("だぁ", ["K", "D"], "だ"),
    ("ねぇ", ["K", "S"], "ねえ"),
    ("うむっ", ["K", "K", "D"], "うむ"),
    ("のッ", ["K", "D"], "の"),
    ("バイキングっ", ["K", "K", "K", "K", "K", "D"], "バイキング"),
    ("楽しむっ", ["K", "K", "K", "D"], "楽しむ"),
    ("あっっっっっ", ["K", "K", "D", "D", "D", "D"], "あっ"),
    ("ますぅ", ["K", "K", "D"], "ます"),
    ("かい〜", ["K", "K", "D"], "かい"),
    ("そう〜", ["K", "K", "D"], "そう"),
    ("おーい", ["K", "D", "K"], "おい"),
    ("あーーー", ["K", "K", "D", "D"], "あー"),
    ("自然ー", ["K", "K", "D"], "自然"),
    ("きたー", ["K", "K", "D"], "きた"),
    ("ましたー", ["K", "K", "K", "D"], "ました"),
    ("ました〜", ["K", "K", "K", "D"], "ました"),
    ("飲んだー", ["K", "K", "K", "D"], "飲んだ"),
    ("続くー", ["K", "K", "D"], "続く"),
    ("寒〜い", ["K", "D", "K"], "寒い"),
    ("いや〜", ["K", "K", "D"], "いや"),
    ("あっちこち", ["K", "D", "K", "K", "K"], "あちこち"),
    ("かるーい", ["K", "K", "D", "K"], "かるい"),
    ("ずーっと", ["K", "P", "K", "K"], "ずうっと"),
    ("よー", ["K", "P"], "よう"),
    ("もーれつ", ["K", "P", "K", "K"], "もうれつ"),
    ("咲いたー", ["K", "K", "K", "D"], "咲いた"),
    ("なぁ〜", ["K", "S", "D"], "なあ"),
    ("ふわーっと", ["K", "K", "D", "K", "K"], "ふわっと"),
    ("ずら〜っと", ["K", "K", "D", "K", "K"], "ずらっと"),
    ("でーす", ["K", "D", "K"], "です"),
    ("で〜す", ["K", "D", "K"], "です"),
    ("まーす", ["K", "D", "K"], "ます"),
    ("ま〜す", ["K", "D", "K"], "ます"),
    ("いや〜", ["K", "K", "D"], "いや"),
    ("やったぁー", ["K", "K", "K", "D", "D"], "やった"),
    ("安っぽぃ", ["K", "K", "K", "S"], "安っぽい"),
    ("安っぽぃー", ["K", "K", "K", "S", "D"], "安っぽい"),
    ("だー", ["K", "D"], "だ"),
    ("ね〜", ["K", "E"], "ねえ"),
    ("すっげー", ["K", "D", "K", "E"], "すげえ"),
    ("まぁまぁだ", ["K", "S", "K", "S", "K"], "まあまあだ"),
    ("びみょーーー", ["K", "K", "K", "P", "D", "D"], "びみょう"),
    ("ごめんなさーぃ", ["K", "K", "K", "K", "K", "D", "S"], "ごめんなさい"),
    ("あっまい", ["K", "D", "K", "K"], "あまい"),
    ("もどかしー", ["K", "K", "K", "K", "P"], "もどかしい"),
    ("かわぃぃー", ["K", "K", "S", "S", "D"], "かわいい"),
    ("ほどよぃー", ["K", "K", "K", "S", "D"], "ほどよい"),
    ("あぉーい", ["K", "S", "D", "K"], "あおい"),
    ("鎌ヶ谷", ["K", "S", "K"], "鎌ケ谷"),
    ("龍ヶ崎", ["K", "S", "K"], "龍ケ崎"),
    ("八ヶ岳", ["K", "S", "K"], "八ケ岳"),
    ("湯ヶ島", ["K", "S", "K"], "湯ケ島"),
    ("がえる", ["V", "K", "K"], "かえる"),
    ("がえるー", ["V", "K", "K", "D"], "かえる"),
]

@pytest.mark.parametrize("surf,ops,expected", wellformed_list)
def test_gen_normalized_surf(surf, ops, expected):
    assert get_normalized(surf, ops, strict=True) == expected

@pytest.mark.parametrize("surf,expected,normalized", wellformed_list)
def test_get_normalization_opns(surf, expected, normalized):
    word_norm_op_tags = get_word_norm_op_tags(surf, normalized)
    assert len(word_norm_op_tags) == len(expected)
    assert all([a == b for a, b in zip(word_norm_op_tags, expected)])

malformed_list = [
    ("なあ", ["K", "S"], "なあ"),
    ("なー", ["K", "S"], "なー"),
    ("ー", ["P"], "ー"),
]

@pytest.mark.parametrize("surf,ops,expected", malformed_list)
def test_gen_normalized_surf_malformed(surf, ops, expected):
    with pytest.raises(ValueError):
        get_normalized(surf, ops, strict=True)

@pytest.mark.parametrize("surf,ops,expected", malformed_list)
def test_gen_normalized_surf_malformed_loose(surf, ops, expected):
    assert get_normalized(surf, ops, strict=False) == expected

def test_morpheme_normalizer():
    jumanpp_text = 'きたー きた きる 動詞 2 * 0 母音動詞 1 タ形 10 "代表表記:着る/きる ドメイン:家庭・暮らし 反義:動詞:脱ぐ/ぬぐ 非標準表記:DPL"'
    expected = ["K", "K", "D"]
    morpheme = Morpheme.from_jumanpp(jumanpp_text)
    normalizer = MorphemeNormalizer()
    word_norm_op_tags = normalizer.get_word_norm_op_tags(morpheme)
    assert len(word_norm_op_tags) == len(expected)
    assert all([a == b for a, b in zip(word_norm_op_tags, expected)])

@pytest.mark.parametrize(
    "surf,expected",
    [
        ("なあ", "なぁ"),
        ("さあ", "さぁ"),
        ("もうれつ", "もーれつ"),
        ("鎌ケ谷", "鎌ヶ谷"),
        ("八ケ岳", "八ヶ岳"),
    ],
)
def test_denormalize_deterministic(surf, expected):
    md = MorphemeDenormalizer()
    assert md._denormalize_deterministic(surf) == expected


#!/usr/bin/env python3.8

'''
main.py
Jason Miles

currently used to run backtesting
'''

import sys

from testing.backtest import Backtest

def usage():
    print('''
    ./main.py [arguments]

    arguments:
        -p              : run in production mode

        -b <file>       : run backtesting on data from file
        -i <interval>   : data point interval in minutes

        -s <strategy>   : use a specific trading strategy
                            default: curves
                            other: crosses , prediction
        -d <amount>     : deposit a specific initial amount of $
        -t <token>      : token to buy/sell
        -u <units>      : amount of units to buy/sell per transaction
        -v              : verbose - print updates

        -l <n>          : low end moving average
        -h <n>          : high end moving average
    ''')

if __name__ == '__main__':

    usage()

    # setup vars
    production_mode = False
    backtest = True
    datafile = './data/sheets/algusd.csv'
    interval = 60
    strategy = 'curves'
    depo_amt = 1000
    token = 'alg'
    units = 100
    verbose = True
    short_avg = 10
    long_avg = 100

    # read args
    cmd_line = sys.argv[1:]
    arg = cmd_line.pop(0)

    while arg:
        if arg[0] == '-':
            if arg[1] == 'p':
                production_mode = True
                print("running in production mode")
            if arg[1] == 'b':
                backtest = True
                datafile = cmd_line.pop(0)
                print("backtesting: ", datafile)
            if arg[1] == 'i':
                interval = int(cmd_line.pop(0))
                print("testing points every {} minutes".format(interval))
            if arg[1] == 's':
                strategy = cmd_line.pop(0)
                print("strategy: ", strategy)
            if arg[1] == 'd':
                depo_amt = int(cmd_line.pop(0))
                print("depositing: $", depo_amt)
            if arg[1] == 't':
                token = cmd_line.pop(0)
                print("token: ", token)
            if arg[1] == 'u':
                units = int(cmd_line.pop(0))
                print("units: ", units)
        # update
        try:
            arg = cmd_line.pop(0)
        except:
            break

    # run
    if backtest:

        # setup testing
        bt = Backtest()
        bt.load_data(datafile)
        bt.add_balance(depo_amt)

        if strategy == 'crosses':
            bt.set_strategy(strategy, short_avg, long_avg)
        elif strategy == 'curves':
            bt.set_strategy(strategy)

        # run testing
        bt.backtest(interval, token, units)


import base64
import hashlib
from django.http import HttpResponseRedirect
from django.shortcuts import render,redirect
from .models import Family
from django.views.decorators.csrf import csrf_exempt
from django.db.models import Q
from .forms import UploadFileForm
from django.core.files import File
from django.core.files.storage import FileSystemStorage

# Create your views here.
def main(request):
    return render(request, "morae/main.html")

def writing(request):
    return render(request, "morae/writing.html")

def details(request):
    addressValue = '모든'
    countryValue = '모든'
    context = {
        'address' : addressValue,
        'country' : countryValue,
        'family' : Family.objects.all()
    }

    if request.GET.get('address') != "":
        addressValue = request.GET.get('address')
        context = {
            'address' : addressValue,
            'country' : countryValue,
            'family' : Family.objects.filter(address__icontains = request.GET.get('address'))
        }

    if request.GET.get('country') != "":
        countryValue = request.GET.get('country')
        context = {
            'address' : addressValue,
            'country' : countryValue,
            'family' : Family.objects.filter(country__icontains = request.GET.get('country'))
        }

    if request.GET.get('country') != "" and request.GET.get('country') != "":
        context = {
            'address' : addressValue,
            'country' : countryValue,
            'family' : Family.objects.filter(country__icontains = request.GET.get('country') , address__icontains = request.GET.get('address'))
        }

    return render(request, "morae/details.html", context)

@csrf_exempt
def create(request):
    if request.method=="POST":
        kakao = request.POST.get('kakao')
        state= request.POST.get('state')
        address = request.POST.get('address')
        gmoney = request.POST.get('gmoney')
        kmoney = request.POST.get('kmoney')
        country = request.POST.get('country')
        detail = request.POST.get('detail')
        writepw = request.POST.get('writepw')

        tphoto = __create_file__(request.FILES['tphoto'])
        gphoto = __create_file__(request.FILES['gphoto'])

        Family.objects.create(state=state, address=address, gmoney=gmoney, kmoney=kmoney, country=country,
                              gphoto=gphoto, tphoto=tphoto, kakao=kakao, detail=detail, writepw=writepw)

        return redirect('/')

def __create_file__(myfile):
	fs = FileSystemStorage()
	filename = fs.save(myfile.name, myfile)
	uploaded_file_url = fs.url(filename)
	return myfile.name

@csrf_exempt
def delete(request):
    temppw = request.POST.get('userpw')
    tempkakao = request.POST.get('kakao2')

    realpw = Family.objects.filter(kakao=tempkakao, writepw = temppw)

    if realpw.exists():
        realpw.delete()

    return redirect('/')


class Solution(object):
    def maxIceCream(self, costs, coins):
        """
        :type costs: List[int]
        :type coins: int
        :rtype: int
        """

        totCoins = coins
        numIcecreams = 0
        myCosts = costs

        myCosts.sort()

        for cost in myCosts:
            totCoins = totCoins - cost
            if(totCoins >= 0 and len(myCosts) > 0):
                numIcecreams = numIcecreams + 1
            else:
                break

        return numIcecreams


# 최소비용 구하기 211005
"""
입력
첫째 줄에 도시의 개수 N(1 ≤ N ≤ 1,000)
둘째 줄에는 버스의 개수 M(1 ≤ M ≤ 100,000)
셋째 줄부터 M+2줄까지 다음과 같은 버스의 정보가 주어진다. 먼저 처음에는 그 버스의 출발 도시의 번호가 주어진다. 그리고 그 다음에는 도착지의 도시 번호가 주어지고 또 그 버스 비용이 주어진다. 버스 비용은 0보다 크거나 같고, 100,000보다 작은 정수이다.
그리고 M+3째 줄에는 우리가 구하고자 하는 구간 출발점의 도시번호와 도착점의 도시번호가 주어진다. 출발점에서 도착점을 갈 수 있는 경우만 입력으로 주어진다.
출력
출발-도착까지 최소비용
* 알고리즘
최단거리 or 방문하지 않은 경우를 들른 뒤 최단거리 업데이트하기
## 시작도시, 끝도시, 비용 3 정보를 활용해서 딕셔너리 형태로 연결시킬까?
    # 1: [(2, 2), (3, 3), (4, 1), (5, 10)], 2: [(4, 2),], 3: [(5, 1)], 4: [(5, 3)]
    이 방법 자체는 틀리지 않았는데 defaultdict를 활용해서 만들자

# 답을 보고 작성하였으나 다익스트라 알고리즘과 queue를 활용한 방법은 그대로 익혀야겠다.
코드중에선 아래의 코드가 제일 직관적

"""
# 입력값 처리 -> 리스트 컴프리헨션으로 s,e,c 정보를 하나의 리스트로 담았다가 바로 정보에 대한 처리를 하는게 더 효율적이라 코드 변경했다.
import sys
import heapq
from collections import defaultdict
input = sys.stdin.readline
graph = defaultdict(list)
distances = [1e9] * (n +1)

n = int(input()) # 도시 개수
for i in range(int(input())): # 출발, 도착, 비용 목록
    s,e,c = map(int, input().split())
    graph[s].append((e, c))
start, end = map(int, input().split()) # start, end 도시

def dijkstra(start):
    queue = []
    heapq.heappush(queue, (0, start)) # queue에 처음 넣는 정보는 (자기 자신과의 거리 0, 시작위치)

    while queue:
        # start에서 최소의 distance를 기준으로 heappop 해준다.
        dist, now = heapq.heappop(queue)
        if distances[now] < dist: # 입력받은 distance 보다 현재 거리가 더 낮다면 그대로 다음 큐로
            continue
        for node in graph[now]: # 그래프에서 현 위치의 연결포인트들
            cost = dist + node[1] # [1] 번 인덱스는 cost를 의미한다 [0] 인덱스는 연결된 도착위치
            if distances[node[0]] > cost:
                # 만약 이번에 든 비용보다 기존의 비용이 더 크다면 업데이트
                distances[node[0]] = cost
                heapq.heappush(queue, (cost, node[0])) # 힙에 넣어준다. 다음 장소 탐색을 위해

dijkstra(start)
print(distances[end])


"""Additional project metadata"""
# pylint: disable=invalid-name

from importlib import metadata as _meta

try:
    distribution = _meta.distribution(__name__.split(".")[0])
except _meta.PackageNotFoundError:  # pragma: no cover
    raise RuntimeError("DoorPi was not properly installed") from None

project = "VoIP Door-Intercomstation with Raspberry Pi"

supporters = (
    "Phillip Munz <office@businessaccess.info>",
    "Hermann Dötsch <doorpi1@gmail.com>",
    "Dennis Häußler <haeusslerd@outlook.com>",
    "Hubert Nusser <hubsif@gmx.de>",
    "Michael Hauer <frrr@gmx.at>",
    "Andreas Schwarz <doorpi@schwarz-ketsch.de>",
    "Max Rößler <max_kr@gmx.de>",
    "missing someone? -> sorry -> mail me",
)

# created with: http://patorjk.com/software/taag/#p=display&f=Ogre&t=DoorPi
epilog = r"""
    ___                  ___ _
   /   \___   ___  _ __ / _ (_)  {project}
  / /\ / _ \ / _ \| '__/ /_)/ |  version:   {version}
 / /_// (_) | (_) | | / ___/| |  license:   {license}
/___,' \___/ \___/|_| \/    |_|  URL:       <{url}>

Author:     {author}
Supporter:  {supporters}
""".format(
    license=distribution.metadata["License"],
    project=distribution.metadata["Name"],
    version=distribution.metadata["Version"],
    author="{} <{}>".format(
        distribution.metadata["Author"], distribution.metadata["Author-email"]
    ),
    supporters="\n            ".join(supporters),
    url=distribution.metadata["Home-page"],
)


from chip8_machine import Chip8Machine
import pytest
import numpy

TEST_SIZE = 50

machine = Chip8Machine()

@pytest.fixture
def sprite1():
	return numpy.array([0xAA, 0x55])

@pytest.fixture
def valid_memory_addresses():
	return numpy.random.randint(0x0, 0x1000, size=TEST_SIZE)

def test_screen(sprite1):
	x = 7
	y = 5

	white = 0xFFFFFF

	manual_array = numpy.zeros(shape=(machine.get_screen_width(), machine.get_screen_height()), dtype=int)

	manual_array[7,5] = white
	manual_array[8,5] = 0
	manual_array[9,5] = white
	manual_array[10,5] = 0
	manual_array[11,5] = white
	manual_array[12,5] = 0
	manual_array[13,5] = white
	manual_array[14,5] = 0

	manual_array[7,6] = 0
	manual_array[8,6] = white
	manual_array[9,6] = 0
	manual_array[10,6] = white
	manual_array[11,6] = 0
	manual_array[12,6] = white
	manual_array[13,6] = 0
	manual_array[14,6] = white

	machine.draw_sprite(sprite1, x, y)

	assert numpy.array_equal(machine.get_screen_state(), manual_array)

	machine.clear_screen()
	assert numpy.array_equal(machine.get_screen_state(), numpy.zeros(shape=(machine.get_screen_width(), machine.get_screen_height()), dtype=int))

def test_read_write_registers():
	for i in range(16):
		number = numpy.random.randint(0,0x100)
		machine.write_register(i, number)
		assert machine.read_register(i) == number

def test_read_write_memory_register():
	number = numpy.random.randint(0, 0xFFF)
	machine.write_memory_register(number)
	assert machine.read_memory_register() == number

def test_overflow_underflow_registers():
	for i in range(16):
		machine.write_register(i, 0xAAA)
		assert machine.read_register(i) == 0xAA

		machine.write_register(i, -0x1)
		assert machine.read_register(i) == 0xFF

		machine.write_memory_register(0x11111)
		assert machine.read_memory_register() == 0x1111

		machine.write_memory_register(-0x1)
		assert machine.read_memory_register() == 0xFFFF

def test_read_write_memory():
	address = numpy.random.randint(0, 0x1001)
	number = numpy.random.randint(0,0x100)
	machine.write_memory(address, number)
	assert machine.read_memory(address) == number

def test_stack(valid_memory_addresses):
	for address in valid_memory_addresses:
		machine.push_stack(address)

	for i in range(TEST_SIZE):
		assert machine.pop_stack() == valid_memory_addresses[-i-1]

def test_timers():
	machine.set_timer(0xAA)
	machine.timer_tick()
	assert machine.get_remaining_time() == 0xA9

	machine.set_sound_timer(0x1)
	machine.sound_timer_tick()
	assert machine.get_remaining_sound_time() == 0x0


"""Miscellaneous analyses of EEG data."""
# %%
# Imports
import numpy as np
import pandas as pd

from config import ANALYSIS_DIR_LOCAL, BAD_SUBJS

# %%
# Settings

analysis_dir = ANALYSIS_DIR_LOCAL

# %%
# File paths
dropped_epochs = analysis_dir / "derived_data" / "dropped_epochs.tsv"

bad_channels_template = (
    analysis_dir / "derived_data" / "annotations" / "sub-{:02}_bad-channels.txt"
)

# %%
# Analyze dropped epochs
df_dropped_epochs = pd.read_csv(dropped_epochs, sep="\t")

mean_retained = 100 - df_dropped_epochs["perc_rejected"].mean()
print(
    f"On average, {np.mean(df_dropped_epochs['nkept_epos']):.0f} "
    "({mean_retained:.1f} %) of epochs were retained per participant."
)

# %%
# Analyze interpolated channels
data = dict(sub=[], nbad=[])
for sub in range(1, 33):
    if sub in BAD_SUBJS:
        continue
    fname = str(bad_channels_template).format(sub)
    with open(fname, "r") as fin:
        lines = fin.readlines()
    nbad = len(lines)
    data["sub"].append(sub)
    data["nbad"].append(nbad)

df_bad_chs = pd.DataFrame.from_dict(data)

mean_bad = np.round(df_bad_chs["nbad"].mean(), 1)
std_bad = np.round(df_bad_chs["nbad"].std(), 1)

print(f"On average, {mean_bad}+-{std_bad} channels were interpolated per participant.")

# %%


from tkinter import *
import requests
from tkinter import messagebox
def clearAll() :
    fromField.delete(0, END)
    toField.delete(0, END)
    amountField.delete(0, END)
    finField.delete(0, END)
def checkError() :
    if (fromField.get() == "" or toField.get() == "" or amountField.get() == "") :
        messagebox.showerror("Input Error")
        clearAll()
        return
def prior():
    from_currency = (fromField.get())
    to_currency = (toField.get())
    amount = int(amountField.get())
    currency_conversion(from_currency,to_currency,amount)
def currency_conversion():
    from_currency = (fromField.get())
    to_currency = (toField.get())
    amount = int(amountField.get())
    response=requests.get(url)
    rate=response.json()['rates'][from_currency]
    amount_in_EUR=amount/rate
    amount=amount_in_EUR*(response.json()['rates'][to_currency])
    finField.insert(10, str(amount))
if __name__ == "__main__" :
    url = str.__add__('http://data.fixer.io/api/latest?access_key=', '7cdf410b0b856588f3c1f803302d1834')
    window = Tk()
    window.configure(background = "light green")
    window.title("Currency Convertor")
    window.geometry("525x300")
    dob = Label(window, text = "Enter Details", bg = "orange")
    from_label = Label(window, text = "from", bg = "turquoise")
    to_label = Label(window, text = "To", bg = "turquoise")
    amount_label = Label(window, text = "Amount", bg = "turquoise")
    convAmt = Label(window, text = "Converted Amount", bg = "turquoise")
    convert = Button(window, text = "Convert", fg = "white", bg = "black", command =currency_conversion)
    clearAllEntry = Button(window, text = "Clear All", fg = "white", bg = "black", command = clearAll)
    fromField= Entry(window)
    toField= Entry(window)
    amountField= Entry(window)
    finField=Entry(window)
    dob.grid(row = 0, column = 1)
    from_label.grid(row = 1, column = 0)
    fromField.grid(row = 1, column = 1)
    to_label.grid(row = 2, column = 0)
    toField.grid(row = 2, column = 1)
    amount_label.grid(row = 3, column = 0)
    amountField.grid(row = 3, column = 1)
    convert.grid(row = 4, column = 2)
    convAmt.grid(row = 9, column = 2)
    finField.grid(row = 10, column = 2)
    clearAllEntry.grid(row = 12, column = 2)
    window.mainloop()


from django.db import models
from multiselectfield import MultiSelectField
class EnquiryData(models.Model):
    name=models.CharField(max_length=100)
    email=models.EmailField(max_length=100)
    mobile=models.BigIntegerField()
    COURSES_CHOICES=(
        ('python','PYTHON'),
        ('django','DJANGO'),
        ('UI','UI'),
        ('Rest Api','REST API')
    )
    courses=MultiSelectField(max_length=100,choices=COURSES_CHOICES)
    TRSINERS_CHOICES=(
        ('narayana','NARAYANA'),
        ('Srinivas','SRINIVAS'),
        ('mohan reddy','MOHAN REDDY'),
        ('wilson','WILSON')
    )
    trainers=MultiSelectField(max_length=100,choices=TRSINERS_CHOICES)
    SHIFTS_CHOICES=(
        ('Morning','MORNING'),
        ('evening','EVENING'),
        ('night','NIGHT')
    )
    shifts=MultiSelectField(max_length=100,choices=SHIFTS_CHOICES)
    LOCATIONS_CHOICES=(
        ('ameerpet','AMEERPET'),
        ('madhapur','MADHAPUR'),
        ('KPHB','KPHB')
    )
    location=MultiSelectField(max_length=100,choices=LOCATIONS_CHOICES)
    start_date=models.DateField(max_length=100)
    gender=models.CharField(max_length=100)


# 회의실 배정
import sys
sys.stdin = open('input.txt', 'r')
input = sys.stdin.readline

N = int(input()) # 회의 수
A = [[0] * 2 for _ in range(N)]

for i in range(N):
  S, E = map(int, input().split())
  A[i][0] = E # 종료시각 우선 정렬이 먼저이므로 0번째에 종료 시각 먼저 저장
  A[i][1] = S

A.sort()
count = 0
end = -1

for i in range(N):
  if A[i][1] >= end: # 겹치지 않는 다음 회의가나온 경우
    end = A[i][0]
    count += 1
print(count)


import numpy as np
import tensorflow as tf
import sys

tf.reset_default_graph()

# he initializer
he_init = tf.contrib.layers.variance_scaling_initializer(factor=1.0)
l2_reg = tf.contrib.layers.l2_regularizer(0.001)
# l2_reg = None

# make model
X = tf.placeholder(tf.float32,shape=[None,50,50,50,1])
y = tf.placeholder(tf.int32, shape=[None])

conv1 = tf.layers.conv3d(X,12,[5,5,5], padding='same', kernel_initializer=he_init, kernel_regularizer=l2_reg)
relu1 = tf.nn.elu(conv1)
maxpool1 = tf.layers.max_pooling3d(relu1, [4,4,4],[3,3,3])

conv2 = tf.layers.conv3d(maxpool1, 24, [5,5,5], padding='same', kernel_initializer=he_init, kernel_regularizer=l2_reg)
relu2 = tf.nn.elu(conv2)
maxpool2 = tf.layers.max_pooling3d(relu2, [4,4,4], [3,3,3])

n_layer = np.prod(maxpool2.shape[1:])._value
flat_layer = tf.reshape(maxpool2,shape=[-1,n_layer])

dense1 = tf.layers.dense(flat_layer, 1500, activation=tf.nn.elu, kernel_initializer=he_init, kernel_regularizer=l2_reg)
dense2 = tf.layers.dense(dense1, 1000, activation=tf.nn.elu, kernel_initializer=he_init, kernel_regularizer=l2_reg)
logits = tf.layers.dense(dense2,19,kernel_initializer=he_init)

# loss function
loss = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=y)
optimizer = tf.train.AdamOptimizer(learning_rate = 0.001)
train_op = optimizer.minimize(loss)

# accuracy evaluation
correct_predictions = tf.nn.in_top_k(logits, y, 1)
accuracy = tf.reduce_mean(tf.cast(correct_predictions,tf.float32))

# load data
from csp_tools import *
#X_train, y_train = load_data_range(range(19),range(40))
#X_val, y_val = load_data_range(range(19),range(40,45))
X_test, y_test = load_data_range(range(19), range(45,50))

saver = tf.train.Saver()
with tf.Session() as sess:
    saver.restore(sess, 'CSP.epoch_99.ckpt')
    acc = sess.run(accuracy, feed_dict = {X: X_test, y: y_test})
    print('test set accuracy =',acc)


from .functions import *
from common.types import *
from common.utils import Singleton

from camera.assets import cameraStoreConfig

import os
import json
import shutil
import subprocess
from pathlib import Path
from datetime import datetime

from typing import Dict

from PIL import Image as PILImage
from picamera2 import Picamera2, Preview

class MyCamera(metaclass=Singleton):
    def __init__(self):
        """
        video : 현재 저장되고 있는 영상!
        """
        self._video:Video = Video(mode="", title="", format="", duration={"start":datetime.now(), "end":datetime.now()}, width=1, height=1, frames=[])
        self._camera = Picamera2()
        self._configure_camera()
        self._camera.start()

        self._isConnected = False

    def __del__(self):
        self._camera.close()

    def _configure_camera(self):
        self._camera.start_preview(Preview.NULL)
        config = self._camera.create_still_configuration()
        config['buffer_count'] = 5
        self._camera.configure(config)

    @property
    def video(self):
        return self._video

    @property
    def isConnected(self):
        return self._isConnected

    async def start_video(self, title:str, width:int, height:int)->None:
        """
        video를 새로 지정하고, 해당 비디오와 동일한 구성요소가 디스크에 있으면 지운다.
        """
        self._video = Video(mode="RGBA", title=title, format="jpeg", duration={"start":datetime.now(), "end":datetime.now()}, width=width, height=height, frames=[])

        if (cameraStoreConfig['paths']['frames'] / title).exists():
            shutil.rmtree(cameraStoreConfig['paths']['frames'] / title)

        if (cameraStoreConfig['paths']['videos'] / title).exists():
            shutil.rmtree(cameraStoreConfig['paths']['videos'] / title)

        os.makedirs(cameraStoreConfig['paths']['frames'] / title, exist_ok=False)
        os.makedirs(cameraStoreConfig['paths']['videos'], exist_ok=True)

        self._isConnected = True
        return None

    async def end_video(self, savedTitle:str) -> None:
        """
        Video 저장하기, 저장경로에 다른 파일이 있다면 지운다.
        """
        if (cameraStoreConfig['paths']['frames'] / savedTitle).exists():
            shutil.rmtree(cameraStoreConfig['paths']['frames'] / savedTitle)
        subprocess.run(['mv', cameraStoreConfig['paths']['frames'] / self.video.title, cameraStoreConfig['paths']['frames'] / savedTitle])

        self.video.title = savedTitle
        self.video.duration["end"] = datetime.now()

        with open(cameraStoreConfig['paths']['videos'] / f"{savedTitle}.json", "w") as fd:
            fd.write(self.video.json())

        self._isConnected = False
        return None

    async def capture(self)->Image:
        """
        사진을 찍고 Image로 반환!
        """
        frame = Frame(id=len(self.video.frames) + 1, captured=datetime.now())
        img:PILImage = self._camera.capture_image().resize([self.video.width, self.video.height], PILImage.Resampling.NEAREST)
        bytesImg = await make_bytes_from_img(img)
        img.close()

        self.video.frames.append(frame)
        return Image(captured=frame.captured, width=self.video.width, height=self.video.height, risked=[], src=self.video.title, id=frame.id, data=bytesImg)

    async def save_frame(self, image:Image) -> bool:
        """
        이미지 저장!
        """
        try:
            name = await make_frame_name(self.video, image.id)
            img = await make_img_from_bytes(image.data, self.video.width, self.video.height)
            img.save(name + '.' + self.video.format)
            with open(name + ".json", 'w') as fd:
                fd.write(image.json())

            return True
        except Exception as e:
            print(e)
            return False

    async def get_frame(self, id: int)->Image:
        """
        Video의 특정 프레임 이미지 가져오기!
        """
        name = await make_frame_name(self.video, id)
        name = name + ".json"
        if not os.path.exists(name):
            raise FileNotFoundError
        else:
            with open(name, 'r') as fd:
                return Image(**json.load(fd))


from adventofcode.year_2021.day_08_2021 import (
    part_two,
    part_one,
    parse_input,
    count_unique_segments,
    get_unique_segments,
    pattern_translation_table,
    patterns_as_frozen_sets,
    get_output_for_line,
)

test_input = [
    "be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe",
    "edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc",
    "fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg",
    "fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb",
    "aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea",
    "fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb",
    "dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe",
    "bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef",
    "egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb",
    "gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce",
]

test_input_single_line = [
    "acedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab | cdfeb fcadb cdfeb cdbaf",
]

def test_parse_input():
    parsed = parse_input(test_input)
    assert len(parsed) == 10

def test_pattern_translation_table():
    patterns, _ = parse_input(test_input_single_line)[0]
    fs_patterns = patterns_as_frozen_sets(patterns.split(" "))
    assert pattern_translation_table(fs_patterns) == {
        frozenset({"a", "b"}): 1,
        frozenset({"a", "d", "b"}): 7,
        frozenset({"a", "f", "b", "e"}): 4,
        frozenset({"d", "c", "f", "b", "e"}): 5,
        frozenset({"a", "d", "c", "f", "g"}): 2,
        frozenset({"a", "d", "c", "f", "b"}): 3,
        frozenset({"a", "d", "c", "f", "b", "e"}): 9,
        frozenset({"d", "c", "f", "b", "g", "e"}): 6,
        frozenset({"a", "d", "c", "b", "g", "e"}): 0,
        frozenset({"a", "d", "c", "f", "b", "g", "e"}): 8,
    }

def test_get_output_for_line():
    line = parse_input(test_input_single_line)[0]
    assert get_output_for_line(line) == 5353

def test_get_unique_segments():
    parsed = parse_input(test_input_single_line)
    assert get_unique_segments(parsed[0][0]) == ["acedgfb", "dab", "eafb", "ab"]

def test_count_unique_segments():
    parsed = parse_input(test_input)
    assert count_unique_segments(parsed) == 26

def test_part_one():
    answer = part_one(test_input)
    assert answer == 26

def test_part_two():
    answer = part_two(test_input)
    assert answer == 61229


from __future__ import print_function

import numpy as np
import cv2

IMAGE_SIZE = 224
RED_MEAN = 123.68
GREEN_MEAN = 116.779
BLUE_MEAN = 103.939
def load_image(image_path):
    image = cv2.imread(image_path)
    shorter_dimension = np.min(image.shape[:2])
    width_offet = (image.shape[0] - shorter_dimension)/2
    height_offet = (image.shape[1] - shorter_dimension)/2
    image = image[width_offet:width_offet+shorter_dimension, height_offet:height_offet+shorter_dimension]
    image = cv2.resize(image, (IMAGE_SIZE, IMAGE_SIZE))
    image = image.astype(np.float)
    #opencv read image as BGR format
    image[:, :, 0] = image[:, :, 0] - BLUE_MEAN
    image[:, :, 1] = image[:, :, 1] - GREEN_MEAN
    image[:, :, 2] = image[:, :, 2] - RED_MEAN
    return image

def print_top_5(probability, label_file_path):
    with open(label_file_path, 'r') as label_file:
        labels = [ line.strip() for line in label_file.readlines()]

    for i in xrange(len(probability)):
        row_output = probability[i,:]
        sort_index = np.argsort(row_output)[::-1]
        for i in xrange(5):
            index = sort_index[i]
            print ('top %d: %s (%0.2f)' % (i+1, labels[index], row_output[index]))


def shoot(i, p, old_list):
    i = int(i)
    p = int(p)
    if 0 <= i < len(old_list):
        old_list[i] -= p
        if old_list[i] <= 0:
            old_list.pop(i)
    return old_list

def add(i, v, old_list):
    i = int(i)
    v = int(v)
    if 0 <= i < len(old_list):
        old_list.insert(i, v)
    else:
        print("Invalid placement!")
    return old_list

def strike(i, r, old_list):
    i = int(i)
    r = int(r)
    if 0 <= i < len(old_list):
        if i - r >= 0 and i + r < len(old_list):
            new_list = old_list[0:(i - r)] + old_list[(i + r + 1):]
            return new_list
    print("Strike missed!")
    return old_list

targets = input().split()
targets = [int(x) for x in targets]
command = input()
while command != "End":
    command = command.split()
    if command[0] == "Shoot":
        targets = shoot(command[1], command[2], targets)
    elif command[0] == "Add":
        targets = add(command[1], command[2], targets)
    elif command[0] == "Strike":
        targets = strike(command[1], command[2], targets)
    command = input()
targets = [str(n) for n in targets]
print("|".join(targets))

Fundamentals/MID EXAM/03. Moving Target.py


from django.shortcuts import render
from comentarios.models import Comentarios
from django.views.generic import ListView, CreateView, UpdateView, DeleteView
from django.views import generic

from comentarios.forms import ComentariosCreateForm
from django.urls import reverse_lazy

from django.contrib.auth.mixins import LoginRequiredMixin

# Create your views here.

class ComentariosListView(ListView):
    model = Comentarios
    context_object_name = 'comentarios'
    template_name = 'comentarios/showComentarios.html'
    ordering = ['created_at',]

class ComentariosCreateView(LoginRequiredMixin, CreateView):
    model = Comentarios
    template_name = 'comentarios/createComentarios.html'
    form_class = ComentariosCreateForm
    success_url =  reverse_lazy('comentarios:showComentarios') #used for user pages redirection from CreatePosts to showPosts.

class ComentariosUpdateView(LoginRequiredMixin, UpdateView):
    model = Comentarios
    fields = {'comentario','post'}
    template_name = 'comentarios/update_comentarios.html'
    success_url = reverse_lazy('comentarios:showComentarios')

class ComentariosDeleteView(LoginRequiredMixin, DeleteView):
    model = Comentarios
    context_object_name = 'comentarios'
    template_name = 'comentarios/delete_comentarios.html'
    success_url = reverse_lazy('comentarios:showComentarios')


import argparse
import os

import torch
import yaml
import torch.nn as nn
import torch.multiprocessing as mp
from torch.utils.tensorboard import SummaryWriter
from torch.utils.data import DistributedSampler, DataLoader
from torch.distributed import init_process_group
from torch.nn.parallel import DistributedDataParallel
from torch.cuda import amp

from tqdm import tqdm

from utils.model import get_model, get_vocoder, get_param_num
from utils.tools import get_configs_of, to_device, log, synth_one_sample
from model import PortaSpeechLoss
from dataset import Dataset

from evaluate import evaluate

torch.backends.cudnn.benchmark = True

def train(rank, args, configs, batch_size, num_gpus):
    preprocess_config, model_config, train_config = configs
    if num_gpus > 1:
        init_process_group(
            backend=train_config["dist_config"]['dist_backend'],
            init_method=train_config["dist_config"]['dist_url'],
            world_size=train_config["dist_config"]['world_size'] * num_gpus,
            rank=rank,
        )
    device = torch.device('cuda:{:d}'.format(rank))

    # Get dataset
    dataset = Dataset(
        "train.txt", preprocess_config, model_config, train_config, sort=True, drop_last=True
    )
    data_sampler = DistributedSampler(dataset) if num_gpus > 1 else None
    group_size = 4  # Set this larger than 1 to enable sorting in Dataset
    assert batch_size * group_size < len(dataset)
    loader = DataLoader(
        dataset,
        batch_size=batch_size * group_size,
        shuffle=False,
        sampler=data_sampler,
        collate_fn=dataset.collate_fn,
    )

    # Prepare model
    model, optimizer = get_model(args, configs, device, train=True)
    if num_gpus > 1:
        model = DistributedDataParallel(model, device_ids=[rank]).to(device)
    scaler = amp.GradScaler(enabled=args.use_amp)
    Loss = PortaSpeechLoss(
        preprocess_config, model_config, train_config).to(device)

    # Load vocoder
    vocoder = get_vocoder(model_config, device)

    # Training
    step = args.restore_step + 1
    epoch = 1
    grad_acc_step = train_config["optimizer"]["grad_acc_step"]
    grad_clip_thresh = train_config["optimizer"]["grad_clip_thresh"]
    total_step = train_config["step"]["total_step"]
    log_step = train_config["step"]["log_step"]
    save_step = train_config["step"]["save_step"]
    synth_step = train_config["step"]["synth_step"]
    val_step = train_config["step"]["val_step"]

    if rank == 0:
        print("Number of PortaSpeech Parameters: {}\n".format(get_param_num(model)))
        # Init logger
        for p in train_config["path"].values():
            os.makedirs(p, exist_ok=True)
        train_log_path = os.path.join(
            train_config["path"]["log_path"], "train")
        val_log_path = os.path.join(train_config["path"]["log_path"], "val")
        os.makedirs(train_log_path, exist_ok=True)
        os.makedirs(val_log_path, exist_ok=True)
        train_logger = SummaryWriter(train_log_path)
        val_logger = SummaryWriter(val_log_path)

        outer_bar = tqdm(total=total_step, desc="Training", position=0)
        outer_bar.n = args.restore_step
        outer_bar.update()

    train = True
    while train:
        if rank == 0:
            inner_bar = tqdm(total=len(loader),
                             desc="Epoch {}".format(epoch), position=1)
        if num_gpus > 1:
            data_sampler.set_epoch(epoch)
        for batchs in loader:
            if train == False:
                break
            for batch in batchs:
                batch = to_device(batch, device)

                with amp.autocast(args.use_amp):
                    # Forward
                    output = model(*(batch[2:]))

                    # Cal Loss
                    losses = Loss(batch, output, step)
                    total_loss = losses[0]
                    total_loss = total_loss / grad_acc_step

                # Backward
                scaler.scale(total_loss).backward()

                # Clipping gradients to avoid gradient explosion
                if step % grad_acc_step == 0:
                    scaler.unscale_(optimizer._optimizer)
                    torch.nn.utils.clip_grad_norm_(
                        model.parameters(), grad_clip_thresh)

                # Update weights
                optimizer.step_and_update_lr(scaler)
                scaler.update()
                optimizer.zero_grad()

                if rank == 0:
                    if step % log_step == 0:
                        losses = [l.item() for l in losses]
                        message1 = "Step {}/{}, ".format(step, total_step)
                        message2 = "Total Loss: {:.4f}, Mel Loss: {:.4f}, KL Loss: {:.4f}, PN Loss: {:.4f}, Duration Loss: {:.4f}, Helper Loss: {:.4f}".format(
                            *losses
                        )

                        with open(os.path.join(train_log_path, "log.txt"), "a") as f:
                            f.write(message1 + message2 + "\n")

                        outer_bar.write(message1 + message2)

                        log(train_logger, step, losses=losses)

                    if step % synth_step == 0:
                        fig, attn_fig, wav_reconstruction, wav_prediction, tag = synth_one_sample(
                            model,
                            batch,
                            output,
                            vocoder,
                            model_config,
                            preprocess_config,
                            num_gpus,
                        )
                        log(
                            train_logger,
                            fig=fig,
                            tag="Training/step_{}_{}".format(step, tag),
                        )
                        log(
                            train_logger,
                            fig=attn_fig,
                            tag="Training_attn/step_{}_{}".format(step, tag),
                        )
                        sampling_rate = preprocess_config["preprocessing"]["audio"][
                            "sampling_rate"
                        ]
                        log(
                            train_logger,
                            audio=wav_reconstruction,
                            sampling_rate=sampling_rate,
                            tag="Training/step_{}_{}_reconstructed".format(
                                step, tag),
                        )
                        log(
                            train_logger,
                            audio=wav_prediction,
                            sampling_rate=sampling_rate,
                            tag="Training/step_{}_{}_synthesized".format(
                                step, tag),
                        )

                    if step % val_step == 0:
                        model.eval()
                        message = evaluate(
                            device, model, step, configs, val_logger, vocoder, len(losses), num_gpus)
                        with open(os.path.join(val_log_path, "log.txt"), "a") as f:
                            f.write(message + "\n")
                        outer_bar.write(message)

                        model.train()

                    if step % save_step == 0:
                        torch.save(
                            {
                                "model": model.module.state_dict() if num_gpus > 1 else model.state_dict(),
                                "optimizer": optimizer._optimizer.state_dict(),
                            },
                            os.path.join(
                                train_config["path"]["ckpt_path"],
                                "{}.pth.tar".format(step),
                            ),
                        )

                if step == total_step:
                    train = False
                    break
                step += 1
                if rank == 0:
                    outer_bar.update(1)

            if rank == 0:
                inner_bar.update(1)
        epoch += 1

if __name__ == "__main__":
    assert torch.cuda.is_available(), "CPU training is not allowed."
    parser = argparse.ArgumentParser()
    parser.add_argument('--use_amp', action='store_true')
    parser.add_argument("--restore_step", type=int, default=0)
    parser.add_argument(
        "--dataset",
        type=str,
        required=True,
        help="name of dataset",
    )
    args = parser.parse_args()

    # Read Config
    preprocess_config, model_config, train_config = get_configs_of(
        args.dataset)
    configs = (preprocess_config, model_config, train_config)

    # Set Device
    torch.manual_seed(train_config["seed"])
    torch.cuda.manual_seed(train_config["seed"])
    num_gpus = torch.cuda.device_count()
    batch_size = int(train_config["optimizer"]["batch_size"] / num_gpus)
    helper_type = train_config["aligner"]["helper_type"]

    # Log Configuration
    print("\n==================================== Training Configuration ====================================")
    print(' ---> Automatic Mixed Precision:', args.use_amp)
    print(' ---> Number of used GPU:', num_gpus)
    print(' ---> Batch size per GPU:', batch_size)
    print(' ---> Batch size in total:', batch_size * num_gpus)
    print(' ---> Type of alignment helper:', helper_type)
    print("=================================================================================================")
    print("Prepare training ...")

    if num_gpus > 1:
        mp.spawn(train, nprocs=num_gpus, args=(
            args, configs, batch_size, num_gpus))
    else:
        train(0, args, configs, batch_size, num_gpus)


import json
import os
import random
import string
import tempfile

from googlecloudsdk.core import config
from googlecloudsdk.core import exceptions
from googlecloudsdk.core import log
from googlecloudsdk.core.docker import constants
from googlecloudsdk.core.docker import docker

MANIFEST_FORMAT = """\
computeMetadata:
  v1: &V1
    project:
      projectId: &PROJECT-ID
        {project_id}
      # TODO(mattmoor): remove gcloud's dependency on this.
      numericProjectId: 1234
    instance:
      attributes: {attributes}
      projectId: *PROJECT-ID
      hostname: test-hostname.kir
      machineType: n1-standard-1
      maintenanceEvent: NONE
      serviceAccounts:
        # Use YAML magic to minimize redundancy
        default: *DEFAULT
        {email}: &DEFAULT
          email: {email}
          scopes: {scopes}
      zone: us-central1-a
"""

class MetadataOptions(object):
  """Options for creating and running the fake metadata service."""

  def __init__(self, account=None, credential=None, project=None,
               attributes=None, scopes=None):
    """Constructor."""
    if not attributes:
      attributes = {}
    if not scopes:
      scopes = config.CLOUDSDK_SCOPES

    self.account = account
    self.credential = credential
    self.project = project
    self.attributes = attributes
    self.scopes = scopes

class FakeMetadata(object):
  """Creates a Fake Metadata instance usable via 'with'."""

  def __init__(self, image, options, suffix=None):
    """Initialize the fake metadata instance."""
    self._image = image
    self._options = options

    if not suffix:
      suffix = ''.join(random.choice(
          string.ascii_uppercase + string.digits) for _ in range(5))
    self.suffix = suffix

  @property
  def name(self):
    """String, identifying a container. Required for linking."""
    return 'metadata-%s' % self.suffix

  @property
  def manifest_file(self):
    """String, path to the manifest file."""
    return os.path.join(
        tempfile.gettempdir(),
        'fake_metadata_{suffix}.yaml'.format(suffix=self.suffix))

  @property
  def image(self):
    """String, identifying a fake-metadata image to be run."""
    return self._image

  def __enter__(self):
    """Creates a fake metadata environment."""
    log.Print('Surfacing credentials via {metadata}...'.format(
        metadata=self.name))

    # Use JSON to inject structured data into the YAML since it
    # is an effective way to create indentation-insensitive YAML
    # NOTE: YAML 1.2 is a superset of JSON.
    with open(self.manifest_file, 'w') as f_out:
      f_out.write(MANIFEST_FORMAT.format(
          attributes=json.dumps(self._options.attributes),
          project_id=self._options.project,
          email=self._options.account,
          scopes=json.dumps(self._options.scopes)))

    # We refresh credentials in case a pull is needed.
    docker.UpdateDockerCredentials(constants.DEFAULT_REGISTRY)
    result = docker.Execute([
        'run', '-d',
        '--name', self.name,
        '-v', self.manifest_file + ':' + self.manifest_file,
        self.image,
        # Arguments to the //cloud/containers/metadata binary,
        # which is the entrypoint:
        '-manifest_file='+self.manifest_file,
        '-refresh_token='+self._options.credential.refresh_token])
    if result != 0:
      raise exceptions.Error('Unable to launch fake-metadata.')
    return self

  # pylint: disable=redefined-builtin
  def __exit__(self, type, value, traceback):
    """Cleans up a fake metadata environment."""
    log.Print('Shutting down metadata credentials')
    result = docker.Execute(['rm', '-f', self.name])
    if result != 0:
      raise exceptions.Error('Unable to tear down fake-metadata.')
    # Clean up the temporary file.
    os.remove(self.manifest_file)


from typing import List

import golem.model

def _repository_from_image_name(image_name: str) -> str:
    return image_name.rsplit('/', maxsplit=1)[0]

class Whitelist:

    @staticmethod
    def get_all() -> List[str]:
        return [
            whitelisted.repository for whitelisted in
            golem.model.DockerWhitelist.select().execute()
        ]

    @classmethod
    def add(cls, image_name: str) -> bool:
        """
        Returns False if the entry was already on the whitelist.
        """
        repository = _repository_from_image_name(image_name)
        if cls.is_whitelisted(repository):
            return False
        golem.model.DockerWhitelist.create(repository=repository)
        return True

    @classmethod
    def remove(cls, image_name: str) -> bool:
        """
        Return False is the entry was not present on the whitelist.
        """
        repository = _repository_from_image_name(image_name)
        if not cls.is_whitelisted(repository):
            return False
        golem.model.DockerWhitelist.delete().where(
            golem.model.DockerWhitelist.repository == repository,
        ).execute()
        return True

    @staticmethod
    def is_whitelisted(image_name: str) -> bool:
        repository = _repository_from_image_name(image_name)
        query = \
            golem.model.DockerWhitelist.select().where(
                golem.model.DockerWhitelist.repository == repository,
            )
        return query.exists()


### Break ###

#Sirve para parar un bucle

cadena = 'Python'

for letra in cadena:

    if letra == 'h':

        print("Se encontró la h")

        break

    print(letra)

#Tambien es util en bucles for

x = 5

while True:
    x -= 1
    print(x)
    if x == 0:
        print("Fin del bucle")
        break

#Si tenemos dos bucles anidados,
#el break rompe el bucle anidado, pero no el exterior.

for i in range(0, 4):
    for j in range(0, 4):
        break
        #Nunca se realiza más de una iteración
    # El break no afecta a este for
    print(i, j)


import numpy as np
import torch
from torch import nn

import torch.nn.functional as F
import torchvision.transforms as T
from torch.utils.data import  DataLoader
import pytorch_lightning as pl
from utils.classifier import PL_model

def prob_heatmap_tensor(img_tensor, patch_classifier,mean_=0.2939,std_=0.2694,
                        batch_size=256,patch_size=224, stride=8, padding = 111):
    '''Sweep image data with a trained model to produce prob heatmaps
    '''
    nb_row = round(float(img_tensor.shape[2])/stride )
    nb_col = round(float(img_tensor.shape[3])/stride )
    nb_row = int(nb_row)
    nb_col = int(nb_col)

    heatmap_list = []
    unfold = torch.nn.Unfold(kernel_size=(patch_size,patch_size), dilation=1, padding= padding, stride=stride)
    for img in img_tensor:
        #img = img.to(device=device)
        img = img.unsqueeze(dim=0)
        img_= unfold(img)
        img_ = img_.permute(0,2,1)
        n = img_.size(0)
        c = img_.size(1)
        img_ = img_.view(c,1,224,224)
        patch_X = img_.expand(-1,3,-1,-1)

        patch_classifier.eval()
        with torch.no_grad():
            patch_X = torch.tensor(patch_X,dtype = torch.float32)
            transform = T.Normalize(mean=[mean_,mean_,mean_],std=[std_,std_,std_])
            patch_X = transform(patch_X.clone())
            loader = DataLoader(patch_X, batch_size)
            preds =[]

            #trainer = pl.Trainer(device=2, accelerator='gpu', strategy='ddp_find_unused_parameters_false',
                                 #log_every_n_steps=10)

            # commence prediction
            #chunk_preds = trainer.predict(
            #    patch_classifier,
            #    loader
            #)

            #chunk_preds = nn.functional.softmax(chunk_preds, dim=1)

            #pred = chunk_preds[:,1:5].sum(axis=1)

            for i in loader:
                #i = i #.to(device)
                chunk_preds = patch_classifier(i)
                chunk_preds = nn.functional.softmax(chunk_preds, dim=1)
                preds.append(chunk_preds)

            pred = torch.vstack(preds)

            pred = pred[:,1:5].sum(axis=1)

            heatmap = pred.reshape((nb_row, nb_col))

            heatmap_list.append(heatmap.unsqueeze(dim=0))

        heatmap_tensor = torch.cat(heatmap_list)

    return heatmap_tensor.cpu().detach()

def makeGaussian(size, fwhm = 3, center=None):
    """ Make a square gaussian kernel.

    size is the length of a side of the square
    fwhm is full-width-half-maximum, which
    can be thought of as an effective radius.
    """

    x = np.arange(0, size, 1, float)
    y = x[:,np.newaxis]

    if center is None:
        x0 = y0 = size // 2
    else:
        x0 = center[0]
        y0 = center[1]

    return np.exp(-4*np.log(2) * ((x-x0)**2 + (y-y0)**2) / fwhm**2)

def warped_imgs(img,heat,res,fwhm):

    img = img.type(torch.float32)
    heat = heat.unsqueeze(dim=1)
    heat = heat.type(torch.float32)
    n = heat.size(0)
    c = heat.size(1)
    h = heat.size(2)
    w = heat.size(3)

    f = heat.reshape(n, c, -1)
    norm = nn.Softmax(dim=2)
    # *3 to obtain an appropriate scale for the input of softmax function.
    scale=8
    f_norm = norm(f * scale)
    x = f_norm.view(n,c,h,w)

    grid_size = 144,112
    padding_size = 28
    global_size = grid_size[0]+2*padding_size,grid_size[1]+2*padding_size

    #We use a gaussian kernel with sigma set to one third of the width of the saliency map
    gaussian_weights = torch.FloatTensor(makeGaussian(2*padding_size+1, fwhm ))
    #filter = nn.Conv2d(1, 1, kernel_size=(2*padding_size+1,2*padding_size+1),bias=False).to(device = device)
    filter = nn.Conv2d(1, 1, kernel_size=(2*padding_size+1,2*padding_size+1),bias=False)
    #customize convolution kernel weights
    filter.weight[0].data[:,:,:] = gaussian_weights

    #P_basis = torch.zeros(2,grid_size[0]+2*padding_size,grid_size[1]+2*padding_size, device = device)
    P_basis = torch.zeros(2,grid_size[0]+2*padding_size,grid_size[1]+2*padding_size)
    for k in range(2):
                for i in range(global_size[0]):
                    for j in range(global_size[1]):
                        P_basis[k,i,j] = k*(i-padding_size)/(grid_size[0]-1.0)+(1.0-k)*(j-padding_size)/(grid_size[1]-1.0)

    x = nn.Upsample(size=(grid_size[0],grid_size[1]), mode='bilinear')(x)

    x = x #.to(device = device)
    #x = x.view(-1,grid_size[0]*grid_size[1])
    #x = nn.Softmax()(x)*7
    #x = x.view(-1,1,grid_size[0],grid_size[1])
    x = nn.ReplicationPad2d(padding_size)(x)
    #x = nn.ZeroPad2d(padding_size)(x)
    #P = torch.autograd.Variable(torch.zeros(1,2,grid_size[0]+2*padding_size,grid_size[1]+2*padding_size).to(device=device) ,requires_grad=False)
    P = torch.autograd.Variable(torch.zeros(1,2,grid_size[0]+2*padding_size,grid_size[1]+2*padding_size),requires_grad=False)
    P[0,:,:,:] = P_basis
    P = P.expand(x.size(0),2,grid_size[0]+2*padding_size,grid_size[1]+2*padding_size)
    x_cat = torch.cat((x,x),1)
    p_filter = filter(x)
    x_mul = torch.mul(P,x_cat).view(-1,1,global_size[0],global_size[1])
    all_filter = filter(x_mul).view(-1,2,grid_size[0],grid_size[1])
    x_filter = all_filter[:,0,:,:].contiguous().view(-1,1,grid_size[0],grid_size[1])
    y_filter = all_filter[:,1,:,:].contiguous().view(-1,1,grid_size[0],grid_size[1])
    x_filter = x_filter/p_filter
    y_filter = y_filter/p_filter

    xgrids = x_filter*2-1
    ygrids = y_filter*2-1
    xgrids = torch.clamp(xgrids,min=-1,max=1)
    ygrids = torch.clamp(ygrids,min=-1,max=1)

    xgrids = xgrids.view(-1,1,grid_size[0],grid_size[1])
    ygrids = ygrids.view(-1,1,grid_size[0],grid_size[1])

    grid = torch.cat((xgrids,ygrids),1)
    grid = nn.Upsample(size=res, mode='bilinear')(grid)
    grid = torch.transpose(grid,1,2)
    grid = torch.transpose(grid,2,3)
    #img = img.to(device=device)
    x_sampled = F.grid_sample(img, grid, align_corners = False)

    #img.detach()

    return x_sampled #.cpu().detach()


import itertools

import dask_image.ndinterp
import pytest
import xarray
from multiscale_spatial_image import MultiscaleSpatialImage
from spatial_image import SpatialImage
from spatialdata._utils import unpad_raster
from spatialdata.models import get_model
from spatialdata.transformations import Affine
from xarray import DataArray

def _pad_raster(data: DataArray, axes: tuple[str, ...]) -> DataArray:
    new_shape = tuple([data.shape[i] * (2 if axes[i] != "c" else 1) for i in range(len(data.shape))])
    x = data.shape[axes.index("x")]
    y = data.shape[axes.index("y")]
    affine = Affine(
        [
            [1, 0, -x / 2.0],
            [0, 1, -y / 2.0],
            [0, 0, 1],
        ],
        input_axes=("x", "y"),
        output_axes=("x", "y"),
    )
    matrix = affine.to_affine_matrix(input_axes=axes, output_axes=axes)
    return dask_image.ndinterp.affine_transform(data, matrix, output_shape=new_shape)

@pytest.mark.ci_only
def test_unpad_raster(images, labels) -> None:
    for raster in itertools.chain(images.images.values(), labels.labels.values()):
        schema = get_model(raster)
        if isinstance(raster, SpatialImage):
            data = raster
        elif isinstance(raster, MultiscaleSpatialImage):
            d = dict(raster["scale0"])
            assert len(d) == 1
            data = d.values().__iter__().__next__()
        else:
            raise ValueError(f"Unknown type: {type(raster)}")
        padded = _pad_raster(data.data, data.dims)
        if isinstance(raster, SpatialImage):
            padded = schema.parse(padded, dims=data.dims, c_coords=data.coords.get("c", None))
        elif isinstance(raster, MultiscaleSpatialImage):
            # some arbitrary scaling factors
            padded = schema.parse(padded, dims=data.dims, scale_factors=[2, 2], c_coords=data.coords.get("c", None))
        else:
            raise ValueError(f"Unknown type: {type(raster)}")
        unpadded = unpad_raster(padded)
        if isinstance(raster, SpatialImage):
            try:
                xarray.testing.assert_equal(raster, unpadded)
            except AssertionError as e:
                raise e
        elif isinstance(raster, MultiscaleSpatialImage):
            d0 = dict(raster["scale0"])
            assert len(d0) == 1
            d1 = dict(unpadded["scale0"])
            assert len(d1) == 1
            try:
                xarray.testing.assert_equal(d0.values().__iter__().__next__(), d1.values().__iter__().__next__())
            except AssertionError as e:
                raise e
        else:
            raise ValueError(f"Unknown type: {type(raster)}")


# Escribir un programa que, utilizando procedimientos con parámetros, lea desde el
# teclado las unidades y el precio que quiere comprar, y en función de las unidades
# introducidas le haga un descuento o no.

max = 3

def descuentos(precio, unidade):
    if unidade >= max:
        desc = precio * unidade * 0.2
        print("se descontaron: ", desc)
    else:
        print("no cumple el monto minimo de unidades.")

precio = int(input("ingrese precio del producto: "))
unidade = int(input("ingrese cantidad de unidades: "))

descuentos(precio, unidade)


from tkinter import *
import tkinter.messagebox as tmsg
import sys
import time
from datetime import datetime,date,timedelta
todays_date=date.today()
dt=datetime.now()
from db import fetchData,insertData,updateBook,returnUpdateBook
from studentdb import insertStudentData,fetchStudentData,updateStudentData,returnStudentBookData,returnSpecifictudentData,specificStudentDatawithDate
root=Tk()
#Creating a Library Management System
root.geometry("3000x700")
root.title("Library Management System")
bookenteridvar=IntVar()
bookenternamevar=StringVar()
bookenterquantityvar=IntVar()
bookid=IntVar()
booktitle=StringVar()
studentId=IntVar()
studentName=StringVar()
address=StringVar()
mobileNo=IntVar()
dateIssued=StringVar()
def changeLabel(statement):
    my_labelinfo.config(text=statement)
    time.sleep(3)
    my_labelinfo.config(text="")
def addBook():
    print(bookenteridvar.get(),bookenternamevar.get(),bookenterquantityvar.get())
    res=insertData(int(bookenteridvar.get()),str(bookenternamevar.get()),int(bookenterquantityvar.get()),0)
    if res==0:
        Label(side_lower,text="Error",font='arial 12 bold',fg='red',bg='lightgreen').grid(row=3,column=1)
    else:
        Label(side_lower,text="Book Insert Successfully",font='arial 12 bold',fg='red',bg='lightgreen').grid(row=3,column=1)
upperFrame=Frame(root,bg='red',borderwidth=7)
upperFrame.pack(padx=0)
def makeElement(title,row,col,runvar):
    Label(inf,text=title,font='arial 14 bold',bg='lightgreen').grid(row=row,column=col,padx=20,pady=3)
    if runvar=="bookid":
        Entry(inf,width=30,textvariable=bookid).grid(row=row,column=col+1,padx=20,pady=2)
    elif runvar=="booktitle":
        Entry(inf,width=30,textvariable=booktitle).grid(row=row,column=col+1,padx=20,pady=2)
    elif runvar=="studentId":
        Entry(inf,width=30,textvariable=studentId).grid(row=row,column=col+1,padx=20,pady=2)
    elif runvar=="studentName":
        Entry(inf,width=30,textvariable=studentName).grid(row=row,column=col+1,padx=20,pady=2)
    elif runvar=="address":
        Entry(inf,width=30,textvariable=address).grid(row=row,column=col+1,padx=20,pady=2)
    elif runvar=="mobileNo":
        Entry(inf,width=30,textvariable=mobileNo).grid(row=row,column=col+1,padx=20,pady=2)
    elif runvar=="dateIssued":
        l=Entry(inf,width=30,textvariable=dateIssued)
        l.insert(1,string=f"{todays_date.day}/{todays_date.month}/{todays_date.year}")
        l.grid(row=row,column=col+1,padx=20,pady=2)

def exitfunc():
    pass
#Issue Book Function is Started
def issueBookfunc():
        print("issue Button is Clicked")
        for bookdp in fetchData():
            if bookdp[0]==bookid.get():
                print("Book is Present")
                if bookdp[2]==bookdp[3]:
                    print("Books are All Issued")
                    changeLabel("Books are All Issued")
                    break

                else:
                    updateBook(bookid.get())
                    for data in fetchStudentData():
                        print("The Value of data is",data)
                        if data[0]==studentId.get():
                            print(data[0])
                            print("Student Id Get equal to enter  Inout Id")

                            updateStudentData(studentId.get(),{"bookid":bookid.get(),"dateOfIssued":dateIssued.get()})
                            break
                    else:
                        print(studentId.get(),studentName.get(),address.get(),mobileNo.get(),{"bookid":bookid.get(),"dateOfIssued":dateIssued.get()})
                        get_id_books=returnSpecifictudentData[4]
                        for key,value in get_id_books.items():
                            if key==bookid.get():
                                changeLabel("Book is Already Issued By Student")
                                break
                        else:
                            insertStudentData(studentId.get(),studentName.get(),address.get(),mobileNo.get(),str([{"bookid":bookid.get(),"dateOfIssued":dateIssued.get()}]))
                            my_labelinfo.config(text="Congrauluations  Book Issued SuccessFully")
                            time.sleep(1)
                            my_labelinfo.config(text="")
                            tmsg.showinfo("Notice","Congrauluations  Book Issued SuccessFully")

            break

        else:
            my_labelinfo.config(text="Sorry Unable To Find Book With Respective Book Id")
            time.sleep(1)
            my_labelinfo.config(text="")
            print("Sorry Unable To Find Book With Respective Book Id")
#Issue Book Function Is Closed
def returnBook():
    for bookdp in fetchData():
        if bookdp[0]==bookid.get():
            print("Book is Present")
            if bookdp[2]==0:
                print("All Books Are Present")
                break

            else:
                for data in fetchStudentData():
                    print("The Value of data is",data)
                    if data[0]==studentId.get():
                        print(data[0])
                        print("Student Id Get equal to enter  Input Id")
                        returnStudentBookData(studentId.get(),{"bookid":bookid.get(),"dateOfIssued":dateIssued.get()})
                        returnUpdateBook(bookid.get())
                        break
                else:
                    print("Unable To Fetch The Student")
                    changeLabel("Unable to Fetch The Student")
                    break
            break

    else:
        changeLabel("Sorry Unable To Find Book With Respective Book Id")
        print("")
def knowStudent():
    print("Know Student Function is Running")
    print("****************",studentId.get())
    mydata=returnSpecifictudentData(studentId.get())
    lbx_student_details.insert(END,f'Student ID:{mydata[0]}')
    lbx_student_details.insert(END,f'Student Name:{mydata[1]}')
    lbx_student_details.insert(END,f"Address:{mydata[2]}")
    lbx_student_details.insert(END,f"Phone No.{mydata[3]}")
    print("********************************************",mydata)
    if len(mydata)!=4:
        myall=specificStudentDatawithDate(studentId.get())
        i=0
        k=4
        colorlist=['red','green','yellow','lightgreen']
        lbx_student_details.insert(END,"-----------------------------------------------------------------------")
        for key,value in mydata[4].items():
            lbx_student_details.insert(END,f"Id :{key}")
            lbx_student_details.insert(END,f"Book Name:{value}:")
            lbx_student_details.insert(END,f"Date Of Issued:{myall[i]}")
            new=datetime.strptime(myall[i],'%d/%m/%Y')
            getOverDueDate=new+ timedelta(days=30)
            lbx_student_details.insert(END,Label(text="Hello",fg='red').pack())
            lbx_student_details.insert(END,f"Before Date:{getOverDueDate.day}/{getOverDueDate.month}/{getOverDueDate.year}")
            lbx_student_details.insert(END,"-----------------------------------------------------------------------")
            i+=1
    pass
Label(upperFrame,text="Book Management System",font=("arial",55,'bold')).pack()
middle=Frame(root,borderwidth=8)
middle.pack(anchor='center')
inf=Frame(middle,highlightbackground='red',highlightcolor="red", highlightthickness=2,bg='lightgreen')
inf.pack(side='left',anchor='w')
book_details=Frame(middle,highlightbackground='red',highlightcolor="red", highlightthickness=2)
book_details.pack(side='right')
Label(book_details,text="Book Details",font='arial 13 bold',fg='white',bg='lightgreen').pack()
lbx=Listbox(book_details,font="arial 12 bold",width=35,height=14)
lbx.pack(side='left')

lbx_student_details=Listbox(book_details,font="arial 12 bold",width=45,height=14)
lbx_student_details.pack()
for row in fetchData():
    quantity=row[2]
    issued=row[3]
    if quantity-issued>0:
        lbx.insert(ACTIVE,row[1])
my_buttons=Frame(root,borderwidth=2)
my_buttons.pack(anchor='n')
Button(my_buttons,text="Issue Book",fg='white',bg='lightgreen',height=1,width=15,font='arial 13 bold',highlightbackground='red',highlightcolor="red", highlightthickness=2,command=issueBookfunc).pack(side='left',padx=25)
Button(my_buttons,text="Return Book",fg='white',bg='lightgreen',height=1,width=15,font='arial 13 bold',highlightbackground='red',highlightcolor="red", highlightthickness=2,command=returnBook).pack(side='left',padx=25)
Button(my_buttons,text="Know Student",fg='white',bg='lightgreen',height=1,width=15,font='arial 13 bold',highlightbackground='red',highlightcolor="red", highlightthickness=2,command=knowStudent).pack(side='left',padx=25)
Button(my_buttons,text="Exit",fg='white',bg='lightgreen',height=1,width=15,font='arial 13 bold',highlightbackground='red',highlightcolor="red", highlightthickness=2,command='exitfunc').pack(side='left',padx=25)
lower_part=Frame(root,highlightbackground='green',highlightcolor="green", highlightthickness=2)
lower_part.pack()
side_lower=Frame(lower_part,highlightbackground='green',highlightcolor="green", highlightthickness=2,bg='lightgreen')
side_lower.pack(side='left')

Label(side_lower,text="BookId",font='arial 16 bold',fg='white',bg='lightgreen').grid(row=0,column=0)
Entry(side_lower,textvariable=bookenteridvar).grid(row=0,column=1)
Label(side_lower,text="Book Name",font='arial 16 bold',fg='white',bg='lightgreen').grid(row=1,column=0)
Entry(side_lower,textvariable=bookenternamevar).grid(row=1,column=1)
Label(side_lower,text="Quantity",font='arial 16 bold',fg='white',bg='lightgreen').grid(row=2,column=0)
Entry(side_lower,textvariable=bookenterquantityvar).grid(row=2,column=1)
Label(side_lower,text="",font='arial 12 bold',fg='red',bg='lightgreen').grid(row=3,column=1)
Button(side_lower,text="Add Book",fg='lightgreen',bg='white',height=1,width=15,font='arial 13 bold',highlightbackground='red',highlightcolor="red", highlightthickness=2,command=addBook).grid(row=4,column=1)

#Making Elements in Information Section
makeElement("Member Type:",0,0,"Student")
makeElement("Book Id:",0,2,"bookid")
makeElement("Book Title:",1,0,"booktitle")
#2nd Row
makeElement("ID No.:",1,2,"studentId")
makeElement("Student Name:",2,0,'studentName')
makeElement("Date Borrowed:",2,2,"dateIssued")
makeElement("Date Due.:",3,0,"nOne")
makeElement("Address 1:",3,2,"address")
makeElement("Days on Book:",4,0,"days")
my_labelinfo=Label(inf,text="",fg='red',font='arial 13 bold',bg='lightgreen')
my_labelinfo.grid(row=6,column=2)

getoverduelabel=Label(inf,text="Date Over Due",bg='lightgreen',font='arial 12 bold')
getoverduelabel.grid(row=4,column=1,padx=20,pady=2)
makeElement("Mobile No.:",5,0,"mobileNo")
root.mainloop()