# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
import os

# 这里填写你的 OSS_ACCESS_KEY_ID 和 OSS_ACCESS_KEY_SECRET
os.environ['OSS_ACCESS_KEY_ID'] = ''
os.environ['OSS_ACCESS_KEY_SECRET'] = ''

auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# 这里改成你的
bucket = oss2.Bucket(auth, 'https://oss-cn-chengdu.aliyuncs.com', 'sourcedream-cloud')
# 填写Object完整路径，完整路径中不包含Bucket名称，例如testfolder/exampleobject.txt。
#
# bucket.get_object_to_file('testfolder/exampleobject.txt', 'D:\\localpath\\examplefile.txt')

for obj in oss2.ObjectIterator(bucket):
    # 下面都是在判断文件是否存在 不存在就新建
    dirStr = str(obj.key)
    last_slash_index = dirStr.rfind('/')
    result = dirStr[:last_slash_index]
    if not os.path.exists(result):
        os.makedirs(result)
    # 下载Object到本地文件，并保存到指定的本地路径D:\\localpath\\examplefile.txt。如果指定的本地文件存在会覆盖，不存在则新建。
    # 这个东西必须要文件存在才可以下载
    bucket.get_object_to_file(obj.key, f'{obj.key}')


import torch
from torch import nn
from spdnet.spd import Normalize

class GBMS_RNN(nn.Module):
    def __init__(self, bandwidth=0.1, normalize=True):
        super(GBMS_RNN, self).__init__()
        self.bandwidth = nn.Parameter(torch.tensor(bandwidth))
        self.normalize = None
        if normalize:
            self.normalize = Normalize()

    def forward(self, X):
        bandwidth = self.bandwidth
        if self.normalize:
            W = torch.exp((X @ X.transpose(-2, -1) - 1) / (bandwidth * bandwidth))
        else:
            pair_dis = torch.cdist(X, X)
            pair_dis_square = pair_dis**2
            W = torch.exp(-0.5 * pair_dis_square / (bandwidth * bandwidth))
        D = W.sum(dim=-1).diag_embed()
        D_inv = D.inverse()
        X = (X.transpose(-2, -1) @ W @ D_inv).transpose(-2, -1)
        if self.normalize:
            X = self.normalize(X)
        output = X
        return output

def cosine_similarity(input):
    output = input @ input.transpose(-2, -1) * 0.5 + 0.5
    return output

def similarity_loss(input, targets, alpha=0):
    similarity = cosine_similarity(input)
    identity_matrix = targets.unsqueeze(-2) == targets.unsqueeze(-2).transpose(-2, -1)
    loss = (1 - similarity) * identity_matrix + torch.clamp(
        similarity - alpha, min=0
    ) * (~identity_matrix)
    loss = torch.mean(loss)
    return loss


"""
Problem 20: Factorial digit sum
https://projecteuler.net/problem=20

n! means n × (n − 1) × ... × 3 × 2 × 1

For example, 10! = 10 × 9 × ... × 3 × 2 × 1 = 3628800,
and the sum of the digits in the number 10! is 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27.

Find the sum of the digits in the number 100!
"""

def test_get_sum_of_digits():
    # arrange
    from src.p020_factorial_digit_sum import get_sum_of_digits

    # act
    actual_result = get_sum_of_digits('3628800')

    # assert
    expected_result = 27
    assert actual_result == expected_result


import pygame
from settings import BOSSTELEPORTINGSOUND, ENEMYHITSOUND, importFolder, bossPositions
from random import randint
from os import path

class Boss(pygame.sprite.Sprite):
    def __init__(self, pos, surface, level):
        super().__init__()
        #animation
        self.displaySurface = surface
        self.frameIndex = 0
        self.animationSpeed = 0.15
        self.status = 'idle'
        self.importCharacterAssets()
        self.image = self.animations['idle'][self.frameIndex]
        self.rect = self.image.get_rect(center = pos)
        self.hitbox = pygame.Rect((0,0), (40, 50))

        self.canTakeAction = False
        self.spawnTime = pygame.time.get_ticks()
        self.level = level
        self.defeated = False
        #stats
        self.maxHp = 50
        self.hp = self.maxHp
        self.specialDamage = 3

        #status-gameplay
        self.facingRight = False
        self.alive = True
        self.hasIFrames = False
        self.iFramesCD = 500
        self.hitTime = 0
        self.hit = False
        self.location = 2

        #bossmagic
        self.specialAttackHitboxes = pygame.sprite.Group()
        self.canSpecialAttack = True
        self.specialAttack = False
        self.specialAttackDuration = 600
        self.specialAttackCD = 5000
        self.specialAttackTime = 0

        #bossTeleport
        self.teleporting = False
        self.canTeleport = False
        self.teleportTime = 0
        self.teleportDuration = 500
        self.teleportCD = 5000

    def importCharacterAssets(self):
        characterPath = path.join('Assets','enemies','boss')
        self.animations = {'idle':[],'attack':[],'death':[],'idle':[],'skill':[],'summon':[]}

        for animation in self.animations.keys():
            fullPath = path.join(characterPath,animation)
            self.animations[animation] = importFolder(fullPath)

    def animate(self):
        animation = self.animations[self.status]
        #loop over frame index
        self.frameIndex += self.animationSpeed
        if self.frameIndex >= len(animation):
            if not self.alive:
                self.defeated = True
                return
            self.frameIndex = 0

        image = animation[int(self.frameIndex)]
        if self.facingRight:
            self.image = image
        else:
            flippedImage = pygame.transform.flip(image, True, False)
            self.image = flippedImage

        #set the rect
        self.hitbox.center = self.rect.center

    def cooldowns(self):
        self.hit = False
        currentTime = pygame.time.get_ticks()

        if self.specialAttack:
            self.canSpecialAttack = False
            if currentTime - self.specialAttackTime >= self.specialAttackDuration:
                self.specialAttack = False

        if not self.canSpecialAttack:
            if currentTime - self.specialAttackTime >= self.specialAttackCD:
                self.canSpecialAttack = True

        if self.teleporting:
            self.canTeleport = False
            if currentTime - self.teleportTime >= self.teleportDuration:
                self.teleporting = False

        if not self.canTeleport:
            if currentTime - self.teleportTime >= self.teleportCD:
                self.canTeleport = True

        if self.hasIFrames:
            self.hit = False
            if currentTime - self.hitTime >= self.iFramesCD:
                self.hasIFrames = False

        if not self.canTakeAction:
            if currentTime - self.spawnTime >= 1000:
                self.canTakeAction = True

    def getStatus(self):
        if not self.alive:
            self.status = 'death'
        elif self.teleporting:
            self.status = 'skill'
        elif self.specialAttack:
            self.status = 'summon'
        else:
            self.status = 'idle'

    def createSpecialAttackHitbox(self):
        self.specialAttack = True
        self.specialAttackTime = pygame.time.get_ticks()
        summon1 = BossSummon((160, 176), self.level.player.sprite.hitbox.center)
        summon2 = BossSummon((160, 304), self.level.player.sprite.hitbox.center)
        summon3 = BossSummon((656, 176), self.level.player.sprite.hitbox.center)
        summon4 = BossSummon((656, 304), self.level.player.sprite.hitbox.center)
        self.specialAttackHitboxes.add(summon1)
        self.specialAttackHitboxes.add(summon2)
        self.specialAttackHitboxes.add(summon3)
        self.specialAttackHitboxes.add(summon4)

    def loseHP(self, damage):
        if not self.hasIFrames and self.alive:
            self.hit = True
            self.hasIFrames = True
            self.hitTime = pygame.time.get_ticks()
            self.hp -= damage
            ENEMYHITSOUND.play(0)
            if self.hp <= 0:
                self.alive = False

    def changePosition(self):
        if self.canTeleport:
            BOSSTELEPORTINGSOUND.play(0)
            self.teleportTime = pygame.time.get_ticks()
            self.teleporting = True
            newPosIndex = randint(0,4)
            if self.location == bossPositions[newPosIndex]:
                if newPosIndex == 4:
                    newPosIndex = 0
                else:
                    newPosIndex += 1
            if newPosIndex in (0,3,2):
                self.facingRight = True
            else:
                self.facingRight = False
            self.rect.center = bossPositions[newPosIndex]

    def drawing(self, scrolling):
        x = int(self.rect.x - scrolling.x)
        y = int(self.rect.y - scrolling.y)
        self.displaySurface.blit(self.image, (x, y))

    def update(self):
        if not self.defeated:
            self.getStatus()
            self.animate()
            self.cooldowns()
            if self.canTakeAction:
                self.changePosition()
                if self.canSpecialAttack:
                    self.createSpecialAttackHitbox()

class BossSummon(pygame.sprite.Sprite):
    def __init__(self, spawnPosition, target):
        super().__init__()
        self.frameIndex = 0
        self.animationSpeed = 0.15
        self.status = 'idle'
        self.importSpellAssets()
        self.image = self.animations['idle'][self.frameIndex]
        self.rect = self.image.get_rect(center = spawnPosition)
        self.hitbox = pygame.Rect(0, 0, 11, 23)
        self.target = target
        self.spawnPosition = spawnPosition
        self.spawnTime = pygame.time.get_ticks()
        self.startMove = 1000
        self.endLife = 5000
        self.speed = 4
        if self.target[0] - spawnPosition[0] > 0:
            self.goingRight = False
        else:
            self.goingRight = True

    def importSpellAssets(self):
        characterPath = path.join('Assets','enemies','bossSummon')
        self.animations = {'idle':[],'moving':[]}

        for animation in self.animations.keys():
            fullPath = path.join(characterPath,animation)
            self.animations[animation] = importFolder(fullPath)

    def animate(self):
        animation = self.animations[self.status]
        #loop over frame index
        self.frameIndex += self.animationSpeed
        if self.frameIndex >= len(animation):
            self.frameIndex = 0

        image = animation[int(self.frameIndex)]
        if self.goingRight:
            self.image = image
        else:
            flippedImage = pygame.transform.flip(image, True, False)
            self.image = flippedImage

        self.hitbox.center = self.rect.center

    def moveTowardTarget(self):
        projectileVector = pygame.math.Vector2(self.spawnPosition)
        targetVector = pygame.math.Vector2(self.target)
        towards = (targetVector - projectileVector).normalize() * self.speed
        self.rect.x += towards.x
        self.rect.y += towards.y

    def drawing(self, surface, scrolling):
        x = int(self.rect.x - scrolling.x)
        y = int(self.rect.y - scrolling.y)
        surface.blit(self.image, (x, y))

    def update(self):
        self.animate()
        currentTime = pygame.time.get_ticks()
        if currentTime - self.spawnTime >= self.startMove:
            self.status = 'moving'
            self.moveTowardTarget()
        elif currentTime - self.spawnTime >= self.endLife:
            self.kill()


import logging
from math import sqrt
from typing import Optional

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
import torch
from tqdm import trange

from ..common import HistoricalData, get_device
from ..exceptions import SimulationException
from . import Simulations

logger = logging.getLogger("pyfmc.simulations.gbm")

