import math
from random import choice
import pygame
import pygame.draw as p
import numpy as np
from random import randint

RED = (255, 0, 0)#блок задания цветовой гаммы мячей
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
GREEN = (0, 255, 0)
MAGENTA = (255, 0, 255)
CYAN = (0, 255, 255)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GRAY = (100, 100, 100)
COLORS = [RED, BLUE, YELLOW, GREEN, MAGENTA, CYAN]

class Ball: #класс обычных шаров
    def __init__(self, x: int, y: int, r0: int, r: int, color: tuple, dx: int, dy: int, j: int, t: int):
        '''
        задаем начальные параметры элемента класса:
        x, y - координаты элемента;
        ro - начальный радиус, r - текущий радиус;
        color - цвет, dx, dy - проекции скорости элеиента на оси;
        j - подтип элемента (0 - обычный мяч, 1 - мяч с изменяющимся радиусом, 2 - ядро,
        3 - картечь, 4 - осколки картечи)
        '''
        self.x = x
        self.y = y
        self.r0 = r0
        self.r = r0
        self.color = color
        self.dx = dx
        self.dy = dy
        self.j = j
        self.t = t

    def move_ball(self, screen: pygame.Surface, w: int ):
        '''
        реализует перемещение шаров
        '''
        self.x = self.x + self.dx
        self.y = self.y + self.dy
        if self.j == 1:
            self.r = int(self.r0 * np.cos(np.pi/45 * w))
        if (self.j >= 2) and (self.j <= 4):
            self.dy = self.dy + 1
            self.t = self.t + 1
        if (self.j != 5) or (w % 6 >= 3):
            p.circle(screen, self.color, (self.x, self.y), self.r)
    def ball_collision (self, s: list):
        '''
        реализует столкновения шаров между собой
        '''
        for i in s:
            if i != 0:
                if (self != i) and ((self.x-i.x) ** 2 + (self.y-i.y) ** 2 <= (self.r + i.r) ** 2) and \
                ((self.x-self.dx-i.x-i.dx) ** 2 + (self.y-self.dy-i.y-i.dy) ** 2) > (self.x-i.x) ** 2 + (self.y-i.y) ** 2:
                    self.dx = - self.dx
                    self.dy = - self.dy

    def wall_collision (self):
        '''
        реализует столкновения шаров со стенами
        '''
        if (self.x < self.r) and (self.dx < 0) :
            self.dx = randint(1, 3)
            self.dy = a[randint(0, len(a)-1)]
        if (self.x > 1000 - self.r) and (self.dx > 0) :
            self.dx = randint(-3, -1)
            self.dy = a[randint(0, len(a)-1)]
        if (self.y < self.r + 35) and (self.dy < 0) :
            self.dy = randint(1, 3)
            self.dx = a[randint(0, len(a) - 1)]
        if (self.y > 600 - self.r) and (self.dy > 0):
            self.dy = randint(-3, -1)
            self.dx = a[randint(0, len(a) - 1)]

class Border_Points:
    '''
    класс граничных точек танка, служащий для установления факта столкновения обЪекта с танком
    '''
    def __init__(self, x, y):
        self.x = x
        self.y = y

class Shell (Ball): #класc cнарядов, которым стреляет пушка танка
    def __init__(self, x: int, y: int, r0: int, r: int, color: tuple, dx: int, dy: int, j: int, t: int):
        '''
        задаем начальные параметры элемента класса
        '''
        Ball.__init__(self, x, y, r0, r, color, dx, dy, j, t)
    def critical_collision (self, g: list, s: list, k: int, v: int):
        '''
        реализует столкновения шара-ядра с мишенью
        '''
        collision = False
        for i in range(len(s)):
            if s[i] != 0:
                if ((self.x - s[i].x) ** 2 + (self.y - s[i].y) ** 2 <= (self.r + s[i].r) ** 2):
                    collision = True
                    if s[i].j == 0:
                        k = k + 1
                    else:
                        k = k + 3
                    s[i] = 0
        if collision == True:
            if self.j != 3:
                g[v] = 0
            else:
                g[v] = explosion_of_buckshot(self) #взрыв картечи
        return (g, s, k)

    def critical_wall_collision (self):
        '''
        реализует столкновения ядер со стенами
        '''
        if (self.x < self.r) and (self.dx < 0) or(self.x > 1000 - self.r) and (self.dx > 0) :
            self.dx = - self.dx // 2
        if (self.y < self.r + 35) and (self.dy < 0) or (self.y > 600 - self.r) and (self.dy > 0):
            self.dy = - self.dy // 2

class Buckshot (Shell): #класс снарядов картечного типа
    def __init__(self, x: int, y: int, r: int, color: tuple, dx: int, dy: int, children: list, j: int, t: int, explosion: bool):
        '''
        задаем начальные параметры элемента класса:
        x, y - координаты элемента;
        r - радиус;
        color - цвет, dx, dy - проекции скорости элемента на оси;
        children - список, в котором будут храниться дочерние снаряды - осколки картечи),
        t - время полета снаряда)
        '''
        self.x = x
        self.y = y
        self.r = r
        self.color = color
        self.dx = dx
        self.dy = dy
        self.children = children
        self.j = j
        self.t = t
        self.explosion = explosion

def collision_buckshot_with_other_shells(T: list, k: int):
    '''
    реализует столкновения картечного снаряда с ядрами
    '''
    for h in range(2):
        for i in range((T[k].m)):
            if ((T[h].shells[i].x - T[k].buckshot.x) ** 2 + (T[h].shells[i].y - \
            T[k].buckshot.y) ** 2 <= (T[h].shells[i].r + T[k].buckshot.r) ** 2):
                T[k].buckshot = explosion_of_buckshot(T[k].buckshot)
                T[h].shells[i] = 0
    return T

class Bombs (Ball):
    def __init__(self, x: int, y: int, r0: int, r: int, color: tuple, dx: int, dy: int, j: int, t: int):
        '''
        задаем начальные параметры элемента класса
        '''
        Ball.__init__(self, x, y, r0, r, color, dx, dy, j, t)
    def collision_bombs_with_tanks(self, location, number, lives):
        '''
        реализует попадание бомб в танки
        '''
        x = location - (-1) ** number * 15
        if (self.x - x) ** 2 + (self.y - 600) ** 2 <= (self.r ** 2 + 45 ** 2):
            self.r = 0
            lives = lives - 1
        return lives