class Trajectory:
    def __init__(self, dist: torch.Tensor, label: str = "Trajectory") -> None:
        self.dist = dist.numpy()
        self.label = label

    def value(self):
        return self.dist

    def plot(self, title=None, xlabel=None, ylabel=None):
        fig, ax = plt.subplots()
        sns.lineplot(data=self.dist, legend=False)
        ax.set_xlabel(xlabel or "time")
        ax.set_ylabel(ylabel or self.label)
        ax.set_title(title or self.label)
        return fig, ax

class Distribution:
    def __init__(self, dist: torch.Tensor, label: str = "Distribution"):
        self.dist = dist.numpy()
        self.label = label

    def value(self):
        return self.dist

    def plot(self, bins=10, kde=False, title=None, xlabel=None, ylabel=None):
        fig, ax = plt.subplots()
        if kde:
            sns.kdeplot(data=self.dist, color="blue", fill=True, ax=ax)
        else:
            sns.histplot(self.dist, bins=bins, ax=ax)
        ax.set_xlabel(xlabel or self.label)
        ax.set_ylabel(ylabel or ("Density" if kde else "Counts"))
        ax.set_title(title or self.label)
        return fig, ax

    def __str__(self) -> str:
        return str(self.dist)

class GBMResult:
    def __init__(
        self, init_dist: torch.Tensor, final_dist: torch.Tensor, trajectories: Optional[torch.Tensor] = None
    ) -> None:
        self.init_dist = init_dist.cpu()
        self.final_dist = final_dist.cpu()
        self._trajectories = trajectories.cpu() if trajectories is not None else trajectories

    def price_distribution(self):
        return Distribution(self.final_dist, label="Price Distribution")

    def trajectories(self):
        if self._trajectories is None:
            logger.warning("No trajectories")
            return
        return Trajectory(self._trajectories)

    def return_distribution(self):
        if self.final_dist.size() != self.init_dist.size():
            logger.warning("Size mismatch due to MPS mode, fixing ...")
            init_dist = self.init_dist[: self.final_dist.size(0)]
        else:
            init_dist = self.init_dist
        return Distribution((self.final_dist - init_dist) / init_dist, label="Return Distribution")

    def VaR(self, alpha: float):
        return np.percentile(self.return_distribution().value(), alpha)

class GBM(Simulations):
    def __init__(
        self,
        df: pd.DataFrame,
        n_walkers: int,
        n_steps: int,
        n_trajectories: int = 0,
        step_size: float = 1,
        open_index: str = "Open",
        close_index: str = "Close",
        device_acc: bool = False,
    ) -> None:
        super().__init__(n_walkers, n_steps, device_acc)
        self.df = df
        self.step_size = step_size
        self.open_index = open_index
        self.close_index = close_index
        self.n_trajectories = n_trajectories
        if (open_index and close_index) not in df.columns:
            raise SimulationException("Wrong open_index or close_index")

    def simulate(self):
        hist_data = HistoricalData(self.df, self.open_index, self.close_index)
        device = get_device() if self.device_acc else torch.device("cpu")
        logger.info("Using %s for calculation ...", device)
        dtype = torch.float32 if device == torch.device("mps") else torch.float64
        logger.info("Using device: %s", device)

        exp_return = torch.tensor(hist_data.return_mean, device=device, dtype=dtype)
        std_return = torch.tensor(hist_data.return_std, device=device, dtype=dtype)
        last_price = hist_data.get_latest_close_price()

        s0 = torch.tensor([last_price] * self.n_walkers, device=device, dtype=dtype)
        init_dist = torch.clone(s0)
        trajectories = init_dist[: self.n_trajectories] if self.n_trajectories > 0 else None

        s1 = torch.zeros(self.n_walkers, device=device, dtype=dtype)
        ds = torch.zeros(self.n_walkers, device=device, dtype=dtype)
        dt = torch.tensor(self.step_size)

        for _ in trange(self.n_steps):
            epsilon = torch.randn(self.n_walkers, device=device, dtype=dtype)
            shock = (std_return * sqrt(dt)) * epsilon
            drift = dt * exp_return
            ds = (shock + drift) * s0
            s1 = s0 + ds
            s0 = torch.clone(s1)
            if self.n_trajectories > 0:
                trajectories = torch.concat((trajectories, s0[: self.n_trajectories]))

        s0 = s0[torch.isfinite(s0)]
        return GBMResult(
            init_dist,
            s0,
            trajectories.reshape([self.n_steps + 1, self.n_trajectories]) if self.n_trajectories > 0 else None,
        )


import random
from random import seed

seed(1)

import time

def random_list_generator(N, NMAX):
    lst=[]

    for i in range(N):
        lst.append(random.randint(0,NMAX))

    return lst

def reverse_sorted_list_generator(N,NMAX):
    lst=[]
    i=random.randint(N,NMAX)
    j=N-1

    while j>=0:
        lst.append(i)
        i-=1
        j-=1

    return lst

def sorted_list_generator(N,NMAX):

    lst=[]

    i=random.randint(0,NMAX-N)
    j=i+N-1

    while i<=j:
        lst.append(i)
        i+=1

    return lst

def almost_Sorted_generator(N,NMAX):
    lst=[]
    c=0

    for i in range(N):
        if i%5!=0:
            lst.append(c)
            c+=1
        else:
            lst.append(random.randint(0,NMAX))

    return lst

def almost_Reverse_Sorted_generator(N, NMAX):
    lst = []
    i = c =  NMAX

    while i > NMAX - N:
        if i%5==0:
            lst.append(random.randint(0,NMAX))
        else:
            lst.append(c)
            c-=1
        i -= 1

    return lst

def count_sort(L):
    freq=[]

    val_max=max(L)

    for i in range(val_max+1):
        freq.append(0)

    for x in L:
        freq[x]+=1

    SORTED=[]

    for i in range(val_max+1):
       while freq[i]!=0:
            SORTED.append(i)
            freq[i]-=1

    return SORTED

def bubble_sort(L):

    n=len(L)-1
    ok=0
    j=n

    while ok==0:
        ok=1
        for i in range(0,j):

            if L[i]>L[i+1]:
                aux=L[i]
                L[i]=L[i+1]
                L[i+1]=aux

            ok=0
        j-=1
    return L

def insertionSort(L):

    lg=len(L)

    for i in range(1, lg):

        key = L[i]

        j = i - 1
        while j >= 0 and key < L[j]:
            L[j + 1] = L[j]
            j -= 1
        L[j + 1] = key

    return L

def interclasare(A, B):
    a = len(A)
    b = len(B)
    i = 0
    j = 0
    C = []
    while i < a and j < b:
        if A[i] > B[j]:
            C.append(B[j])
            j += 1
        else:
            C.append(A[i])
            i += 1

    for k in range(i, len(A)):
        C.append(A[k])
    for k in range(j, len(B)):
        C.append(B[k])

    return C

def merge_sort(V, st, dr):

    mid = (st + dr) // 2

    if st == dr:
        return [V[mid]]

    if dr-st<=10:
        return insertionSort(V[st:dr+1])

    return interclasare(merge_sort(V, st, mid), merge_sort(V, mid + 1, dr))

def quick_sort(L):
    if L == []:
        return []

    if len(L) < 11:
        return insertionSort(L)

    k = random.randint(0, len(L) - 1)

    mai_mici = [x for x in L if x < L[k]]
    egale = [x for x in L if x == L[k]]
    mai_mari = [x for x in L if x > L[k]]

    return quick_sort(mai_mici) + egale + quick_sort(mai_mari)

def BFPRT(A):
        if len(A) <= 5:
            return sorted(A)[len(A) // 2]

        grupuri = [sorted(A[i:i + 5]) for i in range(0, len(A), 5)]

        mediane = [grup[len(grup) // 2] for grup in grupuri]

        return BFPRT(mediane)

def quick_sort_BFPRT(L):
        if L == []:
            return []

        if len(L) < 11:
            return insertionSort(L)

        bfprt = BFPRT(L)

        mai_mici = [x for x in L if x < bfprt]
        egale = [x for x in L if x == bfprt]
        mai_mari = [x for x in L if x > bfprt]

        return quick_sort(mai_mici) + egale + quick_sort(mai_mari)

def countsort(L,exp):
    freq=[]

    for i in range(10):
        freq.append([])

    for number in L:
        freq[(number//exp)%10].append(number)

    L=[]

    for i in range(10):
        L+=freq[i]

    return L

def radix_sort(L):

    nrcif_max=len(str(max([number for number in L])))
    i=1
    exp=1

    while i<=nrcif_max:
        L=countsort(L,exp)
        exp*=10
        i+=1

    return L

def log_2(x):
    c=0

    while x!=1:
        x//=2
        c+=1
    return c

def count_sort_2(L,exp):
    freq=[]

    for i in range(2):
        freq.append([])

    for number in L:
        freq[(number>>exp)%2].append(number)

    L=[]

    for i in range(2):
        L+=freq[i]

    return L

def radix_sort_2(L):

    log2=log_2(max(L))

    exp=0

    while exp<=log2+1:
        L=count_sort_2(L,exp)
        exp+=1

    return L

def log_4(x):
    c=0

    while x!=1:
        x//=2
        c+=1
    return c

def count_sort_4(L,exp):
    freq=[]

    for i in range(4):
        freq.append([])

    for number in L:
        freq[(number>>(2*exp))%4].append(number)

    L=[]

    for i in range(4):
        L+=freq[i]

    return L

def radix_sort_4(L):

    log4=log_4(max(L))

    exp=0

    while exp<=log4:
        L=count_sort_4(L,exp)
        exp+=1

    return L

def este_sortat(L):
    for i in range(len(L)-1):
        if L[i]>L[i+1]:
            return "Nu a sortat bine"

    return "A sortat bine"

fisier=open("teste.in")

T=int(fisier.readline())

while T:
    lista=fisier.readline().strip("\n").split()

    N=int(lista[0])

    NMAX=int(lista[1])

    tip=lista[2]

    T-=1

    de_sortat=[]

    if tip=="sorted":
        de_sortat=sorted_list_generator(N,NMAX)
    else:
        if tip=="reverseSorted":
            de_sortat=reverse_sorted_list_generator(N,NMAX)
        else:
            if tip=="random":
                de_sortat=random_list_generator(N,NMAX)
            else:
                if tip=="almostSorted":
                    de_sortat=almost_Sorted_generator(N,NMAX)
                else:
                    if tip=="almostReverseSorted":
                        de_sortat=almost_Reverse_Sorted_generator(N,NMAX)

    print("\t\t", "N=",N,"  NMAX=",NMAX," ", "  caz:", tip, sep="")
    print()

    de_sortat_sorted = de_sortat.copy()
    test_sorted = de_sortat.copy()

    start = time.time()

    sorted(de_sortat_sorted)

    print("Timpul de executie pentru sorted din Python este de ", time.time() - start, " secunde.", sep="")
    print(este_sortat(sorted(test_sorted)), ".", sep="")
    print()

    de_sortat_count = de_sortat.copy()
    test_count = de_sortat.copy()

    start = time.time()

    count_sort(de_sortat_count)

    print("Timpul de executie pentru count sort este de ", time.time() - start, " secunde.", sep="")
    print(este_sortat(count_sort(test_count)), ".", sep="")
    print()

    if N<100000:

        de_sortat_bubble = de_sortat.copy()
        test_bubble = de_sortat.copy()

        start = time.time()

        bubble_sort(de_sortat_bubble)

        print("Timpul de executie pentru bubble sort este de ", time.time() - start, " secunde.", sep="")
        print(este_sortat(bubble_sort(test_bubble)), ".", sep="")
        print()
    else:
        print("Bubble sort nu poate sorta.")
        print()

    de_sortat_merge=de_sortat.copy()
    test_merge=de_sortat.copy()

    start=time.time()

    merge_sort(de_sortat_merge,0,len(de_sortat_merge)-1)

    print("Timpul de executie pentru merge sort este de ", time.time()-start, " secunde.", sep="" )
    print(este_sortat(merge_sort(de_sortat_merge,0,len(de_sortat_merge)-1)), ".", sep="")
    print()

    de_sortat_quick=de_sortat.copy()
    test_quick=de_sortat.copy()

    start=time.time()

    quick_sort(de_sortat_quick)

    print("Timpul de executie pentru quick sort este de ", time.time()-start, " secunde.", sep="")
    print( este_sortat(quick_sort(test_quick)), ".", sep="")
    print()

    de_sortat_bfprt=de_sortat.copy()
    test_bfprt=de_sortat.copy()

    start=time.time()

    quick_sort_BFPRT(de_sortat_bfprt)

    print("Timpul de executie pentru quick sort (BFPRT) este de ", time.time()-start, " secunde.",  sep="")
    print( este_sortat(quick_sort_BFPRT(test_bfprt)), ".", sep="")
    print()

    de_sortat_radix=de_sortat.copy()
    test_radix=de_sortat.copy()

    start=time.time()

    radix_sort(de_sortat_radix)

    print("Timpul de executie pentru radix sort cu baza 10 este de ", time.time()-start, " secunde.", sep="")
    print( este_sortat(radix_sort(test_radix)), ".", sep="")
    print()

    de_sortat_radix2=de_sortat.copy()
    test_radix2=de_sortat.copy()

    start=time.time()

    radix_sort_2(de_sortat_radix2)

    print("Timpul de executie pentru radix sort cu baza 2 este de ", time.time()-start, " secunde.", sep="")
    print( este_sortat(radix_sort_2(test_radix2)), ".", sep="")
    print()

    de_sortat_radix4 = de_sortat.copy()
    test_radix4 = de_sortat.copy()

    start = time.time()

    radix_sort_4(de_sortat_radix4)

    print("Timpul de executie pentru radix sort cu baza 4 este de ", time.time() - start, " secunde.", sep="")
    print(este_sortat(radix_sort_4(test_radix4)), ".", sep="")
    print()

    print("\n\n\n\n\n")


"""

Test the OOD DiscDist2 scorer. It disentangle the feature into discriminative space and the residual space

"""
import pdb
import numpy as np
import matplotlib.pyplot as plt
import os
import argparse
import torch
from tqdm import tqdm
import torch.backends.cudnn as cudnn

from ood_scores.get_scorers import get_scorer
from utils.argparser import OODArgs
from dataset.dataloaders import get_loaders_for_ood
from models.get_models import get_model
from utils.metrics import get_measures
from utils.utils import print_measures, load_features, get_feat_dims

np.random.seed(10)

# ==================== Prepare
# args
argparser = OODArgs()
args = argparser.get_args()

print(args)

# scorer
scorer = get_scorer(args.score, args)

# dataloaders
id_train_loader, id_test_loader, ood_loaders = get_loaders_for_ood(args)

# feature dims
net = get_model(arch=args.arch, args=args, load_file=args.load_file, strict=True)
net.eval()
if args.ngpu > 1:
    net = torch.nn.DataParallel(net, device_ids=list(range(args.ngpu)))
elif args.ngpu > 0:
    net.cuda()
    # torch.cuda.manual_seed(1)
device = "cuda" if torch.cuda.is_available() else "cpu"
cudnn.benchmark = True  # fire on all cylinders

embed_mode = "supcon" in args.arch or "clip" in args.arch
proj_dim, featdims = get_feat_dims(args, net, embed_mode=embed_mode)
last_start_idx = featdims[:-1].sum()    #<- For getting the last feature only

# ==================== Load id_train features and prepare the scorer
# Load id-train feature and append
id_train_feat, id_train_logit, id_train_label = load_features(args, id=True, split="train", last_idx=last_start_idx, \
    featdim=featdims[-1], projdim=proj_dim, feat_space=args.feat_space)
scorer.append_features(id_train_feat, id_train_label)
print(f"The ID data number: {scorer.N}; Feature dim: {scorer.D}; Class number: {scorer.num_class}")
scorer.fit()
print("Scorer fitting done.")

# ==================== Load id test features and cal ood score
print("Calculating the in distribution OOD scores...")
id_test_feat, id_test_logit, id_test_label = load_features(args, id=True, split="test", last_idx=last_start_idx, \
    featdim=featdims[-1], projdim=proj_dim, feat_space=args.feat_space)
if args.run_together:
    id_scores = scorer.cal_score(id_test_feat, return_all=True)
else:
    N = id_test_feat.shape[0]
    id_scores = []
    id_scores_disc = []
    id_scores_residual = []
    for i in tqdm(range(N)):
        id_score_this, id_score_disc_this, id_score_residual_this = scorer.cal_score(id_test_feat[i, :], return_all=True)
        id_scores.append(id_score_this)
        id_scores_disc.append(id_score_disc_this)
        id_scores_residual.append(id_score_residual_this)
    id_scores = np.array(id_scores)
    id_scores_disc = np.array(id_scores_disc)
    id_scores_residual = np.array(id_scores_residual)

# ==================== Load ood test features, cal ood score, and evaluate ood_performance
aurocs, fprs = [], []
aurocs_disc, fprs_disc = [], []
aurocs_residual, fprs_residual = [], []
ood_names = [ood_loader.dataset.name for ood_loader in ood_loaders]
for ood_name in ood_names:
    print(f"\n\n{ood_name} OOD Detection")

    # load feature
    ood_feat, ood_logit = load_features(args, id=False, ood_name=ood_name, last_idx=last_start_idx, \
        featdim=featdims[-1], projdim=proj_dim, feat_space=args.feat_space)

    # calculate ood_scores
    if args.run_together:
        ood_scores = scorer.cal_score(ood_feat, return_all=True)
    else:
        N = ood_feat.shape[0]
        ood_scores = []
        ood_scores_disc = []
        ood_scores_residual = []
        for i in tqdm(range(N)):
            ood_score_this, ood_score_disc_this, ood_score_residual_this = scorer.cal_score(ood_feat[i, :], return_all=True)
            ood_scores.append(ood_score_this)
            ood_scores_disc.append(ood_score_disc_this)
            ood_scores_residual.append(ood_score_residual_this)
        ood_scores = np.array(ood_scores)
        ood_scores_disc = np.array(ood_scores_disc)
        ood_scores_residual = np.array(ood_scores_residual)

    # evaluate - Use all the OOD samples
    for id_s, ood_s, name, aurocs_bin, fprs_bin in zip(
        [id_scores_disc, id_scores_residual, id_scores],
        [ood_scores_disc, ood_scores_residual, ood_scores],
        ["DiscSpace", "ResidualSpace", "Together"],
        [aurocs_disc, aurocs_residual, aurocs],
        [fprs_disc, fprs_residual, fprs],
    ):
        auroc_this, _, fpr_this = get_measures(id_s, ood_s)
        aurocs_bin.append(auroc_this)
        fprs_bin.append(fpr_this)

        # print
        print_measures(auroc=auroc_this, fpr=fpr_this, method_name=name)

# the mean performance
print("\n\n")
print("Mean results:")
for  name, aurocs_bin, fprs_bin in zip(
    ["DiscSpace", "ResidualSpace", "Together"],
    [aurocs_disc, aurocs_residual, aurocs],
    [fprs_disc, fprs_residual, fprs],
):
    auroc = np.array(aurocs_bin).mean()
    fpr = np.array(fprs_bin).mean()
    print_measures(auroc=auroc, fpr=fpr, method_name=name)


import unittest

import sys
import time

sys.path.append("..")

from deltarest import DeltaRESTAdapter, DeltaRESTService

from pyspark.sql import SparkSession

class Test(unittest.TestCase):
    root_dir: str = f"/tmp/delta_rest_test_{int(time.time())}"

    spark: SparkSession = None

    dra: DeltaRESTAdapter

    @classmethod
    def setUpClass(cls):
        cls.spark = SparkSession \
            .builder \
            .appName("unit_tests") \
            .master("local") \
            .config("spark.jars.packages", "io.delta:delta-core_2.12:0.8.0") \
            .config("spark.sql.jsonGenerator.ignoreNullFields", "false") \
            .getOrCreate()
        cls.dra = DeltaRESTAdapter(cls.root_dir, 10)

    @classmethod
    def tearDownClass(cls):
        cls.spark.stop()
        # os.rmdir(cls.root_dir)

    def test_scenario(self):
        # PUT

        self.assertEqual(
            '{"message":"Table foo created"}',
            bytes.decode(self.dra.put("/tables/foo").response[0], "utf-8")
        )

        self.assertEqual(
            '{"message":"Table foo already exists"}',
            bytes.decode(self.dra.put("/tables/foo").response[0], "utf-8")
        )

        self.assertEqual(
            '{"message":"Table bar created"}',
            bytes.decode(self.dra.put("/tables/bar").response[0], "utf-8")
        )

        # POST

        self.assertEqual(
            '{"message":"Rows created"}',
            bytes.decode(self.dra.post(
                "/tables/foo",
                {"rows": [
                    {"id": 1},
                    {"id": 2}
                ]}
            ).response[0], "utf-8")
        )

        # schema merging
        self.assertEqual(
            '{"message":"Rows created"}',
            bytes.decode(self.dra.post(
                "/tables/foo",
                {"rows": [
                    {"collection": [1, 2]},
                    {"collection": [3, 4]}
                ]}
            ).response[0], "utf-8")
        )

        # post rows in a table not created yet

        self.assertEqual(
            '{"message":"Table foo_ not found"}',
            bytes.decode(self.dra.post(
                "/tables/foo_",
                {"rows": [
                    {"id": 1, "collection": [1, 2]},
                    {"id": 2, "collection": [3, 4]}
                ]}
            ).response[0], "utf-8")
        )

        # GET

        # get full table

        self.assertEqual(
            '{"rows":[{"id":null,"collection":[1,2]},' +
            '{"id":null,"collection":[3,4]},' +
            '{"id":1,"collection":null},{"id":2,"collection":null}]}',
            bytes.decode(
                self.dra.get("/tables/foo").response[0],
                "utf-8"
            )
        )

        # get with query on a table

        self.assertEqual(
            '{"rows":[{"count":2,"collections_concat_size":4}]}',
            bytes.decode(
                self.dra.get(
                    """/tables/foo?sql=SELECT
                    count(id) as count,
                    sum(size(ifnull(collection, array()))) as collections_concat_size
                    FROM foo"""
                ).response[0],
                "utf-8"
            )
        )

        # get with query on tables

        self.assertEqual(
            '{"rows":[{"count":16}]}',
            bytes.decode(
                self.dra.get(
                    """/tables?sql=SELECT
                      count(*) as count
                    FROM foo as t1 CROSS JOIN foo as t2
                    LIMIT 100"""
                ).response[0],
                "utf-8"
            )
        )

        # get tables names listing

        self.assertEqual(
            '{"tables":["bar","foo"]}',
            bytes.decode(
                self.dra.get("/tables").response[0],
                "utf-8"
            )
        )

    # def test_service(self):
    #     DeltaRESTService(self.root_dir).run("0.0.0.0", "4444")


import requests
from krules_core.base_functions import *
from krules_core import RuleConst as Const, event_types

from krules_core.providers import proc_events_rx_factory
from krules_env import publish_proc_events_errors, publish_proc_events_all  #, publish_proc_events_filtered

from app_functions.slack import SlackMessage

try:
    from ruleset_functions import *
except ImportError:
    # for local development
    from .ruleset_functions import *

rulename = Const.RULENAME
subscribe_to = Const.SUBSCRIBE_TO
ruledata = Const.RULEDATA
filters = Const.FILTERS
processing = Const.PROCESSING

proc_events_rx_factory().subscribe(
  on_next=publish_proc_events_all,
)
# proc_events_rx_factory().subscribe(
#  on_next=publish_proc_events_errors,
# )

rulesdata = [

    """
    Location changed (first location)
    """,
    {
        rulename: "on-location-changed-starting-notify-slack",
        subscribe_to: event_types.SUBJECT_PROPERTY_CHANGED,
        ruledata: {
            filters: [
                PayloadMatchOne("$.old_value", None)  # first time we get a location
            ],
            processing: [
                SlackMessage(
                    channel="devices_channel",
                    text=lambda self: ":triangular_flag_on_post: *{}* >> device *{}* located in {}".format(
                                    self.subject.name.split(":")[1],
                                    self.subject.name.split(":")[2],
                                    self.payload.get("value")
                                )
                ),
            ]
        }
    },

    """
    Location changed (changed from a known location)
    """,
    {
        rulename: "on-location-changed-moving-notify-slack",
        subscribe_to: event_types.SUBJECT_PROPERTY_CHANGED,
        ruledata: {
            filters: [
                PayloadMatchOne("$.old_value", lambda v: v is not None)
            ],
            processing: [
                SlackMessage(
                    channel="devices_channel",
                    text=lambda self: ":rocket: *{}* >> device *{}* moved to {}".format(
                                    self.subject.name.split(":")[1],
                                    self.subject.name.split(":")[2],
                                    self.payload.get("value")
                                )
                ),
            ]
        }
    },

]


# -*- coding: utf-8 -*-
"""Bottle web-server."""

from bottle import Bottle
from bottle import template, static_file
from os.path import dirname, abspath
from datetime import date, timedelta

app = Bottle()

BASE_DIR = dirname(abspath(__file__))

@app.route('/static/<filename:path>')
def server_static(filename):
    """Serve all static files which used in HTML."""
    return static_file(filename, root=f'{BASE_DIR}/static')

@app.route("/")
def main():
    """Load main page."""
    age = (date.today() - date(1999, 11, 11)) // timedelta(days=365.2425)

    return template(f'{BASE_DIR}/views/main.html', age=age)

if __name__ == "__main__":
    app.run(host='localhost', port=8080, debug=True)


from unittest import TestCase
from three_sum_closest import Solution

class TestSolution(TestCase):
    def test_three_sum_closest(self):
        inputs = (
            ([-1, 2, 1, -4], 1),
        )
        outs = (2,)
        for inp, out in zip(inputs, outs):
            self.assertEqual(out, Solution().threeSumClosest(*inp))


# coding: utf-8

import tkinter as tk
from tkinter import messagebox, filedialog
import os
from PIL import Image, ImageTk

from detector import PlateDetector
from util import resized_size

class LPRGUI:
    max_image_width = 600
    max_image_height = 600

    def __init__(self):
        self.detector = PlateDetector(chinese_cnn_path='./models/chinese/79.pth',
                                      others_cnn_path='./models/others/49.pth')

        root = tk.Tk()
        root.title('Licence Plate Recognition')
        root.geometry('800x800')
        root.resizable(0, 0)

        self.plate_number_var = tk.StringVar(root, value='None')

        self.add_gap(root, 20)

        # Show image
        self.image_canvas = tk.Canvas(root, width=self.max_image_width, height=self.max_image_height, bg='#E0E0E0')
        self.image_canvas.pack()
        self.tk_image = None

        self.add_gap(root, 20)

        # Show detected plate number
        frame = tk.Frame(root)
        frame.pack()
        tk.Label(frame, text='Plate Number:', font=('Times New Roman', 20)).grid(row=0, column=0)
        tk.Label(frame, textvariable=self.plate_number_var, font=('Times New Roman', 20)).grid(row=0, column=1)

        # Load image button
        self.load_button = tk.Button(root, text="Load Image", width=16, command=self.on_load_image)
        self.load_button.pack(expand=True)

        # Detect button
        self.detect_button = tk.Button(root, text="Detect", width=16, command=self.on_detect)
        self.detect_button.pack(expand=True)
        self.detect_button['state'] = 'disabled'

        # Clear button
        self.clear_button = tk.Button(root, text="Clear", width=16, command=self.on_clear)
        self.clear_button.pack(expand=True)

        print("-------------init success-------------")
        root.mainloop()

    def on_load_image(self):
        file_path = filedialog.askopenfilename(title='Load Image',
                                               filetypes=[('Image Files', '*.jfif *.jpg *.png *.gif'),
                                                          ('All Files', '*')],
                                               initialdir=os.getcwd())

        assert os.path.exists(file_path)

        image = Image.open(file_path)
        self.draw_canvas(image=image)

        self.detector.load_img(file_path)
        self.detect_button['state'] = 'active'
        self.plate_number_var.set('None')

    def on_detect(self):
        try:
            self.detector.find_plate_location()
            self.draw_canvas(Image.fromarray(self.detector.img_after_detected[..., ::-1]))
            self.detector.split_characters()
            self.detector.classify_characters()
            self.plate_number_var.set(''.join(self.detector.result_list))
        except Exception:
            messagebox.showwarning('Error', 'Detection failed!')

    def on_clear(self):
        self.tk_image = None
        self.image_canvas.delete('all')
        self.detector.clear_img()
        self.detect_button['state'] = 'disabled'
        self.plate_number_var.set('None')

    def draw_canvas(self, image):
        self.image_canvas.delete('all')
        image = image.resize(resized_size(image.size, (self.max_image_width, self.max_image_height), mode='scale'))
        self.tk_image = ImageTk.PhotoImage(image)

        horizontal_padding, vertical_padding = 0, 0
        if image.width < self.max_image_width:
            horizontal_padding = (self.max_image_width - image.width) // 2
        else:
            vertical_padding = (self.max_image_height - image.height) // 2
        image_item = self.image_canvas.create_image(horizontal_padding, vertical_padding, anchor='nw')
        self.image_canvas.itemconfig(image_item, image=self.tk_image)

    @classmethod
    def add_gap(cls, root, height):
        tk.Frame(root, height=height).pack()

if __name__ == '__main__':
    LPRGUI()


# JadenCase란 모든 단어의 첫 문자가 대문자이고, 그 외의 알파벳은 소문자인 문자열입니다. 단, 첫 문자가 알파벳이 아닐 때에는 이어지는 알파벳은 소문자로 쓰면 됩니다. (첫 번째 입출력 예 참고)
# 문자열 s가 주어졌을 때, s를 JadenCase로 바꾼 문자열을 리턴하는 함수, solution을 완성해주세요.
# #s는 알파벳과 숫자, 공백문자(" ")로 이루어져 있습니다.
# 숫자는 단어의 첫 문자로만 나옵니다.
# 숫자로만 이루어진 단어는 없습니다.
# 공백문자가 연속해서 나올 수 있습니다. => split을 사용할수없음

def solution(s):
    answer=s[0].upper()
    for i in range(1,len(s)):
        if s[i-1]==" " and s[i] !=" ":
            answer += s[i].upper()
        else:
            answer += s[i].lower()
    return answer


# Given a string of numbers and operators, return all possible results from computing all the different
# possible ways to group numbers and operators. The valid operators are +, - and *.
#
#
# Example 1
# Input: "2-1-1".
#
# ((2-1)-1) = 0
# (2-(1-1)) = 2
# Output: [0, 2]
#
#
# Example 2
# Input: "2*3-4*5"
#
# (2*(3-(4*5))) = -34
# ((2*3)-(4*5)) = -14
# ((2*(3-4))*5) = -10
# (2*((3-4)*5)) = -10
# (((2*3)-4)*5) = 10
# Output: [-34, -14, -10, -10, 10]
#
class Solution(object):
    def diffWaysToCompute(self, input):
        """
        :type input: str
        :rtype: List[int]
        """
        return self.dfs(input)

    def dfs(self, input):
        ans = []
        for i in range(len(input)):
            if input[i] == '+' or input[i] == '-' or input[i] == '*':
                left = self.dfs(input[:i])
                right = self.dfs(input[i + 1:])
                for ele1 in left:
                    for ele2 in right:
                        if input[i] == '+':
                            ans.append(ele1 + ele2)
                        elif input[i] == '-':
                            ans.append(ele1 - ele2)
                        elif input[i] == '*':
                            ans.append(ele1 * ele2)
        if ans == []:
            ans.append(eval(input))
        return ans

241. Different Ways to Add Parentheses.py


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os
import time
import numpy as np
import tensorflow as tf
import pandas as pd
import model
from data_reader import load_data, DataReader, DataReaderFastText, FasttextModel

FLAGS = tf.flags.FLAGS

def run_test(session, m, data, batch_size, num_steps):
    """Runs the model on the given data."""

    costs = 0.0
    iters = 0
    state = session.run(m.initial_state)

    for step, (x, y) in enumerate(reader.dataset_iterator(data, batch_size, num_steps)):
        cost, state = session.run([m.cost, m.final_state], {
            m.input_data: x,
            m.targets: y,
            m.initial_state: state
        })

        costs += cost
        iters += 1

    return costs / iters

def initialize_epoch_data_dict():
    return {
        'test_loss': list(),
        'test_perplexity': list(),
        'test_samples': list(),
        'time_elapsed': list(),
        'time_per_batch': list(),
    }

def save_data_to_csv(avg_loss,count,time_elapsed):
    if not os.path.exists(FLAGS.train_dir):
        os.makedirs(FLAGS.train_dir)
    pd.DataFrame(FLAGS.flag_values_dict(), index=range(1)).to_csv(FLAGS.train_dir + '/test_parameters.csv')
    test_results = initialize_epoch_data_dict()

    test_results['test_loss'].append(avg_loss)
    test_results['test_perplexity'].append(np.exp(avg_loss))
    test_results["test_samples"].append(count * FLAGS.batch_size)
    test_results["time_elapsed"].append(time_elapsed)
    test_results["time_per_batch"].append(time_elapsed / count)

    pd.DataFrame(test_results, index=range(1)).to_csv(FLAGS.train_dir + '/test_results.csv')

def main(print):
    ''' Loads trained model and evaluates it on test split '''
    if FLAGS.load_model_for_test is None:
        print('Please specify checkpoint file to load model from')
        return -1

    if not os.path.exists(FLAGS.load_model_for_test + ".index"):
        print('Checkpoint file not found', FLAGS.load_model_for_test)
        return -1

    word_vocab, char_vocab, word_tensors, char_tensors, max_word_length, words_list = \
        load_data(FLAGS.data_dir, FLAGS.max_word_length, eos=FLAGS.EOS)

    test_reader = DataReader(word_tensors['test'], char_tensors['test'],
                              FLAGS.batch_size, FLAGS.num_unroll_steps)

    fasttext_model_path = None
    if FLAGS.fasttext_model_path:
        fasttext_model_path = FLAGS.fasttext_model_path

    if 'fasttext' in FLAGS.embedding:
        fasttext_model = FasttextModel(fasttext_path=fasttext_model_path).get_fasttext_model()
        test_ft_reader = DataReaderFastText(words_list=words_list, batch_size=FLAGS.batch_size,
                                            num_unroll_steps=FLAGS.num_unroll_steps,
                                            model=fasttext_model,
                                            data='test')

    print('initialized test dataset reader')

    with tf.Graph().as_default(), tf.Session() as session:

        # tensorflow seed must be inside graph
        tf.set_random_seed(FLAGS.seed)
        np.random.seed(seed=FLAGS.seed)

        ''' build inference graph '''
        with tf.variable_scope("Model"):
            m = model.inference_graph(
                    char_vocab_size=char_vocab.size,
                    word_vocab_size=word_vocab.size,
                    char_embed_size=FLAGS.char_embed_size,
                    batch_size=FLAGS.batch_size,
                    num_highway_layers=FLAGS.highway_layers,
                    num_rnn_layers=FLAGS.rnn_layers,
                    rnn_size=FLAGS.rnn_size,
                    max_word_length=max_word_length,
                    kernels=eval(FLAGS.kernels),
                    kernel_features=eval(FLAGS.kernel_features),
                    num_unroll_steps=FLAGS.num_unroll_steps,
                    dropout=0,
                    embedding=FLAGS.embedding,
                    fasttext_word_dim=300,
                    acoustic_features_dim=4)
            m.update(model.loss_graph(m.logits, FLAGS.batch_size, FLAGS.num_unroll_steps))

            global_step = tf.Variable(0, dtype=tf.int32, name='global_step')

        saver = tf.train.Saver()
        saver.restore(session, FLAGS.load_model_for_test)
        print('Loaded model from' + str(FLAGS.load_model_for_test) + 'saved at global step' + str(global_step.eval()))

        ''' training starts here '''
        rnn_state = session.run(m.initial_rnn_state)
        count = 0
        avg_loss = 0
        start_time = time.time()
        for batch_kim, batch_ft in zip(test_reader.iter(), test_ft_reader.iter()):
            count += 1
            x, y = batch_kim
            loss, rnn_state, logits = session.run([
                m.loss,
                m.final_rnn_state,
                m.logits
            ], {
                m.input2: batch_ft,
                m.input: x,
                m.targets: y,
                m.initial_rnn_state: rnn_state
            })

            avg_loss += loss

        avg_loss /= count
        time_elapsed = time.time() - start_time

        print("test loss = %6.8f, perplexity = %6.8f" % (avg_loss, np.exp(avg_loss)))
        print("test samples:" + str( count*FLAGS.batch_size) + "time elapsed:" + str( time_elapsed) + "time per one batch:" +str(time_elapsed/count))

        save_data_to_csv(avg_loss, count, time_elapsed)

if __name__ == "__main__":
    tf.app.run()


import random

def game(num):
    pregunta = input("Hazme una pregunta: ")
    if num ==1:
        return "Chancla"
    elif num==2:
        return "Nel papi"
    elif num==3:
        return "Simon carnal"
    elif num==4:
        return "Concentrate y pregunta otravez"
    elif num==5:
        return "No creo"
    elif num==6:
        return "Pregúntale a tu hermana"
    elif num==7:
        return "¿Porqué preguntas esas mamadas?"
    elif num==8:
        return "Ya verás"

numero=random.randint(1,8)
function = game(numero)
print(function)


"""
Resample Raster Files
"""

def match_cellsize_and_clip(rstBands, refRaster, outFolder,
                            clipgeo=None, isint=None, ws=None):
    """
    Resample images to make them with the same resolution and clip

    Good to resample Sentinel bands with more than 10 meters.

    Dependencies:
    * GRASS GIS;
    * GDAL/OGR.
    """

    import os
    from glass.prop.df  import is_rst
    from glass.prop.prj import rst_epsg
    from glass.wenv.grs import run_grass
    from glass.pys.oss  import fprop, mkdir
    from glass.pys.tm   import now_as_str

    # Check if outfolder exists
    if not os.path.exists(outFolder):
        mkdir(outFolder, overwrite=None)

    # Get EPSG from refRaster
    epsg = rst_epsg(refRaster, returnIsProj=None)

    """
    Start GRASS GIS Session
    """
    ws = mkdir(os.path.join(outFolder, now_as_str())) \
        if not ws else ws
    grsb = run_grass(
        ws, grassBIN='grass78', location='resample',
        srs=epsg
    )

    import grass.script.setup as gsetup

    gsetup.init(grsb, ws, 'resample', 'PERMANENT')

    """
    Import packages related with GRASS GIS
    """
    from glass.it.rst    import rst_to_grs, grs_to_rst, grs_to_mask
    from glass.wenv.grs  import rst_to_region
    from glass.it.shp    import shp_to_grs
    from glass.dtt.torst import grsshp_to_grsrst as shp_to_rst

    # Send Ref Raster to GRASS GIS and set region
    extRst = rst_to_grs(refRaster, 'ext_rst')
    rst_to_region(extRst)

    # Import all bands in rstBands
    grs_bands = [rst_to_grs(i, fprop(i, 'fn')) for i in rstBands]

    if clipgeo:
        clip_is_rst = is_rst(clipgeo)

        # Add clipgeo to GRASS
        if not clip_is_rst:
            if '.gdb' in clipgeo:
                lyr = os.path.basename(clipgeo)

                clipgeo = os.path.dirname(clipgeo)

                if clipgeo[-4:] != '.gdb':
                    clipgeo = os.path.dirname(clipgeo)

            else:
                lyr = None

            grs_clip = shp_to_grs(clipgeo, asCMD=True, lyrname=lyr)

            # SHP to Raster
            rst_clip = shp_to_rst(
                grs_clip, 1, f'rst_{grs_clip}',
                cmd=True
            )

        else:
            rst_clip = rst_to_grs(clipgeo, fprop(clipgeo, 'fn'))

        # Set region using
        rst_to_region(rst_clip)

        # Set mask
        grs_to_mask(rst_clip)

    # Export bands
    return [grs_to_rst(
        i, os.path.join(outFolder, i + '.tif'),
        rtype=int if isint else float
    ) for i in grs_bands]

def resample_by_majority(refrst, valrst, out_rst):
    """
    Resample valrst based on refrst:
        Get Majority value of valrst for each cell in refrst

    Useful when ref raster has cellsize greater
    than value raster.

    TODO: Valrst must be of int type
    """

    import numpy        as np
    from osgeo          import gdal
    from glass.prop.img import get_cell_size, get_nd, rst_epsg
    from glass.wt.rst   import obj_to_rst

    # Data to Array
    if type(refrst) == gdal.Dataset:
        refsrc = refrst

    else:
        refsrc = gdal.Open(refrst)

    if type(valrst) == gdal.Dataset:
        valsrc = valrst
    else:
        valsrc = gdal.Open(valrst)

    refnum = refsrc.ReadAsArray()
    valnum = valsrc.ReadAsArray()

    # Get Ref shape
    ref_shape = refnum.shape

    # in a row, how many cells valnum are for each refnum cell
    refcs = int(get_cell_size(refsrc)[0])
    valcs = int(get_cell_size(valsrc)[0])
    dcell = int(refcs / valcs)

    # Valnum must be of int type

    # Create generalized/resampled raster
    resnum = np.zeros(ref_shape, dtype=valnum.dtype)

    for row in range(ref_shape[0]):
        for col in range(ref_shape[1]):
            resnum[row, col] = np.bincount(
                valnum[row*dcell:row*dcell+dcell, col*dcell : col*dcell+dcell].reshape(dcell*dcell)
            ).argmax()

    # Export out raster
    return obj_to_rst(
        resnum, out_rst,
        refsrc.GetGeoTransform(), rst_epsg(refsrc),
        noData=get_nd(valsrc)
    )


# w mode=>it will overwrite the existing content if previously written
# D:\\python\\fileh\\write.txt

# it will create or open file bcoz we are using w mode
obj = open("D:\\python\\fileh\\write.txt", "w")
# obj.write("This is 1st line written using writefile.py")
obj.write("This is 2nd line written using writefile.py")  # overwritten
obj.close()

# you can also use with keyword to write the file


# -*- coding: utf-8 -*-

from django.http import HttpResponse
from django.template import RequestContext, Template
from django.views.decorators.csrf import csrf_exempt
from django.utils.encoding import smart_str, smart_unicode

import xml.etree.ElementTree as ET
import urllib, urllib2, time, hashlib

@csrf_exempt
def handle_request(request):
    if request.method == 'GET':
        response = HttpResponse(check_signature(request),content_type="text/plain")
        return response
    elif request.method == 'POST':
        response = HttpResponse(response_msg(request),content_type="application/xml")
        return response
    else:
        return HttpResponse("Hello world ")

def check_signature(request):
    token = "wangqihui0324"
    signature = request.GET.get("signature")
    timestamp = request.GET.get("timestamp")
    nonce = request.GET.get("nonce")
    echostr = request.GET.get("echostr")
    signature_tmp = [token,timestamp,nonce]
    #lexicographical sorting
    signature_tmp.sort()
    #string concatenation
    # signature_tmp = ''.join(signature_tmp)
    signature_tmp = "%s%s%s" % tuple(signature_tmp)
    #sha1 encryption
    signature_tmp = hashlib.sha1(signature_tmp).hexdigest()
    #compare with signature
    if signature_tmp == signature:
        return echostr
    else:
        return HttpResponse("Hello world ! ")

def response_msg(request):
    #get post message
    msg = request.body
    #parser xml format
    msg_xml = ET.fromstring(msg)
    msg = {}
    for element in msg_xml:
        msg[element.tag] = smart_str(element.text)
    # content = msg.get('Content')
    # url_get_base = "http://api.ltp-cloud.com/analysis/?"
    # api_key = "YourApikey"
    # format = "plain"
    # pattern = "pos"
    #call for ltp-cloud api
    # result = urllib2.urlopen(url_get_base + 'api_key='+api_key+'&text='+content+'&format='+format+'&pattern='+pattern)
    # content = result.read().strip()
    content = "1"
    response = "<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%d</CreateTime><MsgType><![CDATA[%s]]></MsgType><Content><![CDATA[%s]]></Content></xml>"
    #generate xml formt response
    response = response % (msg['FromUserName'],msg['ToUserName'],int(time.time()),'text',content)
    return response


import re
path = r"C:\Users\nicoa\Documents\Programacion\UCEMA_Fundamentos_de_informatica-master\Python_intro\manipulacion_archivos.txt"
lista = []
lista2 = []
with open(path,"r") as file:
    for lineas in file:
        lista.extend(lineas.split())
    print("Hay", len(lista), "palabras")
    for i in range(len(lista)):
        lista2.append(len(lista[i]))
    print(lista2)
    print(max(lista2))
    numero = lista2.index(14)
    print(lista[numero])


import re
import operator

filename = 'aoc201608_input.txt'
# filename = 'testinput.txt'
f = open(filename,"r")

#read lines into one string
data = [x.strip() for x in f.readlines()]

# build rectangles or initital grid
def buildrect(x,y,lightson = 0):
    grid = {}
    state = ''
    if lightson == 1:
        state = '#'
    else:
        state = '.'
    for i in range(x):
        for j in range(y):
            grid[(i,j)] = state
    return grid

# return the current grid
def curgrid(dict,linelength):
    lightkeys = sorted(dict,key = operator.itemgetter(1,0))
    lightgrid = ''
    for key in lightkeys:
        if key in lights:
            lightgrid += lights[key]
    regex = "(.{" + str(linelength) + "})"
    output = re.sub(regex,"\\1\n",lightgrid, re.DOTALL)
    return output

# set grid size
x = 50
y = 6

# build initital grid
lights = buildrect(x,y)

#loop through instructions
for i in data:
    rect = re.match(r'(rect)\s(\d+)x(\d+)',i)
    rotate = re.match(r'(rotate.*)\s[x|y]=(\d+)\sby\s(\d+)',i)

    if rect is None:
        op = rotate
    else:
        op = rect
    #handle rectangle instructions
    if op.group(1) =='rect':
        newrect = buildrect(int(rect.group(2)),int(rect.group(3)),1)
        lights.update(newrect)
    #handle rot column instructions
    elif op.group(1) == 'rotate column':
        newgrid = {}
        # loop through light keys
        for key in lights:
            matchval = '\(' + op.group(2) + '\,\s\d+\)'
            # if key x matches instruction x then create shifted key/value
            if re.match(matchval,str(key)):
                newy = (key[1] + int(op.group(3))) % y
                newgrid[(key[0],newy)] = lights[key]
        lights.update(newgrid)

    elif op.group(1) == 'rotate row':
        newgrid = {}
        # loop through light keys
        for key in lights:
            matchval = '\(\d+\,\s' + op.group(2) + '\)'
            # if key x matches instruction x then create shifted key/value
            if re.match(matchval,str(key)):
                newx = (key[0] + int(op.group(3))) % x
                newgrid[(newx,key[1])] = lights[key]
        lights.update(newgrid)

    # print(i)
    # print(curgrid(lights,x))

#part1
print(len(re.findall('#',curgrid(lights,x))))
#part2
print(curgrid(lights,x))


from __future__ import (absolute_import, division,
                        print_function, unicode_literals)

import sys
import os
sys.path.append(os.path.join("..", ".."))

from ds_drawer.generators.lists import create_linked_list
from ds_drawer.shapes.cross import Cross
from ds_drawer.shapes.arrow import Arrow
from ds_drawer.shapes.pointer import Pointer
from ds_drawer.shapes.linked_list import LinkedList
from ds_drawer.viewer import viewer

RED = (255, 0, 0)
BLUE = (0, 0, 255)

def draw():
    l, e2, a24, e4, a4n, n = create_linked_list([None, 2, None, 4])
    # Add 0
    cl = Cross(l, color=RED)
    e0 = LinkedList((e2.x - 40, e2.y + 40, 0), 0, color=RED)
    a02 = Arrow(e0.prox_1, e2.start_4, color=RED)
    l0 = Pointer(e0, 'l', direction='ul.start_0', color=RED)
    # Add 3
    ca24 = Cross(a24, color=BLUE)
    e3 = LinkedList((e4.x - 60, e4.y + 40, 0), 3, color=BLUE)
    a23 = Arrow(e2.prox_3, e3.start_0, color=BLUE)
    a34 = Arrow(e3.prox_1, e4.start_4, color=BLUE)

    ant = Pointer(e2, 'ant', direction='u.u_2', color=BLUE)
    pp = Pointer(e4, 'p', direction='u.u_2', color=BLUE)
    novo = Pointer(e3, 'novo', direction='d.d_2', color=BLUE)

    return [
    	l, e2, a24, e4, a4n, n,
    	cl, e0,  a02, l0,
        ca24, e3, a23, a34,
        ant, pp, novo
    ]

if __name__ == '__main__':
	viewer(draw)


def get_population(data):
  population_dict = {
    '2022' : int(data['2022 Population']),
    '2020' : int(data['2020 Population']),
    '2015' : int(data['2015 Population']),
    '2010' : int(data['2010 Population']),
    '2000' : int(data['2000 Population']),
    '1990' : int(data['1990 Population']),
    '1980' : int(data['1980 Population']),
    "1970" : int(data['1970 Population'])
  }
  labels = population_dict.keys()
  values = population_dict.values()
  return labels, values

def population_by_country(data, country):
  #print(country)
 # print(data)
  result = list(filter(lambda item: item['Country/Territory'] == country, data))

  return result

def column(data):
  data = list(filter(lambda item: item["Continent"] == "South America", data))
  country = list(map(lambda item : item['Country/Territory'], data))
  column = list(map(lambda item : item['World Population Percentage'], data))
  return country, column


#!/usr/bin/env pybricks-micropython
from constants import(VERY_HIGH_SPEED,
                    MEDIUM_SPEED,HIGH_SPEED,ROTATION_GEAR_RATIO,
                    MIN_ROTATION_ANGLE,MAX_ROTATION_ANGLE,
                    CHECK_INTERVAL_IN_MILLISECONDS,
                    CRANE_GEAR_RATIO,
                    CRANE_RESTING_HIGH_ANGLE,
                    CLAW_OPEN_ANGLE,
                    STRING_TO_COLOR_DICTIONARY,
                    MIN_NUMBER_POSITIONS
                    )

from robot_setup import(rotationMotor,
                        craneMotor,
                        clawMotor,
                        screen,
                        speaker,
                        buttons,
                        ev3)
from pybricks.parameters import Button
from pybricks.tools import wait

def notify(message: str) -> None:
    """
    Notify user through terminal, screen and speaker.

    Parameters:
      message (str): message to notify user with.
    """
    print(message)
    screen.print(message)
    speaker.say(message)

def configure_height_and_angle_positions() -> tuple:
    """
    Configure a specific zone by pressing buttons on the robot.

    Use buttons on the ev3 to change height and move left and right. Center button to commit position.

    Returns:
      tuple(angle (float), height (float)): angle and height of commited positions
    """
    initial_rotation = rotationMotor.angle()
    initial_crane_height = craneMotor.angle()
    clawMotor.run_target(HIGH_SPEED, CLAW_OPEN_ANGLE)
    angle_rotation = angle_crane = None
    while True:
        pressed = buttons.pressed()

        if Button.CENTER in pressed:
            craneMotor.hold()
            rotationMotor.hold()
            angle_rotation = -rotationMotor.angle() / ROTATION_GEAR_RATIO
            angle_crane = craneMotor.angle()
            break

        if Button.UP in pressed:
            craneMotor.run(-MEDIUM_SPEED)
        elif Button.DOWN in pressed:
            craneMotor.run(MEDIUM_SPEED)
        else:
            craneMotor.hold()

        if Button.RIGHT in pressed and rotationMotor.angle() / ROTATION_GEAR_RATIO < MIN_ROTATION_ANGLE:
            rotationMotor.run(VERY_HIGH_SPEED)
        elif Button.LEFT in pressed and rotationMotor.angle() / ROTATION_GEAR_RATIO > -MAX_ROTATION_ANGLE:
            rotationMotor.run(-VERY_HIGH_SPEED)
        else:
            rotationMotor.hold()
        wait(CHECK_INTERVAL_IN_MILLISECONDS)

    craneMotor.run_target(HIGH_SPEED, -CRANE_GEAR_RATIO * CRANE_RESTING_HIGH_ANGLE)
    rotationMotor.run_target(VERY_HIGH_SPEED, initial_rotation)
    craneMotor.run_target(HIGH_SPEED, initial_crane_height)
    return angle_rotation, angle_crane

def configure_zones(number_of_zones, include_heights=False):
    """
    Configure some number of zones using the buttons.

    Use buttons on the ev3 to change height and move left and right. Center button to commit position.

    Parameters:
      number_of_zones (int): number of zones to configure
      include_heights (bool): Whether to include the heights in the list. Default False.

    Returns:
      if include_heights:
        lst[tuple(angle (float), height (float))]: list of tuples of angle and height of commited positions.
      else:
        lst[float]: list of angles
    """
    lst = []
    notify("Configuring zones")

    for i in range(number_of_zones):
        ev3.screen.print("\tzone: " + str(i))
        angle_rotation, angle_crane = configure_height_and_angle_positions()
        if include_heights:
            lst.append((angle_rotation, angle_crane))
        else:
            lst.append(angle_rotation)
    notify("DONE configuring zones")
    return lst

def user_generate_color_dictionary():
    print("""
Select one of the colors:
Black, Blue, Green, Yellow, Red, White, Brown.
Select an angle in [0, 180].
Select number of positions (minimum 3).
For each position...\
"""
    )
    rotationMotor.stop()

    color_dictionary = dict()

    positions_input_lambda = lambda: int(input("Select number of positions: "))
    color_input_lambda = lambda: input(
        "Select color for position " + str(i + 1) + ": "
    ).lower()

    positions = positions_input_lambda()
    while positions < MIN_NUMBER_POSITIONS:
        print("Please enter an integer greater or equal to", MIN_NUMBER_POSITIONS)
        positions = positions_input_lambda()

    for i in range(positions):
        print("\nPosition ", str(i + 1), ":", sep="")

        color = color_input_lambda()
        while color not in STRING_TO_COLOR_DICTIONARY:
            print("Please enter a color in", str(STRING_TO_COLOR_DICTIONARY.keys()))
            color = color_input_lambda()

        input("Press enter to select current position as drop-off zone.")
        angle = -rotationMotor.angle() / ROTATION_GEAR_RATIO

        color_dictionary[STRING_TO_COLOR_DICTIONARY[color]] = angle
    return color_dictionary


from zipline.pipeline.factors import CustomFactor
from zipline.pipeline.data import USEquityPricing
import numpy as np
import warnings

def recurs_sum(arr):
    arr_sum = np.zeros(arr.shape)
    arr_sum[0] = arr[0]

    for i in range(1, len(arr)):
        arr_sum[i] = arr_sum[i-1]+arr[i]

    return arr_sum

class AD(CustomFactor):
    """
    Chaikin Accumulation Distribution Oscillator

    Volume indicator

    **Default Inputs:** USEquityPricing.high, USEquityPricing.low, USEquitypricing.close, USEquityPricing.volume

    **Default Window Length:** 14

    http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:accumulation_distribution_line
    """
    inputs = [USEquityPricing.close, USEquityPricing.high, USEquityPricing.low, USEquityPricing.volume]
    window_length = 14 + 1
    outputs = 'cho_yesterday', 'AD_yesterday', 'cho_today', 'AD_today'

    def compute(self, today, assets, out, close, high, low, vol):

        # ignore unimportant nan warnings
        warnings.filterwarnings('ignore')

        # close location value
        clv = ((close - low) - (high - close)) / (high - low)
        ad = clv * vol

        # today
        ad_revised = recurs_sum(ad[-14:])

        sma_3d = np.nanmean(ad_revised[-3:], axis=0)
        sma_10d = np.nanmean(ad_revised[-10:], axis=0)

        cho_today = sma_3d - sma_10d

        out.cho_today[:] = cho_today
        out.AD_today[:] = ad_revised[-1]

        # yesterday
        ad_revised = recurs_sum(ad[:14])

        sma_3d = np.nanmean(ad_revised[-3:], axis=0)
        sma_10d = np.nanmean(ad_revised[-10:], axis=0)

        cho_yesterday = sma_3d - sma_10d

        out.cho_yesterday[:] = cho_yesterday
        out.AD_yesterday[:] = ad_revised[-1]


import bisect
from typing import List

class Solution:
    def maxEnvelopes(self, envelopes: List[List[int]]) -> int:
        items = sorted(envelopes, key=lambda x: (x[0], -x[1]))
        piles = []
        for item in items:
            v = item[1]
            i = bisect.bisect_left(piles, v)
            if i == len(piles):
                piles.append(v)
            else:
                piles[i] = v
        return len(piles)

solution = Solution()
envelopes = [[5,4],[6,4],[6,7],[2,3]]
assert solution.maxEnvelopes(envelopes) == 3, "Should be 3"

leetcode/354. Russian Doll Envelopes/index.py


import os
import requests
from bs4 import BeautifulSoup

#os.system("clear")

def crawl():
    url = "https://www.iban.com/currency-codes"

    iban_result = requests.get(url)
    iban_soup = BeautifulSoup(iban_result.text, "html.parser")

    table = iban_soup.find("table", {"class": "table table-bordered downloads tablesorter"})

    tbody = table.find("tbody")
    tds = tbody.find_all("td")

    information = {}
    length = len(tds)
    key = 0
    country = []
    for i in range(0, length, 4):
        if tds[i + 1].string == "No universal currency":
            continue
        else:
            country.append(tds[i].string.capitalize())
            country.append(tds[i + 1].string.capitalize())
            country.append(tds[i + 2].string)
            country.append(tds[i + 3].string)
            information[key] = country
            key = key + 1
            country = []

    return information

def main():
    country_dic = crawl()
    print("Hello! Please choose select a country by number: ")

    for i in range(len(country_dic)):
        print('# {} {}'.format(i, country_dic[i][0]))

    while (True):
        try:
            country_num = int(input("#: "))
            if country_num >= len(country_dic):
                print("Choose a number from the list.")
                continue
            else:
                break
        except:
            print("That wasn't a number.")
            continue

    print(f"You choose {country_dic[country_num][0]}")
    print(f"The currency code is {country_dic[country_num][2]}")

main()


num = int(input())
count = 0

def check(string):
  alph = [1 for i in range(26)]
  global count
  # 문자열 길이만큼 반복
  for i in range(len(string) - 1):
    text = string[i]
    if (text == string[i+1]):
      continue
    if(alph[ord(text) - 97] == 0):
      return
    alph[ord(text) - 97] = 0
    if(alph[ord(string[i+1]) - 97] == 0):
      return
  count += 1

for i in range(num):
  string = input()
  check(string)

print(count)


import PySimpleGUI as sg

class GameGui:
    def __init__(self,
                   box_size=15,
                   title = 'Japanese Crossword Puzzle!',
                   puzzle_size=500,
                   coor_sys_height=130
                  ):
        self.box_size = box_size
        self.rows = 8
        self.cols = 8
        sg.theme('SystemDefaultForReal')

        layout = [
            [sg.Text(title), sg.Text('Press "Generate Puzzle" to start game', key='-Status-')],
            [sg.Graph((puzzle_size, puzzle_size),
                      (0, coor_sys_height),
                      (coor_sys_height, 0),
                      key='-PuzzleBoard-',
                      change_submits=True, drag_submits=False),
             sg.Text(('\n'+' '*60)*24, key='-Clues-')
            ],
        ]

        # Generate japanese character input buttons
        i = 0
        for row in range(4):
            input_buttons = []
            for col in range(22):
                # every button is associated with a single character for event detection
                input_buttons.append(sg.Button('{}'.format(chr(0x3041 + i))))
                i += 1
                if 0x3041 + i > 0x3096: break # remove unnecessary characters
            layout.append(input_buttons)

        layout.append([sg.Button('Generate Puzzle'), sg.Button('Show Answer'), sg.Button('Exit')])

        self.window = sg.Window('Window Title', layout, finalize=True)

    def get_puzzle_interface(self):
        return self.window['-PuzzleBoard-']

    def monitor_events(self):
        return self.window.read()

    def display_puzzle(self, horizontal_words = [], vertical_words = [], show_answer=False):
        rows = self.rows
        cols = self.cols
        box_size = self.box_size
        puzzle_board = self.get_puzzle_interface()

        # build black background first
        for row in range(rows):
            for col in range(cols):
                self.render_rectangle(row, col, fill_color='black')

        counter = 0

        # render white squares
        for hori_word in horizontal_words:
            # unpack info:
            start_row, start_col, word_len, clue = hori_word[0], hori_word[1], len(hori_word[2]), hori_word[3]
            for i in range(start_col, start_col + word_len):
                self.render_rectangle(start_row, i, fill_color='white')
                if show_answer: self.render_tile_char(start_row, i, hori_word[2][i-start_col],'blue')
        for vert_word in vertical_words:
            # unpack info:
            start_row, start_col, word_len, clue = vert_word[0], vert_word[1], len(vert_word[2]), hori_word[3]
            for i in range(start_row, start_row + word_len):
                self.render_rectangle(i, start_col, fill_color='white')
                if show_answer: self.render_tile_char(i, start_col, vert_word[2][i-start_row],'blue')

        # render tile lables for vertical and horizontal words
        self.render_tile_labels(horizontal_words, vertical_words)
        self.render_clues(horizontal_words, vertical_words)
        self.window['-Status-'].update("Generated Puzzle")

        if show_answer:
            self.window['-Status-'].update("Showing Answer")

    def render_rectangle(self, row, col, fill_color='black', line_color='black'):
        box_size = self.box_size
        puzzle_board = self.get_puzzle_interface()

        puzzle_board.draw_rectangle((col * box_size , row * box_size ),
                                 ((col+1) * box_size , (row+1) * box_size ),
                                 line_color=line_color,  fill_color=fill_color)
    def render_black_rectangles(self, words_matrix):
        rows = self.rows
        cols = self.cols
        box_size = self.box_size
        puzzle_board = self.get_puzzle_interface()

        for row in range(len(words_matrix)):
            for col in range(len(words_matrix[row])):
                if not (words_matrix[row][col]):
                    self.render_rectangle(row, col, fill_color='black')

    def render_selected_tile(self, row, col, fill_color='green'):
        rows = self.rows
        cols = self.cols
        box_size = self.box_size
        puzzle_board = self.get_puzzle_interface()

        # draw polygon
        points = [((col+.9) * box_size , (row+.1) * box_size ),
                  ((col+.99) * box_size , (row+.1) * box_size ),
                  ((col+.99) * box_size , (row+.2) * box_size )
                 ]
        puzzle_board.DrawPolygon(points, fill_color=fill_color)

    def clean_previous_selected_tiles(self, words_matrix):
        rows = self.rows
        cols = self.cols
        box_size = self.box_size
        puzzle_board = self.get_puzzle_interface()
        # clear all previous polygons
        for row in range(rows):
            for col in range(cols):
                self.render_selected_tile(row, col, fill_color='white')

        self.render_black_rectangles(words_matrix)

    def render_tile_char(self, row, col, tile_char, color='black'):
        box_size = self.box_size
        puzzle_board = self.get_puzzle_interface()

        self.render_rectangle(row, col, fill_color='white')
        letter_location = (col * box_size + box_size*.7,
                           row * box_size + box_size*.7)
        puzzle_board.draw_text(tile_char, letter_location, font='Courier 25', color=color)

    def render_tile_label(self, row, col, tile_label, align='horizontal'):
        box_size = self.box_size
        puzzle_board = self.get_puzzle_interface()
        if align == 'horizontal':
            puzzle_board.draw_text(tile_label, (col * box_size + box_size*.2, row * box_size+ box_size*.4))
        else: # for vertical words
            puzzle_board.draw_text(tile_label, (col * box_size + box_size*.4, row * box_size+ box_size*.2))

    def render_tile_labels(self, horizontal_words, vertical_words):
        box_size = self.box_size
        puzzle_board = self.get_puzzle_interface()

        counter = 0

        for hori_word in horizontal_words:

            # unpack info:
            start_row, start_col = hori_word[0], hori_word[1]
            self.render_tile_label(start_row, start_col, tile_label='h'+str(counter), align='horizontal')
            counter += 1

        counter = 0
        for vert_word in vertical_words:
            # unpack info:
            start_row, start_col = vert_word[0], vert_word[1]
            self.render_tile_label(start_row, start_col,tile_label='v'+str(counter), align='vertical')
            counter += 1

    def render_clues(self, horizontal_words, vertical_words):
        box_size = self.box_size
        puzzle_board = self.get_puzzle_interface()

        counter = 0
        clues = 'Clues:\n'
        for hori_word in horizontal_words:

            # unpack info:
            clue = hori_word[3]
            clues = clues + 'h'+str(counter) + ') ' + clue + '\n'
            counter += 1

        counter = 0
        for vert_word in vertical_words:
            # unpack info:
            clue = vert_word[3]
            clues = clues + 'v'+str(counter) + ') ' + clue + '\n'
            counter += 1
        print(clues)

        self.window['-Clues-'].update(clues)


import enum
import logging
import os
import subprocess
import sys
import tempfile
from pathlib import Path
from typing import Iterable, List, Tuple, Union
from pprint import pprint
import commentjson

import config
import resume.sections as sections

def create_resume_(data: dict, output_filename: str):
    class SECTIONS(enum.Enum):
        none = enum.auto()
        achv = enum.auto()
        skills = enum.auto()
        experience = enum.auto()
        education = enum.auto()
        project = enum.auto()

    section_mapping = {
        "experience": SECTIONS.experience,
        "education": SECTIONS.education,
        "technical_skill": SECTIONS.skills,
        "project": SECTIONS.project,
        "achievement": SECTIONS.achv,
    }

    def get_order(data: dict):
        default_order = ["experience", "education", "technical_skill", "project", "achievement"]

        if data.get("meta"):
            if data["meta"].get("order"):
                order = data["meta"].get("order")
                return [section_mapping.get(item, SECTIONS.none) for item in order]

        return [section_mapping.get(item, SECTIONS.none) for item in default_order]

    def create_metadata() -> str:
        nonlocal data
        meta_text = ""
        metadata = sections.MetaData(data["basics"])
        metadata.set_colors(data.get("meta"))
        meta_text += metadata.to_latex()

        profile_text = "\n"
        profiles = sections.ProfileLinks(data["basics"]["profiles"])
        profile_text += profiles.to_latex()

        return meta_text + profile_text

    def get_section_text(section_type: SECTIONS) -> str:
        """get text for all sections except meta and profile"""

        def get_section_name():
            nonlocal section_type
            mapping = {
                SECTIONS.achv: "Achievements",
                SECTIONS.skills: "Technical Skills",
                SECTIONS.experience: "Experience",
                SECTIONS.education: "Education",
                SECTIONS.project: "Projects",
            }
            return mapping[section_type]

        nonlocal data
        section_begin = "\\section{" + get_section_name() + "}\n"
        section_text = ""

        if section_type is SECTIONS.achv:
            section_text += sections.Achievements(data["awards"]).to_latex()

        if section_type is SECTIONS.skills:
            section_text += sections.TechnicalSkills(data["skills"]).to_latex()

        if section_type is SECTIONS.experience:
            section_text += sections.Experience(data["work"]).to_latex()

        if section_type is SECTIONS.education:
            section_text += sections.Education(data["education"]).to_latex()

        if section_type is SECTIONS.project:
            section_text += sections.Projects(data["projects"]).to_latex()

        return section_begin + section_text + "\n"

    order = get_order(data)
    meta_text = create_metadata()

    content_text = ""
    for section_type in order:
        content_text += get_section_text(section_type)

    logging.info(f"generated text, moving files to compilation")
    compile_tex_file(content_text, meta_text, output_filename)

def compile_tex_file(content_text: str, meta_text: str, output_filename: str) -> None:
    """compile tex file with main.tex string passed into input with temporary directory"""

    template_dir = config.TEMPLATE_DIR
    logging.info(f"using template {template_dir.name}")

    with tempfile.TemporaryDirectory() as td:
        temp_path = Path(td)
        main_cwd = Path(os.getcwd())
        outdir_nm = output_filename

        with open(temp_path.joinpath("content.tex"), "w") as content_file:
            content_file.write(content_text)

        with open(temp_path.joinpath("meta.tex"), "w") as meta_file:
            meta_file.write(meta_text)

        def run_process(cmd: str, timeout=config.TIMEOUT):
            process = subprocess.run(
                cmd,
                shell=True,
                executable="/bin/bash",
                capture_output=True,
                text=True,
                check=True,
                timeout=timeout,
            )
            return process

        latemk_stdout = None
        error_raised = False
        try:
            move_process = run_process(
                f"""
                cp "{template_dir}/macros.tex" "{temp_path}/macros.tex"
                cp "{template_dir}/resume.tex" "{temp_path}/resume.tex"
                cp -R "./assets" "{temp_path}"
                mkdir -p out
                """
            )
            logging.info("moved files into temp directory")

            if config.KEEP_GENERATED_TEX:
                out_resume_path = f"{main_cwd}/out/resume"
                move_created_tex_files = run_process(
                    f"""
                    mkdir -p out/resume
                    cp "{template_dir}/macros.tex" "{out_resume_path}/macros.tex"
                    cp "{template_dir}/resume.tex" "{out_resume_path}/resume.tex"
                    cp "{temp_path}/content.tex" "{out_resume_path}/content.tex"
                    cp "{temp_path}/meta.tex" "{out_resume_path}/meta.tex"
                    """
                )

        except subprocess.TimeoutExpired as e:
            logging.error(f"Timeout during initial move\n" + str(e))

        except subprocess.CalledProcessError as e:
            logging.error(f"ProcessError for initial move:\n" + str(e))

        else:
            # no exception generated in move block, can move to compilation phase
            try:
                latexmk_process = run_process(
                    f"""
                    cd "{temp_path}"
                    latexmk -xelatex resume.tex
                    """,
                    timeout=config.LATEXMK_TIMEOUT,
                )

            except subprocess.TimeoutExpired as e:
                logging.error("Timeout during latexmk run:\n" + str(e))
                error_raised = True
                latemk_stdout = str(e.output.decode("utf-8"))

            except subprocess.CalledProcessError as e:
                logging.error("ProcessError for latexmk:\n" + str(e))
                error_raised = True

            else:  # get pdf file, as no exceptions raised
                get_pdf_file_proc = run_process(
                    f"""
                    cd "{temp_path}"
                    cp -R "resume.pdf" "{main_cwd}/out/{output_filename}.pdf"
                    """
                )
                logging.info(f"build and saved {output_filename}.pdf")

            finally:  # get latexmk log, in any case, evenif exceptions raised or not
                if config.KEEP_LOG_FILES:
                    try:
                        get_latex_log_process = run_process(
                            f"""
                            cd "{temp_path}"
                            cp -R "resume.log" "{main_cwd}/out/{output_filename}.log"
                            """
                        )

                        log_text = open(f"{main_cwd}/out/{output_filename}.log", "r").read()
                        if error_raised:
                            pprint("LaTeX Log\n" + log_text)

                    except subprocess.CalledProcessError as e:
                        logging.error(f"error during log_extraction process")

                    if latemk_stdout:
                        with open(f"{main_cwd}/out/latex_stdout.txt", "w") as stdout_file:
                            stdout_file.write(latemk_stdout)

def main():
    logging.basicConfig(
        level=config.LOG_LEVEL,
        format="%(levelname)s - %(asctime)s - %(message)s",
        datefmt="%d-%b-%y %H:%M:%S",
    )

    def parse_json(path: Path = "./resume.jsonc") -> dict:
        with open(path, "r") as f:
            data = commentjson.load(f)
        return data

    args = sys.argv
    if len(args) - 1 == 2:
        data = parse_json(Path(args[1]))
        output_filename = args[2]

    elif len(args) - 1 == 1:
        data = parse_json(Path(args[1]))
        output_filename = args[1].split("/")[1].split(".")[0]

    create_resume_(data, output_filename)

if __name__ == "__main__":
    main()


# coding=utf-8
import os
import logging
from bs4 import UnicodeDammit
from subliminal.api import io, defaultdict
from subliminal_patch.patch_provider_pool import PatchedProviderPool

logger = logging.getLogger(__name__)

def download_subtitles(subtitles, **kwargs):
    """Download :attr:`~subliminal.subtitle.Subtitle.content` of `subtitles`.

    All other parameters are passed onwards to the :class:`ProviderPool` constructor.

    :param subtitles: subtitles to download.
    :type subtitles: list of :class:`~subliminal.subtitle.Subtitle`

    """
    with PatchedProviderPool(**kwargs) as pool:
        for subtitle in subtitles:
            logger.info('Downloading subtitle %r', subtitle)
            pool.download_subtitle(subtitle)

def list_all_subtitles(videos, languages, **kwargs):
    """List all available subtitles.

    The `videos` must pass the `languages` check of :func:`check_video`.

    All other parameters are passed onwards to the :class:`ProviderPool` constructor.

    :param videos: videos to list subtitles for.
    :type videos: set of :class:`~subliminal.video.Video`
    :param languages: languages to search for.
    :type languages: set of :class:`~babelfish.language.Language`
    :return: found subtitles per video.
    :rtype: dict of :class:`~subliminal.video.Video` to list of :class:`~subliminal.subtitle.Subtitle`

    """
    listed_subtitles = defaultdict(list)

    # return immediatly if no video passed the checks
    if not videos:
        return listed_subtitles

    # list subtitles
    with PatchedProviderPool(**kwargs) as pool:
        for video in videos:
            logger.info('Listing subtitles for %r', video)
            subtitles = pool.list_subtitles(video, languages - video.subtitle_languages)
            listed_subtitles[video].extend(subtitles)
            logger.info('Found %d subtitle(s)', len(subtitles))

    return listed_subtitles

def get_subtitle_path(video_path, language=None, extension='.srt', forced_tag=False):
    """Get the subtitle path using the `video_path` and `language`.

    :param str video_path: path to the video.
    :param language: language of the subtitle to put in the path.
    :type language: :class:`~babelfish.language.Language`
    :param str extension: extension of the subtitle.
    :return: path of the subtitle.
    :rtype: str

    """
    subtitle_root = os.path.splitext(video_path)[0]

    if language:
        subtitle_root += '.' + str(language)

    if forced_tag:
        subtitle_root += ".forced"

    return subtitle_root + extension

def save_subtitles(video, subtitles, single=False, directory=None, encoding=None, encode_with=None, chmod=None,
                   forced_tag=False, path_decoder=None):
    """Save subtitles on filesystem.

    Subtitles are saved in the order of the list. If a subtitle with a language has already been saved, other subtitles
    with the same language are silently ignored.

    The extension used is `.lang.srt` by default or `.srt` is `single` is `True`, with `lang` being the IETF code for
    the :attr:`~subliminal.subtitle.Subtitle.language` of the subtitle.

    :param video: video of the subtitles.
    :type video: :class:`~subliminal.video.Video`
    :param subtitles: subtitles to save.
    :type subtitles: list of :class:`~subliminal.subtitle.Subtitle`
    :param bool single: save a single subtitle, default is to save one subtitle per language.
    :param str directory: path to directory where to save the subtitles, default is next to the video.
    :param str encoding: encoding in which to save the subtitles, default is to keep original encoding.
    :return: the saved subtitles
    :rtype: list of :class:`~subliminal.subtitle.Subtitle`

    patch: unicode path probems
    """
    saved_subtitles = []
    for subtitle in subtitles:
        # check content
        if subtitle.content is None:
            logger.error('Skipping subtitle %r: no content', subtitle)
            continue

        # check language
        if subtitle.language in set(s.language for s in saved_subtitles):
            logger.debug('Skipping subtitle %r: language already saved', subtitle)
            continue

        # create subtitle path
        subtitle_path = get_subtitle_path(video.name, None if single else subtitle.language, forced_tag=forced_tag)
        if directory is not None:
            subtitle_path = os.path.join(directory, os.path.split(subtitle_path)[1])

        if path_decoder:
            subtitle_path = path_decoder(subtitle_path)

        # force unicode
        subtitle_path = UnicodeDammit(subtitle_path).unicode_markup

        subtitle.storage_path = subtitle_path

        # save content as is or in the specified encoding
        logger.info('Saving %r to %r', subtitle, subtitle_path)
        has_encoder = callable(encode_with)

        if has_encoder:
            logger.info('Using encoder %s' % encode_with.__name__)

        # save normalized subtitle if encoder or no encoding is given
        if has_encoder or encoding is None:
            content = encode_with(subtitle.text) if has_encoder else subtitle.content
            with io.open(subtitle_path, 'wb') as f:
                f.write(content)

            # change chmod if requested
            if chmod:
                os.chmod(subtitle_path, chmod)

            if single:
                break
            continue

        # save subtitle if encoding given
        if encoding is not None:
            with io.open(subtitle_path, 'w', encoding=encoding) as f:
                f.write(subtitle.text)

        # change chmod if requested
        if chmod:
            os.chmod(subtitle_path, chmod)

        saved_subtitles.append(subtitle)

        # check single
        if single:
            break

    return saved_subtitles