class Tank:
    def __init__(self, location: int, dx: int, l: int, color: tuple, lives: int, press: list, alpha: float, shells: list, \
    buckshot: Buckshot, shooting_with_buckshot: bool,  m: int, border: list, number: int):
        '''
        задаем начальные параметры элемента класса:
        location - положение танка;
        dx - скорость перемещения танка
        l текущая длина пушка танка;
        color - цвет;
        lives - число оставшихся у танка жизней
        press - список логических переменных, описывающих характер движения танка
        alpha - угол наклона пушки в данный момент времени
        shells - список активных ядер, выпущенных танком
        buckshot - картечный снаряд танка
        shooting_with_buckshot - логическая переменная, устанавливающая тип снаряда
        m - число активных ядер танка
        border - граничные точки танка (нужны для установления факта попадания в танк
        number - номер танка
        '''
        self.location = location
        self.dx = dx
        self.l = l
        self.color = color
        self.lives = lives
        self.press = press
        self.alpha = alpha
        self.shells = shells
        self.buckshot = buckshot
        self.shooting_with_buckshot = shooting_with_buckshot
        self.m = m
        self.border = border
        self.number = number

    def move_tank (self, screen: pygame.Surface, w: int):
        '''
        реализует перемещение танка
        '''
        if self.number == 2: #перемещение танка игрока
            if (self.press[1] == True) and (self.location > 60):
                self.location = self.location - 3
            if (self.press[2] == True) and (self.location < 420):
                self.location = self.location + 3
        else:
            if (self.location < 580) or (self.location > 940): #перемещение танка противника
                self.dx = - self.dx
            self.location = self.location + self.dx
        if (self.press[0] == True) and (self.l <= 120): #увеличение длины пушки
            self.l = self.l + 2
        if (self.press[3] == True) and (self.alpha < np.pi / 3): #изменение угла наклона пушки
            self.alpha = self.alpha + np.pi / 180
        if (self.press[4] == True) and (self.alpha > 0):
            self.alpha = self.alpha - np.pi / 180

        self.border[0] = Border_Points(self.location - (-1) ** self.number * 60, 560) #граничные точки танка
        self.border[1] = Border_Points(self.location - (-1) ** self.number * 30, 600)
        self.border[2] = Border_Points(self.location, 600)
        self.border[3] = Border_Points(self.location + (-1) ** self.number * 30, 560)
        self.border[4] = Border_Points(self.location, 560)
        self.border[5] = Border_Points(self.location, 530)
        self.border[6] = Border_Points(self.location - (-1) ** self.number * 30, 530)
        self.border[7] = Border_Points(self.location - (-1) ** self.number * 30, 560)
        for i in range(8):
            self.border[i + 8] = Border_Points((self.border[i].x + self.border[(i + 1) % 8].x) // 2, (self.border[i].y + self.border[i + 1].y) // 2)

        pygame.draw.polygon(screen, self.color, [[self.location, 560], \
        [self.location + (-1) ** self.number * int(- 20 * np.sin(self.alpha)), int(- 20 * np.cos(self.alpha) + 560)], \
        [self.location + (-1) ** self.number * int(self.l * np.cos(self.alpha) - 20 * np.sin(self.alpha)), int(- self.l * np.sin(self.alpha) - 20 * np.cos(self.alpha) + 560)], \
        [self.location + (-1) ** self.number * int(self.l * np.cos(self.alpha)), int(- self.l * np.sin(self.alpha) + 560)]]) #рисуем пушку
        pygame.draw.polygon(screen, GREEN, [[self.location - (-1) ** self.number * 60, 560], [self.location - (-1) ** self.number * 30, 600],\
        [self.location, 600], [self.location + (-1) ** self.number * 30, 560], [self.location, 560], [self.location, 530],\
        [self.location - (-1) ** self.number * 30, 530], [self.location - (-1) ** self.number * 30, 560]])#рисуем корпус танка

def updates (shells, m):
        '''
        обновляет список уцелевших ядер
        '''
        i = m - 1
        while (i >= 0):
            if (shells[i] == 0) or (shells[i].t > 75):
                del(shells[i])
                shells.append(0)
                m = m - 1
            i = i - 1
        return (shells, m)

def update_bombs(bombs: list):
    '''
    обновляет список бомб
    '''
    i = len(bombs) - 1
    while (i >= 0):
        if bombs[i].r == 0:
            del(bombs[i])
        i = i - 1
    return (bombs)

def create_label(label, size: int, a: int, b: int, border: bool, fill: bool):
    '''
    создает надпись на заданной поверхности
    label - надпись
    size - размер шрифта
    a, b - размеры поверхности
    border - наличие рамки у пов-сти (логическая переменная)
    fill - заливка пов-сти (логическая переменная)
    '''
    f = pygame.font.SysFont(None, size)
    text = f.render(label, False, BLACK)
    surf = pygame.Surface((a, b), pygame.SRCALPHA)
    if border == True:
        pygame.draw.rect(surf, BLACK, (0, 0, a, b), 1)
    if fill == True:
        pygame.draw.rect(surf, GREEN, (0, 0, a, b), 0)
    surf.blit(text, (0, 0))
    return surf

def starting_parametres(location: int, l: int, alpha: float, number: int):
        '''
        вспомогательная функция, устанавливающая начальные параметры любого снаряда
        '''
        d = [0]*4
        d[0] = int(location + (-1) ** number * l * np.cos(alpha))
        d[1] = int(- l * np.sin(alpha) - 10 * np.cos(alpha) + 560)
        d[2] = int(10 * l / 50 * np.cos(alpha) * (-1) ** number)
        d[3] = int(- 10 * (l / 50) * np.sin(alpha))
        return d

def create_shell(shells, location: int, m: int, l: int, alpha: float, number: int):
    '''
    создаем ядро, которым стреляет танк в данный момент
    '''
    if m < len(shells): #ограничение на число ядер, одновременно находящихся на экране
        d = starting_parametres (location, l, alpha, number)
        shells[m] = Shell(d[0], d[1], 10, 10, BLACK, d[2], d[3], 2, 0) #создание нового ядра
        m = m + 1
    return shells, m

def create_buckshot (buckshot: Buckshot, location: int, l: int, alpha: float, number: int):
    '''
    создаем картечный снаряд, которым стреляет танк в данный момент
    '''
    d = starting_parametres (location, l, alpha, number)
    buckshot = Buckshot(d[0], d[1], 10, GRAY, d[2], d[3], [0]*7, 3, 0, False) #создание нового ядра
    return buckshot

def collision_buckshot_with_wall(buckshot: Buckshot):
    '''
    реализуем столкновение картечного снаряда со стенами, в результате
    которого происходит разрыв снаряда
    '''
    if (buckshot.x < buckshot.r) and (buckshot.dx < 0) or(buckshot.x > 1000 - buckshot.r) and (buckshot.dx > 0)\
    (buckshot.y < buckshot.r + 35) and (buckshot.dy < 0) or (buckshot.y > 600 - buckshot.r) and (buckshot.dy > 0):
        buckshot = explosion_of_buckshot(buckshot)
    return buckshot
def shout (Tank: Tank):
    '''
    реализует выстрел танка
    '''
    if Tank.shooting_with_buckshot == False:
        Tank.shells, Tank.m = create_shell(Tank.shells, Tank.location, Tank.m, Tank.l, Tank.alpha, Tank.number)
    else:
        if Tank.buckshot == 0:
            Tank.buckshot = create_buckshot (Tank.buckshot, Tank.location, Tank.l, Tank.alpha, Tank.number)
    return Tank

def shell_collisions (T: list):
    '''
    реализует столкновения ядер между собой
    '''
    for i in range(T[0].m):
        for k in range (T[1].m):
            if T[1].shells[k] !=  0:
                if ((T[0].shells[i].x - T[1].shells[k].x) ** 2 + (T[0].shells[i].y - \
                T[1].shells[k].y) ** 2 <= (T[0].shells[i].r + T[1].shells[k].r) ** 2):
                    T[0].shells[i] = 0
                    T[1].shells[k] = 0
                    break
    return T

def explosion_of_buckshot(buckshot: Buckshot):
    '''
    реализует взрыв картечного снаряда
    '''
    for i in range(7):
        buckshot.children[i] = Shell(buckshot.x, buckshot.y, 4, 4, GRAY, randint(buckshot.dx - 10, buckshot.dx + 10),\
        randint(buckshot.dy - 10, buckshot.dy + 10), 4, buckshot.t)
    buckshot.explosion = True
    return buckshot

def collision_with_barrier(object):
    '''
    реализует столкновения с барьером в центре игрового поля
    '''
    if (object != 0) and ((object.x - 500) ** 2 + (object.y - 600) ** 2 < 60 ** 2) and \
    ((object.x + object.dx - 500) ** 2 + (object.y + object.dy - 600) ** 2 < (object.x - 500) ** 2 + (object.y - 600) ** 2):
        object.dx = - object.dx
        object.dy = - object.dy
        if object.j == 3:
            object = explosion_of_buckshot(object)
    return object
def hit(points: list, shell: Shell, lives: int, stage: int):
    '''
    Реализует случай попадания снаряда в танк. Если это первый этап игры (stage = 1) либо скорость ядра невелика, оно
    просто отскакивает от танка, иначе танк поврежден, ядро (shell) исчезает с экрана.
    Point - список граничных точек танка
    '''
    for i in points:
        if (shell.x - i.x) ** 2 + (shell.y - i.y) ** 2 <= (shell.r ** 2):
            if (shell.dx ** 2 + shell.dy ** 2) >= 20 and (stage == 2):
                shell = 0
                lives = lives - 1
            else:
                shell.dx = - shell.dx // 2
                shell.dy = - shell.dy // 2
            break
    return shell, lives

w = 0 #"счетчик времени"
s = [0] * 6 #создание списка, элементами которого будут мячи
bombs = [] #создание списка, элементами которого будут бомбы
a = list(range(-3, -1)) + list(range(1, 3))#задан диапазон значений скоростей мячей

border = [0] * 16 #списки граничных точек
border1 = [0] * 16
T34 = Tank(60, 0, 40, GREEN, 3, [False] * 5, 0, [0] * 4, 0, False, 0, border, 2) #создаем наш танк
Tiger = Tank(940, - 2, 40, GREEN, 3, [False] * 5, 0, [0] * 4, 0, False, 0, border1, 1) #создаем танк противника (Тигр)
T = [0, 0] #создан список из элементов класса Tank
T[0] = T34
T[1] = Tiger
pygame.init()
pygame.font.init()

FPS = 30
screen = pygame.display.set_mode((1000, 600))
screen.fill(WHITE)

pygame.display.update()
clock = pygame.time.Clock()
finished = False #логическая переменная, отвечающая за закрытие программы

label = 'Перезарядка'
recharge = create_label(label, 40, 200, 30, True, False)#создана пов-сть с информацией о факте перезарядки орудия

Restart = create_label('Restart', 40, 100, 30, False, True) #создана пов-сть - кнопка рестарта

text = [0]*9 #инструкция для игрока
table  = [0]*9
text[0] = 'На первом этапе игры Вам необходимо сбить'
text[1] = 'как можно больше шаров - это даст очки жизни Вашему танку.'
text[2] = 'Снаряды учебные - вражескому танку вреда они не наносят.'
text[3] = 'Чтобы сбивать больше снарядов, используйте картечь'
text[4] = '(переключение типа снаряда осуществляется клавишой Shift)'
text[5] = 'На втором этапе игры (когда шары исчезнут)'
text[6] = 'Вам предстоит дуэль с вражеским танком.'
text[7] = '(Да, картечь против него не поможет, поэтому эта функция отключена).'
text[8] = '                     Удачи!'
for i in range(9):
    table[i] = create_label(text[i], 40, 1000, 60, False, False)

screen.fill(WHITE)
w = 0
for i in range(9):
    screen.blit(table[i], (5, 30 + 60 * i))
pygame.display.update()

while (w <= FPS * 4) and (not finished): #игрок читает инструкцию к игре
    clock.tick(FPS)
    w = w + 1

pygame.display.update()
while (w <= FPS * 60) and (not finished) and (T[0].lives > 0): #основной цикл первой части игры
    clock.tick(FPS)

    for i in range(5):
        if s[i] == 0: #блок создания нового мяча
            s[i] = Ball(randint(100, 900), randint(100, 500),  randint(10, 50), 0,
            COLORS[randint(0, 5)], a[randint(0, len(a)-1)], a[randint(0, len(a)-1)], 0, 0)

    if (w > 150) and (s[5] == 0):#блок создания особого мяча
        s[5] = Ball(randint(100, 900), randint(100, 500),  randint(30, 50), 0,
        COLORS[randint(0, 5)], a[randint(0, len(a)-1)], a[randint(0, len(a)-1)], 1, 0)

    if w % 20 == 0: #блок создания бомб
        bombs.append(Bombs(randint(5, 495), 5, 5, 5, RED, 0, randint(5, 10), 5, 0))

    for i in s: #блок реализации перемещения мячей
        if i != 0:
            i.move_ball(screen, w)
            i.ball_collision(s)
            i.wall_collision()

    for i in bombs: #блок реализации перемещения бомб
        i.move_ball(screen, w)

    for event in pygame.event.get():#блок обработки выполненных игроком действий
        if event.type == pygame.QUIT:#выхода из игры
            finished = True
            break
        elif event.type == pygame.MOUSEBUTTONDOWN:#нажатие на кнопку мыши
            x = pygame.mouse.get_pos()[0] #определяем координаты положения мыши
            y = pygame.mouse.get_pos()[1]
            if (x >= 900) and (y <= 30):
                for i in range (2):
                    T[i].lives = 3
                    T[i].shells = [0]*4
                    T[i].buckshot = 0
                    T[i].m = 0
                    w = 0
        elif event.type == pygame.KEYDOWN: #нажатие на клавиши
            if event.key == pygame.K_SPACE:
                T[0].press[0] = True
            if event.key == pygame.K_LSHIFT:
                T[0].shooting_with_buckshot = not (T[0].shooting_with_buckshot)
            if event.key == pygame.K_LEFT:
                T[0].press[1] = True
            if event.key == pygame.K_RIGHT:
                T[0].press[2] = True
            if event.key == pygame.K_UP:
                T[0].press[3] = True
            if event.key == pygame.K_DOWN:
                T[0].press[4] = True
        elif event.type == pygame.KEYUP: #отпускание клавиш
            if event.key == pygame.K_SPACE:
                T[0] = shout(T[0])
                T[0].l = 50
                T[0].press[0] = False
            if event.key == pygame.K_LEFT:
                T[0].press[1] = False
            if event.key == pygame.K_RIGHT:
                T[0].press[2] = False
            if event.key == pygame.K_UP:
                T[0].press[3] = False
            if event.key == pygame.K_DOWN:
                T[0].press[4] = False

    #блок обработки выполненных противником действий
    T[1].press[0] = True
    time = np.sin(np.pi/60*w)
    if time > 0:
        T[1].press[3] = True
    elif time < 0:
        T[1].press[4] = True
    if w % 60 == 0:
        T[1].press[3] = False
        T[1].press[4] = False
    if w % 30 == 29:
        T[1] = shout(T[1])
        T[1].l = 50
        T[1].press[0] = False

    for k in range(2): #блок реализации перемещения танков их их столкновения с бомбами
        T[k].move_tank(screen, w)
        for i in range(len(bombs)):
            T[k].lives = bombs[i].collision_bombs_with_tanks(T[k].location, T[k].number, T[k].lives)

    bombs = update_bombs(bombs) #обновляем список бомб

    if T[0].m >= len(T[0].shells): #выводим на экран предупреждение - пушка игрока перезаряжается и стрелять не может
        screen.blit(recharge, (300, 0))

    for k in range (2):
        for v in range(T[k].m): #блок реализации перемещения ядер и их столкновений с мячами
            T[k].shells[v].move_ball(screen, w)
            T[k].shells, s, T[k].lives = T[k].shells[v].critical_collision(T[k].shells, s, T[k].lives, v)
        T[k].shells, T[k].m = updates(T[k].shells, T[k].m)

    T = shell_collisions (T) #реализуем столкновения ядер между собой
    for k in range (2):
        T[k].shells, T[k].m = updates(T[k].shells, T[k].m)

    for i in range(4): #реализуем столкновение ядер с танком и с барьером
        if T[1].shells[i] != 0:
            T[1].shells[i], T[0].lives = hit (T[0].border, T[1].shells[i], T[0].lives, 1)
            T[1].shells[i] = collision_with_barrier(T[1].shells[i])
        if T[0].shells[i] != 0:
            T[0].shells[i], T[1].lives = hit (T[1].border, T[0].shells[i], T[1].lives, 1)
            T[0].shells[i] = collision_with_barrier(T[0].shells[i])

    for k in range (2):
        for i in range (T[k].m): #блок реализации столкновений ядер со стенами
            T[k].shells[i].critical_wall_collision()
        T[k].shells, T[k].m = updates(T[k].shells, T[k].m)
        if T[k].buckshot != 0: #блок реализации поведения снарядов картечного типа
            if T[k].buckshot.explosion == False: #еще неразорвавшегося снаряда
                T[k].buckshot.move_ball(screen, w)
                T[k].buckshot = collision_with_barrier(T[k].buckshot)
                T[k].buckshot = collision_buckshot_with_wall(T[k].buckshot)
                y, s, T[k].lives = T[k].buckshot.critical_collision([T[k].buckshot], s, T[k].lives, 0)
                T[k].buckshot = y[0]
                T = collision_buckshot_with_other_shells(T, k)
                if T[k].buckshot.t == 30:
                    T[k].buckshot = explosion_of_buckshot(T[k].buckshot)
            else: #разорвавшегося снаряда
                T[k].buckshot.t = T[k].buckshot.t + 1
                for i in range(7):
                    if T[k].buckshot.children[i] != 0:
                        T[k].buckshot.children[i].move_ball(screen, w)
                        T[k].buckshot.children[i] = collision_with_barrier(T[k].buckshot.children[i])
                        T[k].buckshot.children[i].critical_wall_collision()
                        T[k].buckshot.children, s, T[k].lives = \
                        T[k].buckshot.children[i].critical_collision(T[k].buckshot.children, s, T[k].lives, i)
            if T[k].buckshot.t == 60:
                T[k].buckshot = 0

    screen.blit(Restart, (900, 0)) #рисуем кнопку рестарта
    Your_lives = create_label('Your lives - ' + str(T[0].lives), 30, 200, 30, False, False)
    #отображаем текущее кол-во жизней у игрока на экране
    screen.blit(Your_lives,(100, 0))
    Enemy_lives = create_label('Enemy lives - ' + str(T[1].lives), 30, 200, 30, False, False)
    #отображаем текущее кол-во жизней у игрока на экране
    screen.blit(Enemy_lives,(700, 0))

    pygame.draw.line(screen, BLACK, (0, 30), (1000, 30), 5) #рисуем верхнюю грань обл. движения шаров
    pygame.draw.circle(screen, (100, 100, 100), (500, 600), 80) #рисуем барьер

    w = w + 1

    pygame.display.update()
    screen.fill(WHITE)

T[0].shooting_with_buckshot = False
lives = [0]*2
for k in range(2):
    lives[k] = T[k].lives #сохраняем промежуточные результаты

while (not finished) and (T[0].lives > 0) and (T[1].lives > 0) and (w <= FPS * 120): #основной цикл второй части игры
    clock.tick(FPS)

    if w % 20 == 0: #блок создания бомб
        bombs.append(Bombs(randint(5, 495), 5, 5, 5, RED, 0, randint(5, 10), 5, 0))

    for i in bombs: #блок реализации перемещения бомб
        i.move_ball(screen, w)

    for event in pygame.event.get():#блок обработки выполненных игроком действий
        if event.type == pygame.QUIT:#выхода из игры
            finished = True
            break
        elif event.type == pygame.MOUSEBUTTONDOWN:#нажатие на кнопку мыши
            x = pygame.mouse.get_pos()[0] #определяем координаты положения мыши
            y = pygame.mouse.get_pos()[1]
            if (x >= 900) and (y <= 30):
                for k in range(2):
                    T[k].lives = lives[k]
                    T[k].shells = [0]*4
                    T[k].buckshot = 0
                    T[k].m = 0
                w = FPS * 60
        elif event.type == pygame.KEYDOWN: #оьработка нажатий на клавиши
            if event.key == pygame.K_SPACE:
                T[0].press[0] = True
            if event.key == pygame.K_LEFT:
                T[0].press[1] = True
            if event.key == pygame.K_RIGHT:
                T[0].press[2] = True
            if event.key == pygame.K_UP:
                T[0].press[3] = True
            if event.key == pygame.K_DOWN:
                T[0].press[4] = True
        elif event.type == pygame.KEYUP: #обработка отпускания клавиш
            if event.key == pygame.K_SPACE:
                T[0] = shout(T[0])
                T[0].l = 50
                T[0].press[0] = False
            if event.key == pygame.K_LEFT:
                T[0].press[1] = False
            if event.key == pygame.K_RIGHT:
                T[0].press[2] = False
            if event.key == pygame.K_UP:
                T[0].press[3] = False
            if event.key == pygame.K_DOWN:
                T[0].press[4] = False

    #блок обработки выполненных противником действий
    T[1].press[0] = True
    time = np.sin(np.pi/60*w)
    if time > 0:
        T[1].press[3] = True
    elif time < 0:
        T[1].press[4] = True
    if w % 60 == 0:
        T[1].press[3] = False
        T[1].press[4] = False
    if w % 30 == 29:
        T[1] = shout(T[1])
        T[1].l = 50
        T[1].press[0] = False

    for k in range(2): #блок реализации перемещения танков
        T[k].move_tank(screen, w)
        for i in range(len(bombs)):
            T[k].lives = bombs[i].collision_bombs_with_tanks(T[k].location, T[k].number, T[k].lives)

    bombs = update_bombs(bombs) #обновляем список бомб

    if T[0].m >= len(T[0].shells): #выводим на экран предупреждение - пушка игрока перезаряжается и стрелять не может
        screen.blit(recharge, (300, 0))

    screen.blit(Restart, (900, 0)) #рисуем кнопку рестарта
    Your_lives = create_label('Your lives - ' + str(T[0].lives), 30, 200, 30, False, False)
    #отображаем текущее кол-во жизней у игрока на экране
    screen.blit(Your_lives,(100, 0))
    Enemy_lives = create_label('Enemy lives - ' + str(T[1].lives), 30, 200, 30, False, False)
    #отображаем текущее кол-во жизней у противника на экране
    screen.blit(Enemy_lives,(700, 0))

    for k in range (2):
        for v in range(T[k].m): #блок реализации перемещения ядер
            T[k].shells[v].move_ball(screen, w)

    T = shell_collisions (T) #реализуем столкновения ядер между собой
    for k in range (2):
        T[k].shells, T[k].m = updates(T[k].shells, T[k].m)

    for i in range(4): #реализуем попадание в танк
        if T[1].shells[i] != 0:
            T[1].shells[i], T[0].lives = hit (T[0].border, T[1].shells[i], T[0].lives, 2)
        if T[0].shells[i] != 0:
            T[0].shells[i], T[1].lives = hit (T[1].border, T[0].shells[i], T[1].lives, 2)

    for k in range (2): #обновляет список ядер
        T[k].shells, T[k].m = updates(T[k].shells, T[k].m)

    for k in range(2): #реализуем столкновения ядер с барьером
        for i in range(4):
            T[k].shells[i] = collision_with_barrier(T[k].shells[i])

    for k in range (2):
        for i in range (T[k].m): #блок реализации столкновений ядер со стенами
            T[k].shells[i].critical_wall_collision()
        T[k].shells, T[k].m = updates(T[k].shells, T[k].m)

    pygame.draw.line(screen, BLACK, (0, 30), (1000, 30), 5) #рисуем верхнюю грань обл. движения шаров
    pygame.draw.circle(screen, (100, 100, 100), (500, 600), 60) #рисуем барьер
    w = w + 1
    pygame.display.update()
    screen.fill(WHITE)

if (T[0].lives <= 0) or (finished == True): #блок вывода результата игры на экран
    score = 'ПОРАЖЕНИЕ'
elif T[1].lives <= 0:
    score = '  ПОБЕДА'
else:
    score = '  НИЧЬЯ'

result = create_label(score, 80, 400, 80, False, False)
screen.blit(result, (300, 260))
pygame.display.update()

while not finished:
    clock.tick(FPS)
    for event in pygame.event.get():#блок обработки выполненных игроком действий
        if (event.type == pygame.QUIT) or (event.type == pygame.MOUSEBUTTONDOWN):#выхода из игры
            finished = True

pygame.quit()


#coding:utf-8
import requests
import unittest

class GetEventListTest(object):
    '''查询发布会接口测试'''
    # def setUp(self):
    #     self.url="http://127.0.0.1:8000/api/get_event_list/"
    def __init__(self):
        self.url = "http://127.0.0.1:8000/api/get_event_list/"
    def test_get_event_null(self):
        '''发布会id为空'''
        # print '---------'
        r=requests.get(self.url,params={'eid':''})
        result=r.json()
        print(result)
        # print(result['status'])
        # print(result['message'])
    def test_get_event_error(self):
        '''发布会id不存在'''
        r=requests.get(self.url,params={'eid':'901'})
        result=r.json()
        print(result)
        # print(result['status'])
        # print(result['message'])

    def test_get_event_success(self):
        '''发布会id为1，查询成功'''
        r=requests.get(self.url,params={'eid':'1'})
        result=r.json()
        print(result)
        # print(result['status'])
        # print(result['message'])
        # print(result['data']['name'])
        # print(result['data']['address'])
        # print(result['data']['start_time'])

if __name__ == '__main__':
    test=GetEventListTest()
    test.test_get_event_null()
    test.test_get_event_error()
    test.test_get_event_success()


# -*- coding: utf-8 -*-
"""
Created on Fri Dec  9 22:35:50 2022

@author: RJ
"""

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

def read_file(fname):
    """This function is used to read the file and return the transpose the
    file and data."""

    data = pd.read_excel(fname)
    dtranspose = data.set_index('Country Name').transpose()
    return data, dtranspose

# These two lists are created for storing the selected countries for two plots.
coun_list1 = ['Peru', 'China', 'Brazil', 'Italy', 'Zimbabwe', 'Japan']
coun_list2 = ['Iraq', 'Belgium', 'Mexico', 'China', 'Nepal', 'Indonesia']

def filter_bar_data(data):
    """This Function is created to filter the datas with the years
    and country names for bar plots"""

    data = data[['Country Name', 'Indicator Name',
                 '1990', '2000', '1994', '2013', '2019', '2020']]
    data = data[(data["Country Name"] == "Peru") |
                (data["Country Name"] == "China") |
                (data["Country Name"] == "Brazil") |
                (data["Country Name"] == "Italy") |
                (data["Country Name"] == "Zimbabwe") |
                (data["Country Name"] == "Japan")]
    return data

def filter_line_plot(data):
    """This Function is created to filter the datas with the years and country
    names for line plots """

    data = data[['Country Name', 'Indicator Name',
                 '1990', '1994', '2000', '2013', '2019']]
    data = data[(data["Country Name"] == "Iraq") |
                (data["Country Name"] == "Belgium") |
                (data["Country Name"] == "Mexico") |
                (data["Country Name"] == "China") |
                (data["Country Name"] == "Nepal") |
                (data["Country Name"] == "Indonesia")]
    return data

"""
This barplot function is used to plot mutiple bar graph with Country Name
and % of Urban Population and land area on x and y axis respectively
comparing with three different years. """

def barplot(data, label):
    plt.figure(figsize=(26, 16))
    ax = plt.subplot(1, 1, 1)
    x = np.arange(6)
    width = 0.2

    bar1 = ax.bar(x, data["1990"], width, label=1990)
    bar2 = ax.bar(x+width, data["1994"], width, label=1994)
    bar3 = ax.bar(x+width*2, data["2000"], width, label=2000)

    ax.set_xlabel("Country Names", fontsize=40)
    ax.set_title(label, fontsize=40)
    ax.set_xticks(x, coun_list1, fontsize=30, rotation=90)
    ax.legend(fontsize=30)

    ax.bar_label(bar1, padding=2, rotation=90, fontsize=12)
    ax.bar_label(bar2, padding=2, rotation=90, fontsize=12)
    ax.bar_label(bar3, padding=2, rotation=90, fontsize=12)
    plt.savefig(label+"barplot.png", bbox_inches="tight")
    plt.show()

"""This line_plot function is used to plot line graph with Country Name
CO2 Emission and Total Population on x and y axis respectively
comparing with three different years."""

def line_plot(data, label):
    plt.figure(figsize=(20, 18))
    dd = data.set_index('Country Name')
    tran = dd.transpose()
    tran = tran.drop(index=['Indicator Name'])
    for i in range(len(coun_list2)):
        plt.plot(tran.index, tran[coun_list2[i]], label=coun_list2[i])

    plt.title(label, size=25)
    plt.xlabel("Years", size=25)
    plt.xticks(rotation=90)
    plt.legend(fontsize=18)
    plt.savefig(label+"lineplot.png", bbox_inches="tight")
    plt.show()

""" Here we read the files which used for multiple bar graph into proper
variables and filter them using the function filter_bar_data"""

forest_data, forest_data1 = read_file("Forest Area.xls")
forest_data = filter_bar_data(forest_data)
Urban_data, Urban_data1 = read_file("Urban population.xls")
Urban_data = filter_bar_data(Urban_data)

CO2_data, CO2_data1 = read_file("CO2 emission.xls")
CO2_data = filter_line_plot(CO2_data)
Population_data, Population_data1 = read_file("Total Population.xls")
Population_data = filter_line_plot(Population_data)

barplot(forest_data, "Forest Area")
barplot(Urban_data, 'Urban Population')

line_plot(CO2_data, "CO2 Emission (KT)")
line_plot(Population_data, "Total Population")


import sqlite3
import re
import os
import traceback
import json
import sys
import hashlib

DATABASE_FILENAME = 'C:\Program Files (x86)\Steam\steamapps\common\My Time At Portia\Portia_Data\StreamingAssets\CccData\LocalDb.bytes'

CACHED_PROPS = None
CACHED_GIFTS = None
CACHED_FOOD_MENU = None
CACHED_DATE_DIALOG = None
CACHED_GIFT_TAGS = None
CACHED_GIFT_TAGS_NOTRAN = None
CACHED_RECYCLE_TAGS = None

CACHED_QUERIES = {}

def md5_hash(filename):
    hash_md5 = hashlib.md5()
    with open(filename, "rb") as f:
        for chunk in iter(lambda: f.read(4096), b""):
            hash_md5.update(chunk)
    return hash_md5.hexdigest()

def load_cache(current_hash):
    global CACHED_QUERIES
    try:
        if os.path.isfile('cached_queries.json'):
            with open('cached_queries.json') as f:
                CACHED_QUERIES = json.load(f)
            previous_hash = CACHED_QUERIES['hash']
            if current_hash != previous_hash:
                print('LOCALDB CHANGED, DELETING CACHE. THIS NEXT RUN WILL BE SLOW BECAUSE THE CACHE NEEDS TO BE REPOPULATED.')
                CACHED_QUERIES = {}
    except Exception:
        print('Failed to load cache file, creating new cache. Error:\n{}'.format(traceback.format_exc()))
        CACHED_QUERIES = {}

def write_cache(current_hash):
    print('Saving query cache, DO NOT EXIT')
    global CACHED_QUERIES
    CACHED_QUERIES['hash'] = current_hash
    with open('cached_queries.json', 'w') as f:
        json.dump(CACHED_QUERIES, f)
    print('Finished saving query cache')

def do_query(query, connection):
    global CACHED_QUERIES
    if query not in CACHED_QUERIES:
        cursor = connection.cursor()
        cursor.execute(query)
        CACHED_QUERIES[query] = []
        for result in cursor:
            CACHED_QUERIES[query].append(result)
    return CACHED_QUERIES[query]

def props_gift_lookup(gift_tagid, connection, gift_id, like_type=None):
    global CACHED_GIFT_TAGS_NOTRAN
    global CACHED_PROPS

    if like_type is not None:
        query = 'SELECT Favor_{} from Gift where Gift_ID="{}"'.format(like_type, gift_id)
        results = do_query(query, connection)
        assert len(results) == 1

        if CACHED_GIFT_TAGS_NOTRAN is None:
            CACHED_GIFT_TAGS_NOTRAN = find_associations('Props_total_table', 'Tag_List', ',',
                                                        ('props_name', None), {}, connection, ignore_multipliers=True)
            CACHED_GIFT_TAGS_NOTRAN = {x: y.split('\n') for x, y in CACHED_GIFT_TAGS_NOTRAN[0]}

        base_value, exceptions_str = results[0]['favor_{}'.format(like_type.lower())].split('|')
        exceptions = {}
        if exceptions_str.strip() != '':
            for exception in exceptions_str.split('$'):
                tag, value = exception.split('_')
                exceptions[tag] = value

    gift_tagid = gift_tagid.split(';')[0]

    if CACHED_PROPS is None:
        CACHED_PROPS = do_query('SELECT props_name, gift_tagid FROM props_total_table', connection)
    all_gifts = []
    for result in CACHED_PROPS:
        if str(gift_tagid) in result['gift_tagid'].split(','):
            prop_name = result['props_name']
            if like_type is not None:
                special_value = None
                for tag, value in exceptions.items():
                    if prop_name in CACHED_GIFT_TAGS_NOTRAN.get(tag, []):
                        special_value = value
                if special_value is None:
                    actual_value = base_value
                else:
                    actual_value = special_value
                all_gifts.append(do_lookup('Translation_hint', prop_name, '<str>id', 'English',
                                           None, connection, {}).strip() + ' ({})'.format(actual_value))
            else:
                all_gifts.append(do_lookup('Translation_hint', prop_name, '<str>id', 'English',
                                           None, connection, {}).strip())

    if len(all_gifts) == 0:
        return 'No gifts for Gift_TagID {}'.format(gift_tagid)
    return ', '.join(all_gifts)

def find_associations(table, column, split_char, name_mapping, tag_names, connection, ignore_multipliers=False):
    column = column.lower()
    name_column = name_mapping[0].lower()
    options = name_mapping[2] if len(name_mapping) > 2 and name_mapping[2] is not None else {}

    all_results = do_query('SELECT {}, {} FROM {}'.format(name_column, column, table), connection)

    all_values = []
    for result in all_results:
        for value in result[column].split(split_char):
            if value not in all_values:
                all_values.append(value)
    mappings = {}
    cached_lookups = {}
    for value in all_values:
        for result in all_results:
            if value in result[column].split(split_char):
                result_conversion = name_mapping[1]
                looked_up_value = result[name_column]
                if looked_up_value not in cached_lookups:
                    if result_conversion is not None:
                        if callable(result_conversion):
                            looked_up_value = result_conversion(result[name_column], connection)
                        elif isinstance(result_conversion, tuple):
                            looked_up_value = do_lookup(
                                result_conversion[1], looked_up_value, result_conversion[0], result_conversion[2], result_conversion[3], connection, options)
                        elif isinstance(result_conversion, list):
                            for conversion in result_conversion:
                                looked_up_value = do_lookup(conversion[1], looked_up_value,
                                                            conversion[0], conversion[2], conversion[3], connection, options)
                                if 'returned no results' not in looked_up_value:
                                    break
                        else:
                            raise Exception('Invalid value of result_conversion: {}'.format(result_conversion))
                    cached_lookups[result[name_column]] = looked_up_value
                if value not in mappings:
                    mappings[value] = []
                mappings[value].append(cached_lookups[result[name_column]])
    extracted = []
    all_ints = True
    for key in mappings.keys():
        if key == '':
            key = '<empty>'
        try:
            int(key)
        except Exception:
            all_ints = False
    for key, values in mappings.items():
        new_values = {}
        for value in values:
            if value not in new_values:
                new_values[value] = 1
            else:
                new_values[value] += 1
        quantified_values = []
        for value, quantity in new_values.items():
            if value == '':
                value = '(empty)'
            if quantity == 1 or ignore_multipliers:
                quantified_values.append(value)
            else:
                quantified_values.append('{} x{}'.format(value, quantity))
        if all_ints:
            key = int(key)
        extracted.append((key, '\n'.join(sorted(quantified_values, key=lambda x: x.lower()))))
    if all_ints:
        extracted.sort()
        extracted = [(tag_names.get(x, x), y) for x, y in extracted]
        extracted = [(str(x), y) for x, y in extracted]
    else:
        extracted.sort(key=lambda x: x[0].lower())
        extracted = [(tag_names.get(x, x), y) for x, y in extracted]

    return [extracted]

def find_npc_from_gift_tagid(gift_tagid, connection):
    global CACHED_GIFTS
    if CACHED_GIFTS is None:
        CACHED_GIFTS = do_query('SELECT Gift_ID, TagID_Excellent, TagID_Like, TagID_Dislike, TagID_Hate, TagID_Confession, '
                                'TagID_Propose, TagID_Refuse, TagID_Breakup, TagID_Divorce, TagID_Jealous, TagID_MarriageCall FROM Gift', connection)
    qualifier = None
    for result in CACHED_GIFTS:
        if gift_tagid in result['tagid_excellent'].split(';'):
            qualifier = 'Excellent'
            break
        elif gift_tagid in result['tagid_like'].split(';'):
            qualifier = 'Like'
            break
        elif gift_tagid in result['tagid_dislike'].split(';'):
            qualifier = 'Dislike'
            break
        elif gift_tagid in result['tagid_hate'].split(';'):
            qualifier = 'Hate'
            break
        elif gift_tagid in result['tagid_confession'].split(';'):
            qualifier = 'Confession'
            break
        elif gift_tagid in result['tagid_propose'].split(';'):
            qualifier = 'Propose'
            break
        elif gift_tagid in result['tagid_refuse'].split(';'):
            qualifier = 'Refuse'
            break
        elif gift_tagid in result['tagid_breakup'].split(';'):
            qualifier = 'Breakup'
            break
        elif gift_tagid in result['tagid_divorce'].split(';'):
            qualifier = 'Divorce'
            break
        elif gift_tagid in result['tagid_jealous'].split(';'):
            qualifier = 'Jealous'
            break
        elif gift_tagid in result['tagid_marriagecall'].split(';'):
            qualifier = 'Marriage Call'
            break

    if qualifier is None:
        return 'No Gift found with tagid {}'.format(gift_tagid)
    npc_name = do_lookup('NPCRepository', result['gift_id'], '<str>GiftID', 'Name', Lookup.TRANSLATION, connection, {'allow_multiple_lookup_results': True,
                                                                                'multiple_lookup_results_join_char': ', '})
    return '{} ({})'.format(npc_name, qualifier)

def foodtag_lookup(tags, connection):
    global CACHED_FOOD_MENU
    if CACHED_FOOD_MENU is None:
        CACHED_FOOD_MENU = do_query('SELECT Food_Name, Food_Tag FROM Food_Menu', connection)
    foods = []
    for tag in tags.split(','):
        for result in CACHED_FOOD_MENU:
            if tag in result['food_tag'].split(','):
                foods.append(do_lookup('Translation_hint', result['food_name'],
                                       '<str>id', 'English', None, connection, {}))
    return '\n'.join(foods)

class Lookup(object):
    TRANSLATION = ('<str>id', 'Translation_hint', 'English', None)
    PROP = ('<str>Props_Id', 'Props_total_table', 'Props_Name', TRANSLATION)
    REPOSITORY = ('<str>Id', 'NPCRepository', 'Name', TRANSLATION)
    CONVERSATION_BASE = ('<str>baseid', 'Conversation_Base', 'TranslationID', TRANSLATION)
    CONVERSATION_SEGMENT_BASE = ('<str>SegmentID', 'Conversation_Segment', 'BaseID', lambda x, connection: '\n'.join([do_lookup(
        'Conversation_Base', split_val, '<str>BaseId', 'TranslationID', Lookup.TRANSLATION, connection, {}) for split_val in (x.split(',') if ',' in x else x.split(';'))]))
    EXHIBIT_SIZE = ('<str>size', 'ExhibitSize', 'name', TRANSLATION)
    EXHIBIT_TYPE_NAME = ('<str>type', 'ExhibitType', 'name', TRANSLATION)
    EXHIBIT_TYPE_DESCRIPTION = ('<str>type', 'ExhibitType', 'description', TRANSLATION)
    EXHIBIT_DATA_SIZE = ('<str>itemId', 'ExhibitData', 'size', EXHIBIT_SIZE)
    EXHIBIT_DATA_TYPE = ('<str>itemId', 'ExhibitData', 'type', EXHIBIT_TYPE_NAME)
    DATE_DIALOG_CONFESS_ACCEPT = ('<str>Date_DialogID', 'Date_Dialog', 'Confess_Accept', lambda val, connection: '\n'.join([do_lookup(
        'Conversation_Base', v, '<str>baseid', 'TranslationID', Lookup.TRANSLATION, connection, {}) for v in val.split(';')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_CONFESS_REFUSE = ('<str>Date_DialogID', 'Date_Dialog', 'Confess_Refuse', lambda val, connection: '\n'.join([do_lookup(
        'Conversation_Base', v, '<str>baseid', 'TranslationID', Lookup.TRANSLATION, connection, {}) for v in val.split(';')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_CONFESS_LACKITEM = ('<str>Date_DialogID', 'Date_Dialog', 'Confess_LackItem', lambda val, connection: '\n'.join([do_lookup(
        'Conversation_Base', v, '<str>baseid', 'TranslationID', Lookup.TRANSLATION, connection, {}) for v in val.split(';')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_BREAKUP = ('<str>Date_DialogID', 'Date_Dialog', 'BreakUp', lambda val, connection: '\n'.join([do_lookup(
        'Conversation_Base', v, '<str>baseid', 'TranslationID', Lookup.TRANSLATION, connection, {}) for v in val.split(';')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_PROPOSE_ACCEPT = ('<str>Date_DialogID', 'Date_Dialog', 'Propose_Accept', lambda val, connection: '\n'.join([do_lookup(
        'Conversation_Base', v, '<str>baseid', 'TranslationID', Lookup.TRANSLATION, connection, {}) for v in val.split(';')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_PROPOSE_REFUSE = ('<str>Date_DialogID', 'Date_Dialog', 'Propose_Refuse', lambda val, connection: '\n'.join([do_lookup(
        'Conversation_Base', v, '<str>baseid', 'TranslationID', Lookup.TRANSLATION, connection, {}) for v in val.split(';')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_PROPOSE_LACKITEM = ('<str>Date_DialogID', 'Date_Dialog', 'Propose_LackItem', lambda val, connection: '\n'.join([do_lookup(
        'Conversation_Base', v, '<str>baseid', 'TranslationID', Lookup.TRANSLATION, connection, {}) for v in val.split(';')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_PLAY_START = ('<str>Date_DialogID', 'Date_Dialog', 'Play_Start', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_PLAY_MISSEDCONTRACT = ('<str>Date_DialogID', 'Date_Dialog', 'Play_MissedContract', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_PLAY_GIVEUP_HAPPY = ('<str>Date_DialogID', 'Date_Dialog', 'Play_Giveup_Happy', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_PLAY_GIVEUP_UNHAPPY = ('<str>Date_DialogID', 'Date_Dialog', 'Play_Giveup_UnHappy', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_PLAY_ACTIONVALUE_HAPPY = ('<str>Date_DialogID', 'Date_Dialog', 'Play_ActionValue_Happy', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_PLAY_ACTIONVALUE_UNHAPPY = ('<str>Date_DialogID', 'Date_Dialog', 'Play_ActionValue_UnHappy', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_PLAY_TIMEOUT_HAPPY = ('<str>Date_DialogID', 'Date_Dialog', 'Play_TimeOut_Happy', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_PLAY_TIMEOUT_UNHAPPY = ('<str>Date_DialogID', 'Date_Dialog', 'Play_TimeOut_UnHappy', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_PLAY_MOODVALUE = ('<str>Date_DialogID', 'Date_Dialog', 'Play_MoodValue', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_PLAY_JEALOUS = ('<str>Date_DialogID', 'Date_Dialog', 'Play_Jealous', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_PLAY_INTERRUPT = ('<str>Date_DialogID', 'Date_Dialog', 'Play_Interrupt', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_DATE_START = ('<str>Date_DialogID', 'Date_Dialog', 'Date_Start', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_DATE_MISSEDCONTRACT = ('<str>Date_DialogID', 'Date_Dialog', 'Date_MissedContract', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_DATE_GIVEUP_HAPPY = ('<str>Date_DialogID', 'Date_Dialog', 'Date_Giveup_Happy', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_DATE_GIVEUP_UNHAPPY = ('<str>Date_DialogID', 'Date_Dialog', 'Date_Giveup_UnHappy', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_DATE_ACTIONVALUE_HAPPY = ('<str>Date_DialogID', 'Date_Dialog', 'Date_ActionValue_Happy', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_DATE_ACTIONVALUE_UNHAPPY = ('<str>Date_DialogID', 'Date_Dialog', 'Date_ActionValue_UnHappy', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_DATE_TIMEOUT_HAPPY = ('<str>Date_DialogID', 'Date_Dialog', 'Date_TimeOut_Happy', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_DATE_TIMEOUT_UNHAPPY = ('<str>Date_DialogID', 'Date_Dialog', 'Date_TimeOut_UnHappy', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_DATE_MOODVALUE = ('<str>Date_DialogID', 'Date_Dialog', 'Date_MoodValue', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_DATE_INTERRUPT = ('<str>Date_DialogID', 'Date_Dialog', 'Date_Interrupt', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_DATE_JEALOUS = ('<str>Date_DialogID', 'Date_Dialog', 'Date_Jealous', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_DATE_INVITE = ('<str>Date_DialogID', 'Date_Dialog', 'Date_Invite', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    DATE_DIALOG_INVITE_REFUSE = ('<str>Date_DialogID', 'Date_Dialog', 'InviteRefuse', lambda val, connection: '\n'.join([do_lookup(
        'Translation_Hint', v, '<str>id', 'English', None, connection, {}) for v in val.split(',')])if len(val) > 0 else 'No Date_DialogID yet')
    ITEM_DROP_FIXED = ('<str>id', 'Item_drop', 'FixDrop_ItemList', lambda x, connection: '\n'.join([do_lookup(
        'Props_total_table', y.split(',')[0], '<str>Props_Id', 'Props_Name', Lookup.TRANSLATION, connection, {}) for y in x.split(';')]))
    ITEM_DROP_RANDOM = ('<str>id', 'Item_drop', 'RndDrop_ItemList', lambda x, connection: '\n'.join([do_lookup(
        'Props_total_table', y.split(',')[0], '<str>Props_Id', 'Props_Name', Lookup.TRANSLATION, connection, {}) for y in x.split(';')]) if x.split(';')[0].split(',')[0] != '0' else 'None')
    ITEM_DROP_RANDOM_NUMBER = ('<str>Id', 'Item_drop', 'RndDrop_NumRange', None)
    ITEM_DROP_FIXED_NUMBER = ('<str>Id', 'Item_drop', 'FixDrop_MaxNum', None)
    NPC_ID_TO_NAME = ('<str>Id', 'NPCRepository', 'Name', TRANSLATION)
    GIFT_ID_TO_NAME = ('<str>GiftID', 'NpcRepository', 'Name', TRANSLATION)
    CONVERSATION_SEGMENT_SPEAKER = ('<str>SegmentID', 'Conversation_Segment', 'SpeakerID', NPC_ID_TO_NAME)
    CONVERSATION_SEGMENT_SPEAK_TO_ID = ('<str>SegmentID', 'Conversation_Segment', 'SpeakToId', NPC_ID_TO_NAME)
    WISH_ITEM_GROUP = ('<str>WishItemID', 'WishItem', 'PropsId', PROP)
    PARTS_LIST = ('<str>Part_ID', 'CreationPart_List', 'Item_List', lambda x, connection: do_lookup('Props_total_table', x.split(';')[
                  1].split('_')[0], '<str>Props_ID', 'Props_Name', Lookup.TRANSLATION, connection, {}) + ' x{}'.format(x.split(';')[1].split('_')[1]))
    PROP_ITEM_TYPE = ('<str>Props_Id', 'Props_total_table', 'Item_Type', None)
    FIND_DIFF_GAME_ITEMS = ('<str>id', 'FindDiffGame_Items', 'itemId', PROP)
    MAIL = ('<str>id', 'Mail', 'Content', TRANSLATION)
    PK_DIALOG = ('<str>DialogID', 'PK_Dialog', 'Dialog', TRANSLATION)
    ANIMAL_FARM_HOUSE = ('<str>type', 'AnimalFarm_House', 'ItemId', PROP)
    FAVOR_RELATION = ('<str>Favor_Relation_ID', 'Favor_Relation', 'Relation_Name', TRANSLATION)
    COOK_TAG_NAME = ('<str>Tag', 'Cook_TagName', 'Name', TRANSLATION)
    STORE_ID = ('<str>Store_Id', 'Store_4_0', 'Name_Id', TRANSLATION)
    STORE_PRODUCT = ('<str>product_id', 'Store_product', 'item_id', PROP)
    ACTOR_TYPE = ('<str>ID', 'Actor', 'Name', TRANSLATION)
    DUNGEON_CHEST_FIXED = ('<str>ID', 'Dungeon_Chest', 'Drop_Group', ITEM_DROP_FIXED)
    DUNGEON_CHEST_RANDOM = ('<str>ID', 'Dungeon_Chest', 'Drop_Group', ITEM_DROP_RANDOM)
    DUNGEON_MONSTER = ('<str>ID', 'Trial_Dungeon_Monster', 'ActorID', ACTOR_TYPE)
    RIDABLE_INFO_ID = ('<str>RidableInfoID', 'RidableInfo', 'InitNickName', TRANSLATION)
    FOOD_TAG_LIKES = ('<str>Food_GroupID', 'Food_Group', 'LikeFood_Tag', foodtag_lookup)
    FOOD_TAG_DISLIKES = ('<str>Food_GroupID', 'Food_Group', 'DislikeFood_Tag', foodtag_lookup)
    DATE_PROJECT = ('<str>Date_ProjectID', 'Date_Project_new', 'Project_Name', TRANSLATION)
    GUILD_LEVEL = ('<str>ID', 'GuildLevel', 'Level', None)
    FURNITURE_TABLE_SIZE = ('<str>ID', 'Furniture_Table', 'Size', None)
    FURNITURE_TABLE_FEATURE_TYPE = ('<str>ID', 'Furniture_Table', 'Feature_Type', None)
    EXHIBIT_WORKSHOP_PT = ('<str>itemId', 'ExhibitData', 'workshopPT', None)
    REPAIR_TABLE_PARTS_LIST = ('<str>Item_Id', 'Repair_Table', 'Parts_List', None)  # need to split these up by comma
    REPAIR_TABLE_TIME = ('<str>Item_Id', 'Repair_Table', 'Time', None)
    REPAIR_TABLE_CD_COST = ('<str>Item_Id', 'Repair_Table', 'CD_Cost', None)
    PROPS_ID_TO_USER_LEVEL = ('<str>Props_Id', 'Props_total_table', 'User_Level', None)
    PROPS_ID_TO_PROPS_EXPLAIN_ONE = ('<str>Props_Id', 'Props_total_table', 'Props_Explain_One', TRANSLATION)
    PROPS_ID_TO_EFFECT = ('<str>Props_Id', 'Props_total_table', 'Effect', TRANSLATION)
    PROPS_ID_TO_ATK = ('<str>Equipment_Id', 'Item_equipment', 'ATK', None)
    PROPS_ID_TO_DEFENSE = ('<str>Equipment_Id', 'Item_equipment', 'Defense', None)
    PROPS_ID_TO_HEALTH = ('<str>Equipment_Id', 'Item_equipment', 'Health', None)
    PROPS_ID_TO_CPMAX = ('<str>Equipment_Id', 'Item_equipment', 'CpMax', None)
    PROPS_ID_TO_CRIT = ('<str>Equipment_Id', 'Item_equipment', 'Crit', None)
    PROPS_ID_TO_MELEE_CRITICAL = ('<str>Equipment_Id', 'Item_equipment', 'MeleeCriticalAmount', None)
    PROPS_ID_TO_RANGE_CRITICAL = ('<str>Equipment_Id', 'Item_equipment', 'RangeCriticalAmount', None)
    PROPS_ID_TO_ANTICRITICAL = ('<str>Equipment_Id', 'Item_equipment', 'AntiCritical', None)
    PROPS_ID_TO_DATE_FORCE = ('<str>Equipment_Id', 'Item_equipment', 'Date_Force', None)
    ITEM_FOOD_HP_VALUE = ('<str>Food_Id', 'Item_food', 'hp_Value', None)
    ITEM_FOOD_COMFORT_VALUE = ('<str>Food_Id', 'Item_food', 'Comfort_Value', None)
    ITEM_FOOD_ADD_HP_MAX = ('<str>Food_Id', 'Item_food', 'Add_HpMax', None)
    ITEM_FOOD_ADD_CP_MAX = ('<str>Food_Id', 'Item_food', 'Add_CpMax', None)
    ITEM_FOOD_ADD_ATTACK = ('<str>Food_Id', 'Item_food', 'Add_Attack', None)
    ITEM_FOOD_ADD_DEFENCE = ('<str>Food_Id', 'Item_food', 'Add_Defence', None)
    ITEM_FOOD_ADD_CRIT = ('<str>Food_Id', 'Item_food', 'Add_Crit', None)
    ITEM_FOOD_ADD_ANTICRIT = ('<str>Food_Id', 'Item_food', 'Add_AntiCrit', None)
    ITEM_FOOD_BUFF_ID = ('<str>Food_Id', 'Item_food', 'Buff_Id', None)
    ITEM_FOOD_REMOVE_BUFF_ID = ('<str>Food_Id', 'Item_food', 'Remove_Buff_Id', None)
    RECYCLE_TABLE_DROP_ID = ('<str>Item_Id', 'Recycle_Table', 'Drop_Id', ITEM_DROP_FIXED)
    FARM_COMMON_SUITABLE_FLOOR = ('<str>ID', 'Farm_Common', 'SuitableFloor', None)
    FARM_COMMON_AREA = ('<str>ID', 'Farm_Common', 'Area', None)
    FARM_COMMON_UNABLE_FACE_TO_WALL = ('<str>ID', 'Farm_Common', 'UnableFaceToWall', None)
    STORE_PRODUCT_GENERAL = ('<str>product_id', 'Store_product', 'item_id', None)
    FOOD_DIALOG = ('<str>FoodTag_ID', 'Food_Dialog', 'FoodTag_Name', TRANSLATION)
    CABINET_TYPE_LIST = ('<str>Type', 'Cabinet_TypeList', 'Name', TRANSLATION)
    ABILITY_TREE_NEW = ('<str>Id', 'Ability_Tree_New', 'Name', TRANSLATION)
    ITEM_FROM = ('<str>Id', 'ItemFrom', 'Des', TRANSLATION)
    PLAYER_INTEND_NO_TARGET = ('<str>Type', 'Player_Intend', 'NoTarget', None)
    PLAYER_INTEND_HOME_REGION = ('<str>Type', 'Player_Intend', 'HomeRegion', None)
    IN_MISSION_DIALOG = ('<str>MissionID', 'InMission_Dialog', 'Dialog', CONVERSATION_BASE)  # split by semicolon
    TASK_DIALOGUE = ('<str>Dialogue', 'Task_dialogue', 'Id', CONVERSATION_BASE)
    ORDER_REQ_ITEM = ('<str>OrderID', 'Order_Req', 'ItemReq', PROP)  # for now
    ORDER_REQ_GOLD = ('<str>OrderID', 'Order_Req', 'Gold', None)
    ORDER_REQ_RELATIONSHIP = ('<str>OrderID', 'Order_Req', 'Relationship', None)
    ORDER_REQ_WORKSHOP_PT = ('<str>OrderID', 'Order_Req', 'WorkshopPT', None)
    ORDER_REQ_EXP = ('<str>OrderID', 'Order_Req', 'Exp', None)
    ORDER_REQ_LEVEL = ('<str>OrderID', 'Order_Req', 'Level', GUILD_LEVEL)
    ORDER_REQ_WEIGHT = ('<str>OrderID', 'Order_Req', 'Weight', None)
    ORDER_REQ_DEADLINE = ('<str>OrderID', 'Order_Req', 'Deadline', None)
    ORDER_REQ_MISSION = ('<str>OrderID', 'Order_Req', 'MissionID', None)
    ORDER_REQ_SEASON = ('<str>OrderID', 'Order_Req', 'Season', None)
    ORDER_REQ_WEATHER = ('<str>OrderID', 'Order_Req', 'Weather', None)
    TRIAL_DUNGEON_MONSTER = ('<str>ID', 'Trial_Dungeon_Monster', 'ActorID', ACTOR_TYPE)
    REQ_TYPE = ('<str>TypeID', 'Req_Type', 'Order_Rewards', None)  # for now, need to split by ','
    # for now, need to split by ';' and quantity_post '_'
    RESEARCH_LIST_ITEM_LIST = ('<str>ID', 'Research_List', 'Item_List', PROP)
    RESEARCH_LIST_RESEARCH_SPEED = ('<str>ID', 'Research_List', 'Research_Speed', None)
    SWING_ID_TO_NAME = ('<str>SwingGame_ID', 'NpcRepository', 'Name', TRANSLATION)
    TEETER_ID_TO_NAME = ('<str>TeeterGame_ID', 'NpcRepository', 'Name', TRANSLATION)
    RANDOM_HERBS_ITEM_DROP_FIXED = ('<str>ID', 'random_herbs', 'Drop_Group', ITEM_DROP_FIXED)
    RANDOM_HERBS_ITEM_DROP_FIXED_NUMBER = ('<str>ID', 'random_herbs', 'Drop_Group', ITEM_DROP_FIXED_NUMBER)
    RANDOM_HERBS_ITEM_DROP_RANDOM = ('<str>ID', 'random_herbs', 'Drop_Group', ITEM_DROP_RANDOM)
    RANDOM_HERBS_ITEM_DROP_RANDOM_NUMBER = ('<str>ID', 'random_herbs', 'Drop_Group', ITEM_DROP_RANDOM_NUMBER)
    EMOTION_DATA = ('<str>emotionId', 'emotion_data', 'nameId', TRANSLATION)
    SLOT_RATE_TYPE = ('<str>Type', 'Slot_Rate', 'Index_List', None)
    SLOT_RATE_RATE = ('<str>Type', 'Slot_Rate', 'Rate', None)
    COOK_BOOK_QUALITY_COST = ('<str>Quality', 'Cook_BookQuality', 'Cost', None)
    COOK_BOOK_QUALITY_WEIGHT = ('<str>Quality', 'Cook_BookQuality', 'Weight', None)
    DEE_FLAG_NAME = ('<str>id', 'SceneItemTransformBinding', 'flagName', None)
    FOOD_TAG_MAXIMUM = ('<str>Food_GroupID', 'Food_Group', 'Food_Maximum', None)
    FOOD_TAG_MINIMUM = ('<str>Food_GroupID', 'Food_Group', 'Food_Minimum', None)
    ORDER_REQ_GROUP_REQ = ('<str>id', 'Order_ReqGroup', 'req', lambda x, connection: '\n'.join([do_lookup(
        'Order_Req', y.split(',')[0], '<str>OrderID', 'ItemReq', Lookup.PROP, connection, {}) for y in x.split(',')]))

class Transform(object):
    @staticmethod
    def FACTION(x, connection):
        return {'11': 'Person',
                '-1': 'Monster',
                '0': '0 (Unknown)',
                '1': '1 (Unknown)',
                '2': '2 (Unknown)',
                '3': '3 (Unknown)',
                '4': '4 (Unknown)',
                '5': '5 (Unknown)',
                '6': '6 (Unknown)',
                '7': '7 (Unknown)',
                '8': '8 (Unknown)',
                '9': '9 (Unknown)',
                '10': '10 (Unknown)',
                '15': '15 (Unknown)'}[x]

    @staticmethod
    def BOOL(x, connection):
        return {'0': 'False', '1': 'True'}[x]

    @staticmethod
    def EMPTY(x, connection):
        return {'-1': 'n/a'}[x]

    @staticmethod
    def RELATION_TYPE(x, connection):
        return {'1': 'Not Romanceable',
                '2': 'Bachelor/Bachelorette',
                '3': 'Spouse'}[x]

    @staticmethod
    def GIFT_TAGID(x, connection):
        results = []
        tags = x.split(',')
        for tag in tags:
            if tag == '0':
                results.append('No tag')
            elif tag in ['1', '2', '3', '4']:
                results.append({'1': 'Universal love',
                                '2': 'Universal like',
                                '3': 'Universal dislike',
                                '4': 'Universal hate'}[tag])
            else:
                results.append(find_npc_from_gift_tagid(tag, connection))
        return '\n'.join(results)

    @staticmethod
    def TRANSLATION_UNDERSCORE_SPLIT(x, connection):
        results = []
        for q_and_a in x.split(','):
            print(q_and_a)
            q, a = q_and_a.split('_')
            q_and_a_str = 'Question: {}\nAnswer: {}'.format(
                do_lookup('Translation_hint', q, '<str>id', 'English', None, connection, {}),
                do_lookup('Translation_hint', a, '<str>id', 'English', None, connection, {}))
            results.append(q_and_a_str)
        return '\n\n'.join(results)

    @staticmethod
    def SOCIAL_DIALOG(x, connection):
        if x == '-1':
            return 'None'
        results = []
        for dialog in x.split('|'):
            hearts, options = dialog.split('=')
            dialogs = []
            for option in options.split(';'):
                dialogs.append(do_lookup('Conversation_Base', option, '<str>baseid',
                                         'TranslationID', Lookup.TRANSLATION, connection, {}))
            results.append('{0:>3}: {1}'.format(hearts, '\n     '.join(dialogs)))
        return '\n'.join(results)

    @staticmethod
    def PRODUCT_SEASON(x, connection):
        season, products = x.split('=')
        results = []
        for product in products.split(','):
            product, quantity = product.split('_')
            product = do_lookup('Store_product', product, '<str>product_id',
                                'item_id', Lookup.PROP, connection, {})
            results.append('{} x{}'.format(product, quantity))
        season = ['Spring', 'Summer', 'Autumn', 'Winter'][int(season)]
        return '{} -- {}'.format(season, '\n          '.join(results))

    @staticmethod
    def PRODUCT_WEATHER(x, connection):
        weather, products = x.split('=')
        results = []
        for product in products.split(','):
            product, quantity = product.split('_', maxsplit=1)
            product = do_lookup('Store_product', product, '<str>product_id',
                                'item_id', Lookup.PROP, connection, {})
            results.append('{} x{}'.format(product, quantity))
        weather = ['Weather 0', 'Weather 1', 'Weather 2', 'Weather 3'][int(weather)]
        return '{} -- {}'.format(weather, '\n          '.join(results))

    @staticmethod
    def GIFT_ID(x, connection):
        if str(x) == '1':
            return 'ALL'
        results = do_query('SELECT Name FROM NPCRepository where GiftID="{}"'.format(x), connection)
        if len(results) == 0:
            return '<No NPC with GiftID {}>'.format(x)
        name = do_lookup('Translation_hint', results[0]['name'], '<str>id', 'English', None, connection, {})
        if name.strip() == '':
            return '<Empty name, GiftID is {}>'.format(x)
        return name

    @staticmethod
    def FAVOR(x, connection):
        global CACHED_GIFT_TAGS
        if CACHED_GIFT_TAGS is None:
            CACHED_GIFT_TAGS = find_associations('Props_total_table', 'Tag_List', ',',
                                                 ('props_name', Lookup.TRANSLATION), {}, connection)
            CACHED_GIFT_TAGS = {x: y for x, y in CACHED_GIFT_TAGS[0]}
        base_value, exceptions = x.split('|')
        if exceptions.strip() == '':
            return 'Value {}\nExceptions:None'.format(base_value)
        exceptions_translated = []
        for exception in exceptions.split('$'):
            tag, value = exception.split('_')
            items_str = CACHED_GIFT_TAGS.get(tag)
            if items_str is None:
                exceptions_translated.append('{}: {}'.format(value, '<Unknown gift with tag {}>'.format(tag)))
            else:
                items = items_str.split('\n')
                exceptions_translated.append('{}: {}'.format(value, ', '.join(items)))
        return 'Value {}\nExceptions: {}'.format(base_value, '\n            '.join(exceptions_translated))

    @staticmethod
    def REWARDS(x, connection):
        points, mail, drop = x.split(',')
        return 'Points: {}\n  Mail: {}\n'.format(
            points,
            do_lookup('Mail', mail, '<str>id', 'Content', Lookup.TRANSLATION, connection, {}).replace('\n\n', ' ').replace('\n', ' '))
        """
        return 'Points: {}\nReward: {}\n  Mail: {}\n'.format(
            points,
            do_lookup('Item_drop', drop, '<str>id', 'FixDrop_ItemList', lambda x, connection: ', '.join([do_lookup(
                'Props_total_table', y.split(',')[0], '<str>Props_Id', 'Props_Name', Lookup.TRANSLATION, connection, {}) for y in x.split(';')]), connection, {}),
            do_lookup('Mail', mail, '<str>id', 'Content', Lookup.TRANSLATION, connection, {}).replace('\n\n', ' ').replace('\n', ' '))
        """

    @staticmethod
    def GIFT_ID_EXCELLENT(x, connection):
        return do_lookup('Gift', x, '<str>Gift_ID', 'TagID_Excellent', lambda val,
                         connection: props_gift_lookup(val, connection, x, 'Excellent') if len(val.strip()) > 0 else 'No Gift_TagID yet', connection, {})

    @staticmethod
    def GIFT_ID_LIKE(x, connection):
        return do_lookup('Gift', x, '<str>Gift_ID', 'TagID_Like', lambda val,
                         connection: props_gift_lookup(val, connection, x, 'Like') if len(val.strip()) > 0 else 'No Gift_TagID yet', connection, {})

    @staticmethod
    def GIFT_ID_DISLIKE(x, connection):
        return do_lookup('Gift', x, '<str>Gift_ID', 'TagID_Dislike', lambda val,
                         connection: props_gift_lookup(val, connection, x, 'Dislike') if len(val.strip()) > 0 else 'No Gift_TagID yet', connection, {})

    @staticmethod
    def GIFT_ID_HATE(x, connection):
        return do_lookup('Gift', x, '<str>Gift_ID', 'TagID_Hate', lambda val,
                         connection: props_gift_lookup(val, connection, x, 'Hate') if len(val.strip()) > 0 else 'No Gift_TagID yet', connection, {})

    @staticmethod
    def GIFT_ID_CONFESSION(x, connection):
        return do_lookup('Gift', x, '<str>Gift_ID', 'TagID_confession', lambda val,
                         connection: props_gift_lookup(val, connection, x) if len(val.strip()) > 0 else 'No Gift_TagID yet', connection, {})

    @staticmethod
    def GIFT_ID_PROPOSE(x, connection):
        return do_lookup('Gift', x, '<str>Gift_ID', 'TagID_propose', lambda val,
                         connection: props_gift_lookup(val, connection, x) if len(val.strip()) > 0 else 'No Gift_TagID yet', connection, {})

    @staticmethod
    def GIFT_ID_REFUSE(x, connection):
        return do_lookup('Gift', x, '<str>Gift_ID', 'TagID_refuse', lambda val,
                         connection: props_gift_lookup(val, connection, x) if len(val.strip()) > 0 else 'No Gift_TagID yet', connection, {})

    @staticmethod
    def GIFT_ID_BREAK_UP(x, connection):
        return do_lookup('Gift', x, '<str>Gift_ID', 'TagID_breakup', lambda val,
                         connection: props_gift_lookup(val, connection, x) if len(val.strip()) > 0 else 'No Gift_TagID yet', connection, {})

    @staticmethod
    def GIFT_ID_DIVORCE(x, connection):
        return do_lookup('Gift', x, '<str>Gift_ID', 'TagID_divorce', lambda val,
                         connection: props_gift_lookup(val, connection, x) if len(val.strip()) > 0 else 'No Gift_TagID yet', connection, {})

    @staticmethod
    def GIFT_ID_JEALOUS(x, connection):
        return do_lookup('Gift', x, '<str>Gift_ID', 'TagID_jealous', lambda val,
                         connection: props_gift_lookup(val, connection, x) if len(val.strip()) > 0 else 'No Gift_TagID yet', connection, {})

    @staticmethod
    def PROPS_RECYCLE_TAG(x, connection):
        global CACHED_RECYCLE_TAGS
        if CACHED_RECYCLE_TAGS is None:
            CACHED_RECYCLE_TAGS = {}
            results = do_query('SELECT props_name, Recycle_Tag FROM props_total_table', connection)
            for result in results:
                tags = result['recycle_tag'].split(',')
                for tag in tags:
                    if tag not in CACHED_RECYCLE_TAGS:
                        CACHED_RECYCLE_TAGS[tag] = []
                    CACHED_RECYCLE_TAGS[tag].append(result['props_name'])
        if x not in CACHED_RECYCLE_TAGS:
            return 'Did not find any props with recycle tag {}'.format(x)

        props = []
        for prop in CACHED_RECYCLE_TAGS[x]:
            props.append(do_lookup('Translation_hint', prop, '<str>id', 'English', None, connection, {}))
        return '\n'.join(props)

    @staticmethod
    def ORDER_CAN_REQUEST(x, connection):
        if x == '-1':
            return 'None'
        requestables = []
        groups = x.split('#')
        for i, group in enumerate(groups):
            commisions = group.split('|')[0].split(',')
            for commision in commisions:
                results = do_query('SELECT req FROM Order_ReqGroup WHERE id="{}"'.format(commision), connection)
                assert len(results) == 1
                order_ids = results[0]['req'].split(',')
                for order_id in order_ids:
                    results = do_query(
                        'SELECT * FROM Order_Req WHERE OrderId="{}"'.format(order_id), connection)
                    assert len(results) == 1
                    info = results[0]
                    quantity = info['itemreq'].split('_')[1]
                    if len(set(quantity.split('-'))) == 1:
                        quantity = quantity.split('-')[0]
                    name = do_lookup('Props_total_table', info['itemreq'].split('_')[0], '<str>Props_Id',
                                     'Props_Name', Lookup.TRANSLATION, connection, {}) + ' (x{})'.format(quantity)
                    gold = info['gold']
                    if len(set(gold.split('-'))) == 1:
                        gold = gold.split('-')[0]
                    relationship = info['relationship']
                    if len(set(relationship.split('-'))) == 1:
                        relationship = relationship.split('-')[0]
                    workshop_pt = info['workshoppt']
                    if len(set(workshop_pt.split('-'))) == 1:
                        workshop_pt = workshop_pt.split('-')[0]
                    workshop_pt = info['workshoppt']
                    if len(set(workshop_pt.split('-'))) == 1:
                        workshop_pt = workshop_pt.split('-')[0]
                    requestables.append('{}: {}'.format(i + 1, name) +
                                        '\n     Gold: {}'.format(gold) +
                                        '\n     Relationship: {}'.format(relationship) +
                                        '\n     Workshop Pts: {}'.format(workshop_pt) +
                                        '\n     Exp: {}'.format(info['exp']) +
                                        '\n     Level: {}'.format(info['level']) +
                                        '\n     Weight: {}'.format(info['weight']) +
                                        '\n     Mission ID: {}'.format('None' if info['missionid'] == '-1' else info['missionid']) +
                                        '\n     Season: {}'.format('None' if info['season'] == '' else info['season']) +
                                        '\n     Weather: {}'.format('None' if info['weather'] == '' else info['weather']) +
                                        '\n     Deadline: {} Days'.format(info['deadline']))
        return '\n'.join(requestables)

    @staticmethod
    def ORDER_MISSION_DIALOGUE(x, connection):
        if x == '-1':
            return 'None'
        groups = x.split('#')
        dialogues = []
        for group in groups:
            dialogue = do_lookup('Translation_hint', group.split('|')[1], '<str>id', 'English', None, connection, {})
            dialogues.append(dialogue)
        return '\n'.join(dialogues)

    @staticmethod
    def ORDER_CAN_DELIVER_TO(x, connection):
        groups = x.split('#')
        npcs = []
        for group in groups:
            for subgroup in group.split('|')[2:]:
                npc_id = subgroup.split('=')[0]
                npc_name = do_lookup('NPCRepository', npc_id, '<str>Id', 'Name', Lookup.TRANSLATION, connection, {})
            npcs.append(npc_name)
        return '\n'.join(npcs)

    @staticmethod
    def ITEM_DROP_FIXED(x, connection):
        reward_id = x.split(',')[-1]
        return do_lookup('Item_drop', reward_id, '<str>id', 'FixDrop_ItemList',
                         lambda x, connection: '\n'.join([do_lookup('Props_total_table', y.split(',')[0], '<str>Props_Id', 'Props_Name', Lookup.TRANSLATION, connection, {}) for y in x.split(';')]), connection, {})

    @staticmethod
    def ITEM_DROP_RANDOM(x, connection):
        reward_id = x.split(',')[-1]
        return do_lookup('Item_drop', reward_id, '<str>id', 'RndDrop_ItemList',
                         lambda x, connection: '\n'.join([do_lookup('Props_total_table', y.split(',')[0], '<str>Props_Id', 'Props_Name', Lookup.TRANSLATION, connection, {}) for y in x.split(';')]) if x.split(';')[0].split(',')[0] != '0' else 'None', connection, {})

    @staticmethod
    def ITEM_DROP_RANDOM_NUMBER(x, connection):
        reward_id = x.split(',')[-1]
        return do_lookup('Item_drop', reward_id, '<str>id', 'RndDrop_NumRange', None, connection, {})

    @staticmethod
    def ITEM_DROP_FIXED_NUMBER(x, connection):
        reward_id = x.split(',')[-1]
        return do_lookup('Item_drop', reward_id, '<str>id', 'FixDrop_MaxNum', None, connection, {})

def dict_factory(cursor, row):
    d = {}
    for idx, col in enumerate(cursor.description):
        d[col[0].lower()] = row[idx]
    return d

def do_lookup(lookup_table, source_value, lookup_column, result_column, result_conversion, connection, options):
    multiplier = None
    if 'quantity_pre' in options or 'quantity_post' in options:
        quantity_indicator = options.get('quantity_pre', None)
        quantity_indicator = options.get('quantity_post', quantity_indicator)
        assert quantity_indicator is not None
        if quantity_indicator in source_value:
            split_values = source_value.split(quantity_indicator)
            if len(split_values) > 2:
                return 'Unsure how to handle source value with multiple quantity indicators: quantity indicator is {}, value is {}'.format(quantity_indicator, source_value)
            if 'quantity_pre' in options and 'quantity_post' not in options:
                multiplier, source_value = split_values
            elif 'quantity_post' in options and 'quantity_pre' not in options:
                source_value, multiplier = split_values
            else:
                assert False, 'Invalid quantity options combination: {}'.format(options)
    if lookup_column.startswith('<str>'):
        lookup_column = lookup_column[5:]
        query = 'SELECT {} FROM {} where {}="{}"'.format(
            result_column, lookup_table, lookup_column, source_value)
        results = do_query(query, connection)
    else:
        query = 'SELECT {} FROM {} where {}={}'.format(
            result_column, lookup_table, lookup_column, source_value)
        results = do_query(query, connection)
    looked_up_values = []
    for result in results:
        looked_up_values.append(result[result_column.lower()])
    if len(looked_up_values) == 0:
        return 'Query {} returned no results'.format(query)
    if len(looked_up_values) > 1:
        assert options.get('allow_multiple_lookup_results', True), \
            'Multiple results returned for query {} :o'.format(query)
    final_values = []
    for looked_up_value in looked_up_values:
        values_to_process = [looked_up_value]
        if 'lookup_split' in options:
            values_to_process = looked_up_value.split(options['lookup_split'])
        results = []
        for looked_up_value in values_to_process:
            if result_conversion is not None:
                if callable(result_conversion):
                    looked_up_value = result_conversion(looked_up_value, connection)
                elif isinstance(result_conversion, tuple):
                    looked_up_value = do_lookup(
                        result_conversion[1], looked_up_value, result_conversion[0], result_conversion[2], result_conversion[3], connection, options)
                elif isinstance(result_conversion, list):
                    for conversion in result_conversion:
                        looked_up_value = do_lookup(conversion[1], looked_up_value,
                                                    conversion[0], conversion[2], conversion[3], connection, options)
                        if 'returned no results' not in looked_up_value:
                            break
                else:
                    raise Exception('Invalid value of result_conversion: {}'.format(result_conversion))
            if multiplier is not None:
                looked_up_value = looked_up_value + ' x{}'.format(multiplier)
            results.append(looked_up_value)
        final_values.append(options.get('lookup_split_join_char', '\n').join(results))
    return options.get('multiple_lookup_results_join_char', ', ').join(final_values)

def extract_table(name, columns, connection):
    extracted = []
    results = do_query('SELECT {} FROM {}'.format(','.join([x[0] for x in columns]), name), connection)
    for result in results:
        single_extracted = []
        for i in range(len(columns)):
            options = {}
            if len(columns[i]) > 2:
                options = columns[i][2]
                col_name = columns[i][0]
                conversion = columns[i][1]
            elif len(columns[i]) == 2:
                col_name, conversion = columns[i]
            col_values = []

            field_label = options.get('label', col_name)

            if 'split' in options:
                values = result[col_name.lower()].split(options['split'])
            else:
                values = [result[col_name.lower()]]
            for value in values:
                if 'ignore_if_equals' in options and value in options['ignore_if_equals']:
                    col_values.append('(n/a)')
                    continue
                if value == '':
                    col_values.append('(empty)')
                    continue
                if 'regex' in options:
                    match = re.search(options['regex'], value)
                    assert match is not None, 'Regex {} does not match value "{}"'.format(options['regex'], value)
                    value = match.group(1)
                if isinstance(conversion, tuple):
                    col_value = do_lookup(conversion[1], value, conversion[0],
                                          conversion[2], conversion[3], connection, options)
                elif isinstance(conversion, list):
                    for single_conversion in conversion:
                        col_value = do_lookup(
                            single_conversion[1], value, single_conversion[0], single_conversion[2], single_conversion[3], connection, options)
                        if 'returned no results' not in col_value:
                            break
                elif callable(conversion):
                    col_value = conversion(value, connection)
                elif conversion is None:
                    col_value = value
                else:
                    raise Exception('Unexpected conversion type {}'.format(conversion))
                col_values.append(col_value)
            join_string = options.get('join', '\n')
            single_extracted.append((field_label, join_string.join(col_values)))
        extracted.append(single_extracted)
    extracted.sort(key=lambda x: x[0][1].lower())
    return extracted

def main(mappings):
    connection = sqlite3.connect(DATABASE_FILENAME)
    connection.row_factory = dict_factory

    with open('all.txt', 'w', encoding='utf-8') as f_all:
        for filepath, mapping in mappings.items():
            with open(filepath[:-2] + 'txt', 'w', encoding='utf-8') as f:
                try:
                    if 'association' in mapping:
                        column = mapping['association']['column']
                        lookup = None
                        if isinstance(column, tuple):
                            column, lookup = column
                        extracted = find_associations(mapping['name'], column, mapping['association'].get(
                            'split', ','), mapping['association']['name'], mapping['association'].get('tag_names', {}), connection)
                        if lookup is not None:
                            new_extracted = [[]]
                            for i in extracted:
                                for key, value in i:
                                    new_extracted[0].append((do_lookup(
                                        lookup[1], key, lookup[0], lookup[2], lookup[3], connection, {}), value))
                            extracted = new_extracted
                    elif 'columns' in mapping:
                        extracted = extract_table(mapping['name'], mapping['columns'], connection)
                    print(mapping['name'])
                    print('\n')
                    for single in extracted:
                        maxlen = 0
                        for field, _ in single:
                            maxlen = max(len(field), maxlen)
                        multiple_values_in_list = False
                        for field, value in single:
                            if '\n' in value:
                                multiple_values_in_list = True
                        # Does weird things to name column, disable for now
                        multiple_values_in_list = False
                        for field, value in single:
                            if '\n' in value:
                                all_values = value.split('\n')
                                index_length = len(str(len(all_values)))
                                all_values = ['{0:>{1}}: {2}'.format(i + 1, index_length, all_values[i])
                                              for i in range(len(all_values))]
                                value = '\n{0:>{1}}'.format(' ', maxlen + 2).join(all_values)
                            elif multiple_values_in_list:
                                value = '1: {}'.format(value)
                            line = '{0:>{1}}: {2}'.format(field, maxlen, value)
                            try:
                                print(line)
                            except UnicodeEncodeError:
                                print('{0:>{1}}: {2}'.format(field, maxlen,
                                                             value.encode('cp437', 'replace').decode('cp437')))
                            f.write(line + '\n')
                            f_all.write(line + '\n')
                            f.flush()
                            f_all.flush()
                        f.write('\n')
                        f_all.write('\n')
                        print('')
                except Exception:
                    err = 'Failed to evaluate mapping for {} due to the following error:\n\n{}'.format(
                        filepath, traceback.format_exc())
                    print(err)
                    f.write(err)
                    f_all.write(err)

if __name__ == '__main__':
    folder = os.path.join('datasets')
    files = []
    if len(files) == 0:
        for root, _, filenames in os.walk(folder):
            for filename in filenames:
                if filename.endswith('.py'):
                    files.append(os.path.join(root, filename))
    else:
        for i, filepath in enumerate(files):
            if not filepath.endswith('.py'):
                filepath += '.py'
            files[i] = os.path.join(folder, filepath)
    files.sort()
    mappings = {}
    for filepath in files:
        with open(filepath) as f:
            try:
                mapping = eval(f.read())
            except Exception:
                print('Failed to evaluate file {}:\n{}'.format(filepath, traceback.format_exc()))
                exit(1)
        mappings[filepath] = mapping

    if not os.path.isfile(DATABASE_FILENAME):
        print('Please update DATABASE_FILENAME to point to LocalDb.bytes')
    else:
        current_hash = md5_hash(DATABASE_FILENAME)
        load_cache(current_hash)
        initial_size = sys.getsizeof(CACHED_QUERIES)
        main(mappings)
        post_run_size = sys.getsizeof(CACHED_QUERIES)
        if post_run_size - initial_size > 500:
            write_cache(current_hash)


from .settings import Settings, FRAMEWORK, SAMPLE_IMPL, BENCH_DEBUG, DEVICE_CPU
from .types import (FrameType, TorchModes, TFModes, JAXModes, SampleTag,
                    SampleSource)
from .sample_config import SampleConfig
from .args_tree import build_pytree, unfold_custom_class
from .utils import (
    random_shape,
    trans_to_np,
    auto_import,
    auto_register,
    register_sample,
)

__all__ = [
    "DEVICE_CPU",
    "BENCH_DEBUG",
    "FRAMEWORK",
    "SAMPLE_IMPL",
    "Settings",
    "FrameType",
    "TorchModes",
    "TFModes",
    "JAXModes",
    "SampleTag",
    "SampleSource",
    "SampleConfig",
    "random_shape",
    "trans_to_np",
    "auto_import",
    "auto_register",
    "register_sample",
    "build_pytree",
    "unfold_custom_class"
]


from cgi import test
from tkinter.ttk import Progressbar
from tkinter import *
from PIL import ImageTk, Image
from numpy import imag

w=Tk()

#Indicamos las dimensiones y posicion inicial del la pantalla de carga
width_of_window = 427
height_of_window = 250
screen_width = w.winfo_screenwidth()
screen_height = w.winfo_screenheight()
x_coordinate = (screen_width/2)-(width_of_window/2)
y_coordinate = (screen_height/2)-(height_of_window/2)
w.geometry("%dx%d+%d+%d" %(width_of_window,height_of_window,x_coordinate,y_coordinate))

w.overrideredirect(1)

#Creamos la barra de progreso, su largo, color y orientacion(La parte que no carga)
s = ttk.Style()
s.theme_use('clam')
s.configure("red.Horizontal.TProgressbar", foreground='red', background='#4f4f4f')  #Color gris de la barra
progress=Progressbar(w,style="red.Horizontal.TProgressbar",orient=HORIZONTAL,length=500,mode='determinate',)

#La ventana que llama despues de cargar el splash screen
def new_win():
  # w.destroy()
    q=Tk()
    q.title('Main window')
    q.geometry('427x250')
    l1=Label(q,text='ADD TEXT HERE ',fg='grey',bg=None)
    l=('Calibri (Body)',24,'bold')
    l1.config(font=l)
    l1.place(x=80,y=100)

    q.mainloop()

#Barra de progreso
def bar():

    l4=Label(w,text='Cargando...',fg='white',bg=MainWindow)
    lst4=('Calibri (Body)',10)
    l4.config(font=lst4)
    l4.place(x=18,y=210)

    import time
    r=0
    for i in range(100):
        progress['value']=r
        w.update_idletasks()
        time.sleep(0.03)
        r=r+1

    w.destroy()
    #new_win()   #Llamamos a la otra ventana

progress.place(x=-10,y=235) #

#-----------------------Interfaz del splashScreen (Frame Principal)-------------------------
MainWindow='#800080'
Frame(w,width=427,height=241,bg=MainWindow).place(x=0,y=0)  #249794
b1=Button(w,width=10,height=1,text='Iniciar',command=bar,border=0,fg=MainWindow,bg='white')
b1.place(x=170,y=200)

#-----------Labels-------------------------

l1=Label(w,text='Detector de mascarilla',fg='white',bg=MainWindow)
lst1=('Calibri (Body)',18,'bold')
l1.config(font=lst1)
l1.place(x=100,y=80)

image = Image.open("images/mascarilla.png")
image = image.resize((50,50), Image.ANTIALIAS)
img = ImageTk.PhotoImage(image)
l2=Label(w,image=img,fg='white',bg=MainWindow)
l2.pack()
l2.place(x=40,y=80)

l3=Label(w,text='5T3-CO',fg='white',bg=MainWindow)
lst3=('Calibri (Body)',13)
l3.config(font=lst3)
l3.place(x=100,y=110)

w.mainloop()


import numpy as np
from matplotlib import pyplot as plt
from multiprocessing import Pool
import time

def timestep_i(args):
	"""Computes the next position and velocity for the ith mass
	"""
	i, x0, v0, G, m, dt = args
	a_i0 = a(i, x0, G, m)
	v_i1 = a_i0 * dt + v0[i]
	x_i1 = a_i0 * dt**2 + v0[i] * dt + x0[i]
	return i, x_i1, v_i1

def a(i, x, G, m):
	"""The acceleration of the ith mass."""
	x_i = x[i]
	x_j = remove_i(x, i)
	m_j = remove_i(m, i)
	diff = x_j - x_i
	mag3 = np.sum(diff**2, axis=1)**1.5
	result = G*np.sum(diff * (m_j / mag3)[:, np.newaxis], axis=0)
	return result

def remove_i(x, i):
	"""Drops the ith element of an array."""
	shape = (x.shape[0]-1,) + x.shape[1:]
	y = np.empty(shape, dtype=float)
	y[:i] = x[:i]
	y[i:] = x[i+1:]
	return y

def timestep(x0, v0, G, m, dt, pool):
	"""Computes the next position and velocity for all masses given
	initial conditions and a time step size.
	"""
	N = len(x0)
	tasks = [(i, x0, v0, G, m, dt) for i in range(N)]
	results = pool.map(timestep_i, tasks)
	x1 = np.empty(x0.shape, dtype=float)
	v1 = np.empty(v0.shape, dtype=float)
	for i, x_1, v_1 in results:
		x1[i] = x_1
		v1[i] = v_1
	return x1, v1

def initial_cond(N, D):
	"""Generates initial conditions for N unity masses at rest
	starting at random positions in D-dimensional space."""
	x0 = np.random.rand(N, D)
	v0 = np.zeros((N, D), dtype=float)
	m = np.ones(N, dtype=float)
	return x0, v0, m

def simulate(P, N, D, S, G, dt):
	x0, v0, m = initial_cond(N, D)
	pool = Pool(P)
	for s in range(S):
		x1, v1 = timestep(x0, v0, G, m, dt, pool)
		x0, v0 = x1, v1
if __name__ == '__main__':
	Ps = [1, 2, 4, 8, 16]
	runtimes = []
	for P in Ps:
		start = time.time()
		simulate(P, 256, 3, 100, 1.0, 1.0e-3)
		stop = time.time()
		runtimes.append(stop - start)

	plt.figure(figsize=(5,5))
	plt.plot(np.array(Ps), runtimes[0]/np.array(runtimes), '.-')
	plt.show()


# -*- coding: utf-8 -*-
# 例外処理
def judge_bmi():
    result = ""
    while True:
        try:
            weight = float(input("kg? "))
            height = float(input("cm? "))
            height = height / 100
            bmi = weight / (height * height)
            break
        except ValueError as e:
            print(e)
        except ZeroDivisionError as e:
            print(e)
        except:
            print("その他のエラー")
        # 必ず最後に実行する
        # finally:
    if bmi < 18.5:
        result = "痩せ型"
    elif bmi < 25:
        result = "標準体型"
    elif bmi < 30:
        result = "肥満(軽)"
    else:
        result = "肥満(重)"
    return result

print(judge_bmi())

# エラーの発生
# raise Exception("Sample Error")

def for_func(iterable, callback):
    it = iter(iterable)
    while True:
        try:
            v = next(it)
            callback(v)
        except StopIteration:
            break
nums = [n for n in range(1, 11)]
for_func(nums, lambda i: print(i))

ages = {"Taro":20, "Jiro":15, "Saburo":10}
for_func(ages.items(), lambda n: print(n))


amt = int(input())
for i in range(amt):
	line = input().rstrip()
	max_below = 0
	current_level = 0
	for each_char in line:
		if each_char == 'v':
			current_level -= 1
			max_below = min(max_below, current_level)
		if each_char == "^":
			current_level += 1
	print(abs(max_below))


from __future__ import annotations

import typing as t

from django.http import HttpResponseRedirect
from django.utils import timezone
from django.shortcuts import render, get_object_or_404
from django.urls import reverse as reverse_url
from django.db.models import F

if t.TYPE_CHECKING:
    from django.http import HttpRequest

from .models import Question, Choice

def index(request: HttpRequest):
    """
    Return the last five published questions (not including those set to be
    published in the future).
    """
    latest_question_list = Question.objects.filter(
        published_date__lte=timezone.now(),
    ).order_by('-published_date')[:5]

    return render(
        request,
        "polls/index.html",
        {"latest_question_list": latest_question_list},
    )

def detail(request: HttpRequest, question_id):
    question = get_object_or_404(
        Question.objects.filter(published_date__lte=timezone.now()),
        pk=question_id,
    )

    return render(
        request,
        "polls/detail.html",
        {"question": question},
    )

def results(request: HttpRequest, question_id):
    question = get_object_or_404(Question, pk=question_id)

    return render(
        request,
        "polls/results.html",
        {"question": question},
    )

def vote(request: HttpRequest, question_id):
    question = get_object_or_404(Question, pk=question_id)

    try:
        selected_choice: Choice = question.choice_set.get(
            pk=request.POST['choice'],
        )
    except (KeyError, Choice.DoesNotExist):
        # Redisplay the question voting form.
        return render(
            request,
            'polls/detail.html',
            {
                'question': question,
                'error_message': "You didn't select a choice.",
            },
        )
    else:
        selected_choice.votes = F("votes") + 1
        selected_choice.save()

        return HttpResponseRedirect(
            reverse_url(
                "polls:results",
                args=[question.id],
            ),
        )


import random
import urllib.request

def download_web_url(url):
    x=random.randrange(1,1000)
    save_filename = str(x) + "_py_download_test.jpg"
    urllib.request.urlretrieve(url,save_filename)

for i in range(1,20):
    download_web_url("http://www.photohumor.com/joomla/images/Iran%20supports%20Hillary%202016.jpg")