# Rapid Roll Lite 1.0
# By Arnob Paul
# https://arnobpl.github.io
# arnobpl@gmail.com

# The following values are game settings

Screen_Width = 1280
Screen_Height = 720
Screen_Center = 1
Screen_Left = 10
Screen_Top = 10
Full_Screen = 0
Focus_Locked = 1
Game_Speed = 30

building_width_screen = 0.25

safe_bar_width0 = 160
safe_bar_width1 = 200
safe_bar_width2 = 280

danger_bar_width0 = 160
danger_bar_width1 = 200
danger_bar_width2 = 280

window_difference_x = 200
window_difference_y = 200
first_window_x = 40
window_floor_distance = 57
karnisa_length = 100
window_karnisa_distance = 5

game_speed_factor = 1.0001
bar_create_frequency = 100
bar_move_step = 3
bar_type_condition = 80
safe_bar_size_condition0 = 30
safe_bar_size_condition1 = 70
danger_bar_size_condition0 = 30
danger_bar_size_condition1 = 70
max_danger_bar_once = 2
safe_bar_animation_condition = 8
danger_bar_animation_condition = 2

cloud_enabled = 1
cloud_create_frequency0 = 7
cloud_create_frequency1 = 15
cloud_move_step0 = 1
cloud_move_step1 = 2
cloud_scale = 0.7

initial_ball_position = 0.75
ball_move_step_x_keyboard_enabled = 1
ball_move_step_x_keyboard = 15
ball_move_step_x_keyboard_acceleration = 4
ball_move_step_x_mouse_enabled = 1
ball_move_step_y = 10
ball_move_step_y_acceleration = 1
ball_crashed_delay = 30

initial_life_items_gain = 2
max_life_items_gain = 5
initial_life_item_create_condition = 15
life_item_create_condition_factor = 0.999
life_item_crashed_delay = 10

data_directory_name = "Data"
icon_data_file_name = "rapid_roll_icon.png"
sprite_data_file_name = "rapid_roll_sprites.png"

# The above values are game settings

def f_range(start, stop, step):
    if step == 0 or (start > stop and step > 0) or (start < stop and step < 0):
        return []
    if start > stop:
        start, stop = stop, start
        step *= -1
    f_list = []
    while start < stop:
        f_list.append(start)
        start += step
    return f_list

def lerp(value, start, stop, step):
    value += step
    if value < start:
        return start, -step
    if value > stop:
        return stop, -step
    return value, step

ERROR = 0
try:
    print("\nPress ESC to exit the game...")
    from time import sleep

    sleep(1)
    loading_str = "Loading, Please Wait..."
    print("\n\n" + loading_str + "\n\n")

    import os
    import sys

    data_directory_full_path = os.path.join(sys.path[0], data_directory_name)

    import pygame
    from random import randrange
    from math import ceil, floor
    from pygame.locals import *

    pygame.init()

    if Full_Screen:
        # Screen_Width = pygame.display.Info().current_w
        # Screen_Height = pygame.display.Info().current_h
        screen = pygame.display.set_mode((Screen_Width, Screen_Height), FULLSCREEN | HWSURFACE | DOUBLEBUF | NOFRAME)
    else:
        if Screen_Center:
            os.environ["SDL_VIDEO_CENTERED"] = "1"
        else:
            os.environ["SDL_VIDEO_WINDOW_POS"] = "\"" + str(Screen_Left) + "," + str(Screen_Top) + "\""
        screen = pygame.display.set_mode((Screen_Width, Screen_Height), HWSURFACE | DOUBLEBUF | NOFRAME)

    ERROR = 1
    font = pygame.font.Font(None, 40)
    screen.blit(font.render(loading_str, True, (255, 255, 255)), (
        (Screen_Width >> 1) - (font.size(loading_str)[0] >> 1),
        (Screen_Height >> 1) - (font.size(loading_str)[1] >> 1)))
    pygame.display.update()

    ERROR = 2
    pygame.display.set_icon(pygame.image.load(os.path.join(data_directory_full_path, icon_data_file_name)))

    ERROR = 3
    image_data = pygame.image.load(os.path.join(data_directory_full_path, sprite_data_file_name)).convert_alpha()

    # Initial loading successful
    ERROR = 0

except Exception as exception:
    try:
        pygame.quit()
    except:
        pass
    print('\n' * 150 + "Fatal Error!")
    print(exception)

    if ERROR == 0:
        print("Pygame module is missing or invalid.\nPlease install Pygame using the command: \"pip install pygame\"")
    elif ERROR == 1:
        print("Font component of Pygame module is missing or invalid.")
    elif ERROR == 2:
        print("\"" + icon_data_file_name + "\" file is missing or invalid.")
    elif ERROR == 3:
        print("\"" + sprite_data_file_name + "\" file is missing or invalid.")

    print("\n Support: arnobpl@gmail.com\n\n https://arnobpl.github.io\n\n\nPress ENTER to exit..." + '\n' * 8)
    input()

if ERROR == 0:

    # Background
    background_colour = 153, 217, 234
    background = pygame.Surface((round(Screen_Width * (1 - building_width_screen)), Screen_Height))
    R_step = 20
    R_start = background_colour[0] - R_step
    R_stop = background_colour[0] + R_step
    G_step = 20
    G_start = background_colour[1] - G_step
    G_stop = background_colour[1] + G_step
    B_step = 20
    B_start = background_colour[2] - B_step
    B_stop = background_colour[2] + B_step
    R = randrange(R_start, R_stop)
    G = randrange(G_start, G_stop)
    B = randrange(B_start, B_stop)
    background.fill((R, G, B))
    background_left = round(Screen_Width * building_width_screen / 2)

    # Ball
    ball = []
    ball.append(image_data.subsurface((0, 0, 40, 40)))
    ball.append(image_data.subsurface((40, 0, 40, 40)))
    ball.append(image_data.subsurface((80, 0, 40, 40)))
    ball.append(image_data.subsurface((120, 0, 40, 40)))
    ball.append(pygame.transform.flip(ball[2], True, False))
    ball.append(pygame.transform.flip(ball[1], True, False))
    ball.append(image_data.subsurface((160, 0, 40, 40)))

    # Life Item
    life_item = []
    life_item.append(image_data.subsurface((160, 40, 40, 40)))
    life_item.append(pygame.transform.flip(life_item[0], True, False))
    life_item.append(image_data.subsurface((160, 80, 40, 40)))
    life_item.append(pygame.transform.flip(life_item[2], True, False))

    # Safe Bar Main
    safe_bar = []
    safe_bar.append(image_data.subsurface((120, 40, 10, 20)))
    safe_bar.append(image_data.subsurface((130, 40, 10, 20)))
    safe_bar.append(pygame.transform.flip(safe_bar[1], True, False))

    # Safe Bar 0
    safe_bar0 = []
    safe_bar0.append(pygame.Surface((safe_bar_width0, 20), SRCALPHA, 32).convert_alpha())
    for i in range(10, safe_bar_width0 - 10, 10):
        safe_bar0[0].blit(safe_bar[0], (i, 0))
    safe_bar0[0].blit(safe_bar[1], (0, 0))
    safe_bar0[0].blit(safe_bar[2], (safe_bar_width0 - 10, 0))
    safe_bar0.append(pygame.transform.flip(safe_bar0[0], True, False))

    # Safe Bar 1
    safe_bar1 = []
    safe_bar1.append(pygame.Surface((safe_bar_width1, 20), SRCALPHA, 32).convert_alpha())
    for i in range(10, safe_bar_width1 - 10, 10):
        safe_bar1[0].blit(safe_bar[0], (i, 0))
    safe_bar1[0].blit(safe_bar[1], (0, 0))
    safe_bar1[0].blit(safe_bar[2], (safe_bar_width1 - 10, 0))
    safe_bar1.append(pygame.transform.flip(safe_bar1[0], True, False))

    # Safe Bar 2
    safe_bar2 = []
    safe_bar2.append(pygame.Surface((safe_bar_width2, 20), SRCALPHA, 32).convert_alpha())
    for i in range(10, safe_bar_width2 - 10, 10):
        safe_bar2[0].blit(safe_bar[0], (i, 0))
    safe_bar2[0].blit(safe_bar[1], (0, 0))
    safe_bar2[0].blit(safe_bar[2], (safe_bar_width2 - 10, 0))
    safe_bar2.append(pygame.transform.flip(safe_bar2[0], True, False))

    # Danger Bar Main
    danger_bar = []
    danger_bar.append(image_data.subsurface((140, 40, 10, 20)))
    danger_bar.append(image_data.subsurface((150, 40, 10, 20)))
    danger_bar.append(pygame.transform.flip(danger_bar[1], True, False))

    # Danger Bar 0
    danger_bar0 = []
    danger_bar0.append(pygame.Surface((danger_bar_width0, 20), SRCALPHA, 32).convert_alpha())
    for i in range(10, danger_bar_width0 - 10, 10):
        danger_bar0[0].blit(danger_bar[0], (i, 0))
    danger_bar0[0].blit(danger_bar[1], (0, 0))
    danger_bar0[0].blit(danger_bar[2], (danger_bar_width0 - 10, 0))
    danger_bar0.append(pygame.transform.flip(danger_bar0[0], True, False))

    # Danger Bar 1
    danger_bar1 = []
    danger_bar1.append(pygame.Surface((danger_bar_width1, 20), SRCALPHA, 32).convert_alpha())
    for i in range(10, danger_bar_width1 - 10, 10):
        danger_bar1[0].blit(danger_bar[0], (i, 0))
    danger_bar1[0].blit(danger_bar[1], (0, 0))
    danger_bar1[0].blit(danger_bar[2], (danger_bar_width1 - 10, 0))
    danger_bar1.append(pygame.transform.flip(danger_bar1[0], True, False))

    # Danger Bar 2
    danger_bar2 = []
    danger_bar2.append(pygame.Surface((danger_bar_width2, 20), SRCALPHA, 32).convert_alpha())
    for i in range(10, danger_bar_width2 - 10, 10):
        danger_bar2[0].blit(danger_bar[0], (i, 0))
    danger_bar2[0].blit(danger_bar[1], (0, 0))
    danger_bar2[0].blit(danger_bar[2], (danger_bar_width2 - 10, 0))
    danger_bar2.append(pygame.transform.flip(danger_bar2[0], True, False))

    # Top Spike Main
    top_spike = []
    top_spike.append(pygame.transform.flip(image_data.subsurface((120, 60, 10, 20)), False, True))
    top_spike.append(pygame.transform.flip(image_data.subsurface((130, 60, 10, 20)), False, True))
    top_spike.append(pygame.transform.flip(top_spike[1], True, False))

    # Top Spike Object
    top_spike_surface = pygame.Surface((background.get_width(), 20), SRCALPHA, 32).convert_alpha()
    for i in range(10, background.get_width() - 10, 10):
        top_spike_surface.blit(top_spike[0], (i, 0))
    top_spike_surface.blit(top_spike[1], (0, 0))
    top_spike_surface.blit(top_spike[2], (background.get_width() - 10, 0))

    # Bottom Spike Main
    bottom_spike = []
    bottom_spike.append(image_data.subsurface((140, 60, 10, 20)))
    bottom_spike.append(image_data.subsurface((150, 60, 10, 20)))
    bottom_spike.append(pygame.transform.flip(bottom_spike[1], True, False))

    # Bottom Spike Object
    bottom_spike_surface = pygame.Surface((background.get_width(), 20), SRCALPHA, 32).convert_alpha()
    for i in range(10, background.get_width() - 10, 10):
        bottom_spike_surface.blit(bottom_spike[0], (i, 0))
    bottom_spike_surface.blit(bottom_spike[1], (0, 0))
    bottom_spike_surface.blit(bottom_spike[2], (background.get_width() - 10, 0))

    # Cloud
    cloud = []
    cloud.append(image_data.subsurface((0, 40, 120, 80)))
    cloud.append(pygame.transform.flip(cloud[0], True, False))
    cloud.append(pygame.transform.smoothscale(cloud[0], (round(120 * cloud_scale), round(80 * cloud_scale))))
    cloud.append(pygame.transform.flip(cloud[2], True, False))

    # Display
    score_display = image_data.subsurface((160, 120, 40, 40))
    life_display = image_data.subsurface((160, 160, 40, 40))

    # Building Texture 0
    building_texture0 = [image_data.subsurface((120, 80, 15, 15)),
                         pygame.transform.rotate(image_data.subsurface((120, 112, 15, 2)), 90)]

    # Building Texture 1
    building_texture1 = [image_data.subsurface((135, 80, 25, 15)),
                         pygame.transform.rotate(image_data.subsurface((135, 112, 15, 2)), 90)]

    # Building Window 0
    building_window0 = [image_data.subsurface((0, 120, 80, 80))]

    # Building Window 1
    building_window1 = [image_data.subsurface((80, 120, 80, 80))]

    # Building Ornaments 0
    building_ornaments0 = [image_data.subsurface((120, 95, 20, 10)),
                           image_data.subsurface((120, 105, 20, 5)),
                           pygame.transform.rotate(image_data.subsurface((120, 110, 10, 2)), 90),
                           pygame.transform.rotate(image_data.subsurface((140, 110, 5, 2)), 90)]

    # Building Ornaments 1
    building_ornaments1 = [image_data.subsurface((140, 95, 20, 10)),
                           image_data.subsurface((140, 105, 20, 5)),
                           pygame.transform.rotate(image_data.subsurface((130, 110, 10, 2)), 90),
                           pygame.transform.rotate(image_data.subsurface((145, 110, 5, 2)), 90)]

    # Window Karnisa 0
    window_karnisa_surface0 = pygame.Surface((karnisa_length, 10), SRCALPHA, 32).convert_alpha()
    for i in range(0, karnisa_length, 20):
        window_karnisa_surface0.blit(building_ornaments0[0], (i, 0))
    window_karnisa_surface0.blit(building_ornaments0[2], (0, 0))
    window_karnisa_surface0.blit(pygame.transform.flip(building_ornaments0[2], True, False), (karnisa_length - 2, 0))

    # Window Karnisa 1
    window_karnisa_surface1 = pygame.Surface((karnisa_length, 10), SRCALPHA, 32).convert_alpha()
    for i in range(0, karnisa_length, 20):
        window_karnisa_surface1.blit(building_ornaments1[0], (i, 0))
    window_karnisa_surface1.blit(building_ornaments1[2], (0, 0))
    window_karnisa_surface1.blit(pygame.transform.flip(building_ornaments1[2], True, False), (karnisa_length - 2, 0))

    building_width = ceil(Screen_Width * building_width_screen / 2)

    building0 = pygame.Surface((building_width, Screen_Height + 14), SRCALPHA, 32).convert_alpha()
    for i in range(0, Screen_Height + 15, 15):
        for j in range(0, building_width + 15, 15):
            building0.blit(building_texture0[0], (j, i))
    for i in range(0, Screen_Height + 15, 15):
        building0.blit(building_texture0[1], (0, i))

    building1 = pygame.Surface((building_width, Screen_Height + 14), SRCALPHA, 32).convert_alpha()
    for i in range(0, Screen_Height + 15, 15):
        for j in range(0, building_width + 25, 25):
            building1.blit(building_texture1[0], (j, i))
    for i in range(0, Screen_Height + 15, 15):
        building1.blit(building_texture1[1], (0, i))

    building_window_surface0 = pygame.Surface((building_width, Screen_Height + window_difference_y - 1),
                                              SRCALPHA, 32).convert_alpha()
    for i in range(0, Screen_Height + window_difference_y, window_difference_y):
        for j in range(first_window_x, building_width + window_difference_x, window_difference_x):
            building_window_surface0.blit(building_window0[0], (j, i))
    for i in range(window_floor_distance + 80, Screen_Height + window_difference_y, window_difference_y):
        for j in range(0, building_width + window_difference_x, 20):
            building_window_surface0.blit(building_ornaments0[1], (j, i))
        building_window_surface0.blit(building_ornaments0[3], (0, i))
    for i in range(window_difference_y - window_karnisa_distance - 10, Screen_Height + window_difference_y,
                   window_difference_y):
        for j in range(first_window_x - round(karnisa_length / 2) + 40, building_width + window_difference_x,
                       window_difference_x):
            building_window_surface0.blit(window_karnisa_surface0, (j, i))

    building_window_surface1 = pygame.Surface((building_width, Screen_Height + window_difference_y - 1), SRCALPHA,
                                              32).convert_alpha()
    for i in range(0, Screen_Height + window_difference_y, window_difference_y):
        for j in range(first_window_x, building_width + window_difference_x, window_difference_x):
            building_window_surface1.blit(building_window1[0], (j, i))
    for i in range(window_floor_distance + 80, Screen_Height + window_difference_y, window_difference_y):
        for j in range(0, building_width + window_difference_x, 20):
            building_window_surface1.blit(building_ornaments1[1], (j, i))
        building_window_surface1.blit(building_ornaments1[3], (0, i))
    for i in range(window_difference_y - window_karnisa_distance - 10, Screen_Height + window_difference_y,
                   window_difference_y):
        for j in range(first_window_x - round(karnisa_length / 2) + 40, building_width + window_difference_x,
                       window_difference_x):
            building_window_surface1.blit(window_karnisa_surface1, (j, i))

    ball_list = []
    life_item_list = []
    safe_bar_list = []
    danger_bar_list = []
    cloud_list0 = []
    cloud_list1 = []
    building_list = []
    building_window_surface_list = []

    focus_has_lost = True
    bar_create_condition = 0
    danger_bar_once = 0
    safe_bar_animation_condition_value = 0
    danger_bar_animation_condition_value = 0
    safe_bar_animation_value = 0
    danger_bar_animation_value = 0
    cloud_create_condition0 = 0
    cloud_create_condition1 = 0
    no_ball_state = True
    ball_crashed = False
    life_item_crashed = False
    ball_move_step_x_keyboard_state = 0
    ball_animation_value = 0
    ball_crashed_delay_value = 0
    life_item_crashed_delay_value = 0
    building_left_right_selector = randrange(0, 2)
    score = 0
    life_items_gain = initial_life_items_gain
    danger_item_collided = False

    bar_move_step_value = bar_move_step
    cloud_move_step0_value = cloud_move_step0
    cloud_move_step1_value = cloud_move_step1
    life_item_create_condition = initial_life_item_create_condition

    ball_move_step_y_value = ball_move_step_y
    ball_move_step_x_keyboard_value = ball_move_step_x_keyboard

    if cloud_enabled:
        for i in f_range(Screen_Height - cloud_create_frequency0, -cloud[2].get_height(),
                         -cloud_create_frequency0 - cloud_move_step0):
            cloud_type = randrange(2, 4)
            max_cloud_position = background.get_width() - cloud[2].get_width() + background_left
            cloud_position = randrange(background_left - cloud[2].get_width(),
                                       max_cloud_position + cloud[2].get_width())
            cloud_list0.append([[cloud[cloud_type]], [cloud_position, i]])
        cloud_list0.reverse()

        for i in f_range(Screen_Height - cloud_create_frequency1, -cloud[0].get_height(),
                         -cloud_create_frequency1 - cloud_move_step1):
            cloud_type = randrange(0, 2)
            max_cloud_position = background.get_width() - cloud[0].get_width() + background_left
            cloud_position = randrange(background_left - cloud[0].get_width(),
                                       max_cloud_position + cloud[0].get_width())
            cloud_list1.append([[cloud[cloud_type]], [cloud_position, i]])
        cloud_list1.reverse()

    if building_left_right_selector == 0:
        building_list.append([pygame.transform.flip(building0, True, False), [background_left - building_width, 0], 15])
        building_list.append([building1, [background_left + background.get_width(), 0], 15])
        building_window_surface_list.append(
            [pygame.transform.flip(building_window_surface0, True, False), [background_left - building_width, 0],
             window_difference_y])
        building_window_surface_list.append(
            [building_window_surface1, [background_left + background.get_width(), 0], window_difference_y])
    else:
        building_list.append([pygame.transform.flip(building1, True, False), [background_left - building_width, 0], 15])
        building_list.append([building0, [background_left + background.get_width(), 0], 15])
        building_window_surface_list.append(
            [pygame.transform.flip(building_window_surface1, True, False), [background_left - building_width, 0],
             window_difference_y])
        building_window_surface_list.append(
            [building_window_surface0, [background_left + background.get_width(), 0], window_difference_y])

    r_step = 0.1
    g_step = -0.2
    b_step = -0.3

    pygame.mouse.set_visible(False)
    clock = pygame.time.Clock()
    print('\n' * 150)
    while True:

        clock.tick(Game_Speed)

        background.fill((R, G, B))
        screen.blit(background, (background_left, 0))
        R, r_step = lerp(R, R_start, R_stop, r_step)
        G, g_step = lerp(G, G_start, G_stop, g_step)
        B, b_step = lerp(B, B_start, B_stop, b_step)

        if bar_create_condition == 0:
            bar_type = randrange(0, 100)
            bar_size = randrange(0, 100)
            if bar_type < bar_type_condition or danger_bar_once >= max_danger_bar_once:
                danger_bar_once = 0
                life_item_create = randrange(0, 100)
                if bar_size < safe_bar_size_condition0:
                    max_bar_position = background.get_width() - safe_bar_width0 + background_left
                    bar_position = randrange(background_left, max_bar_position)
                    safe_bar_list.append([safe_bar0, [bar_position, Screen_Height + 40]])
                    if life_item_create < life_item_create_condition:
                        max_life_item_position = bar_position + safe_bar_width0 - 40
                        life_item_position = randrange(bar_position, max_life_item_position)
                        if life_item_position < round(Screen_Width / 2):
                            life_item_type = 0
                        else:
                            life_item_type = 1
                        life_item_list.append([[life_item[life_item_type]], [life_item_position, Screen_Height]])
                elif bar_size < safe_bar_size_condition1:
                    max_bar_position = background.get_width() - safe_bar_width1 + background_left
                    bar_position = randrange(background_left, max_bar_position)
                    safe_bar_list.append([safe_bar1, [bar_position, Screen_Height + 40]])
                    if life_item_create < life_item_create_condition:
                        max_life_item_position = bar_position + safe_bar_width1 - 40
                        life_item_position = randrange(bar_position, max_life_item_position)
                        if life_item_position < round(Screen_Width / 2):
                            life_item_type = 0
                        else:
                            life_item_type = 1
                        life_item_list.append([[life_item[life_item_type]], [life_item_position, Screen_Height]])
                else:
                    max_bar_position = background.get_width() - safe_bar_width2 + background_left
                    bar_position = randrange(background_left, max_bar_position)
                    safe_bar_list.append([safe_bar2, [bar_position, Screen_Height + 40]])
                    if life_item_create < life_item_create_condition:
                        max_life_item_position = bar_position + safe_bar_width2 - 40
                        life_item_position = randrange(bar_position, max_life_item_position)
                        if life_item_position < round(Screen_Width / 2):
                            life_item_type = 0
                        else:
                            life_item_type = 1
                        life_item_list.append([[life_item[life_item_type]], [life_item_position, Screen_Height]])
            else:
                danger_bar_once += 1
                if bar_size < danger_bar_size_condition0:
                    max_bar_position = background.get_width() - danger_bar_width0 + background_left
                    bar_position = randrange(background_left, max_bar_position)
                    danger_bar_list.append([danger_bar0, [bar_position, Screen_Height + 40]])
                elif bar_size < danger_bar_size_condition1:
                    max_bar_position = background.get_width() - danger_bar_width1 + background_left
                    bar_position = randrange(background_left, max_bar_position)
                    danger_bar_list.append([danger_bar1, [bar_position, Screen_Height + 40]])
                else:
                    max_bar_position = background.get_width() - danger_bar_width2 + background_left
                    bar_position = randrange(background_left, max_bar_position)
                    danger_bar_list.append([danger_bar2, [bar_position, Screen_Height + 40]])

        if cloud_enabled and cloud_create_condition0 == 0:
            cloud_type = randrange(2, 4)
            max_cloud_position = background.get_width() - cloud[2].get_width() + background_left
            cloud_position = randrange(background_left - cloud[2].get_width(),
                                       max_cloud_position + cloud[2].get_width())
            cloud_list0.append([[cloud[cloud_type]], [cloud_position, Screen_Height]])

        if cloud_enabled and cloud_create_condition1 == 0:
            cloud_type = randrange(0, 2)
            max_cloud_position = background.get_width() - cloud[0].get_width() + background_left
            cloud_position = randrange(background_left - cloud[0].get_width(),
                                       max_cloud_position + cloud[0].get_width())
            cloud_list1.append([[cloud[cloud_type]], [cloud_position, Screen_Height]])

        for i in cloud_list0:
            screen.blit(i[0][0], (round(i[1][0]), round(i[1][1])))
            i[1][1] -= cloud_move_step0_value

        for i in cloud_list1:
            screen.blit(i[0][0], (round(i[1][0]), round(i[1][1])))
            i[1][1] -= cloud_move_step1_value

        for i in safe_bar_list[::-1]:
            screen.blit(i[0][safe_bar_animation_value], (round(i[1][0]), round(i[1][1])))
            if no_ball_state and i[1][1] <= round(initial_ball_position * Screen_Height) and life_items_gain >= 0:
                ball_list.append(ball[ball_animation_value])
                ball_list.append([i[1][0] - 20 + round(i[0][0].get_width() / 2), i[1][1] - 40])
                if pygame.mouse.get_focused(): pygame.mouse.set_pos(ball_list[1])
                no_ball_state = False
                danger_item_collided = False
            i[1][1] -= bar_move_step_value

        if life_items_gain < 0 and (not ball_crashed):
            pygame.quit()
            print("Game is over!\nYour score is " + str(
                round(score * 0.1)) + ".\nThank you for playing this mini-game.\n\n\nPress ENTER to exit..." + '\n' * 8)
            input()
            break

        for i in danger_bar_list:
            screen.blit(i[0][danger_bar_animation_value], (round(i[1][0]), round(i[1][1])))
            i[1][1] -= bar_move_step_value

        if not no_ball_state:
            if not ball_crashed: ball_list[0] = ball[ball_animation_value]
            screen.blit(ball_list[0], (round(ball_list[1][0]), round(ball_list[1][1])))

        for i in life_item_list:
            screen.blit(i[0][0], (round(i[1][0]), round(i[1][1])))
            i[1][1] -= bar_move_step_value

        for i in building_list, building_window_surface_list:
            for j in range(0, 2):
                i[j][1][1] -= bar_move_step_value % i[j][2]
                if i[j][1][1] <= -i[j][2]:
                    i[j][1][1] += i[j][2]
                screen.blit(i[j][0], (round(i[j][1][0]), round(i[j][1][1])))

        screen.blit(top_spike_surface, (background_left, 0))
        screen.blit(bottom_spike_surface, (background_left, Screen_Height - 20))

        screen.blit(score_display, (10, Screen_Height - 50))
        screen.blit(font.render(str(round(score * 0.1)), True, (0, 0, 0)), (51, Screen_Height - 39))
        screen.blit(font.render(str(round(score * 0.1)), True, (38, 255, 125)), (50, Screen_Height - 40))
        screen.blit(life_display, (Screen_Width - 150, Screen_Height - 47))
        screen.blit(font.render(str(life_items_gain), True, (0, 0, 0)), (Screen_Width - 99, Screen_Height - 39))
        screen.blit(font.render(str(life_items_gain), True, (255, 127, 39)), (Screen_Width - 100, Screen_Height - 40))

        pygame.display.update()

        bar_create_condition += bar_move_step_value
        if bar_create_condition > bar_create_frequency:
            bar_create_condition = 0

        safe_bar_animation_condition_value += 1
        if safe_bar_animation_condition_value > safe_bar_animation_condition:
            safe_bar_animation_value += 1
            if safe_bar_animation_value > 1: safe_bar_animation_value = 0
            safe_bar_animation_condition_value = 0

        danger_bar_animation_condition_value += 1
        if danger_bar_animation_condition_value > danger_bar_animation_condition:
            danger_bar_animation_value += 1
            if danger_bar_animation_value > 1: danger_bar_animation_value = 0
            danger_bar_animation_condition_value = 0

        cloud_create_condition0 += cloud_move_step0_value
        if cloud_create_condition0 > cloud_create_frequency0:
            cloud_create_condition0 = 0

        cloud_create_condition1 += cloud_move_step1_value
        if cloud_create_condition1 > cloud_create_frequency1:
            cloud_create_condition1 = 0

        if ball_crashed:
            ball_crashed_delay_value += 1
            if ball_crashed_delay_value > ball_crashed_delay:
                ball_crashed_delay_value = 0
                ball_crashed = False
                ball_list.clear()
                no_ball_state = True

        if life_item_crashed:
            life_item_crashed_delay_value += 1
            if life_item_crashed_delay_value > life_item_crashed_delay:
                life_item_crashed_delay_value = 0
                life_item_crashed = False
                i = 0
                while i < len(life_item_list):
                    if life_item_list[i][0][0] == life_item[2] or life_item_list[i][0][0] == life_item[3]:
                        del life_item_list[i]
                        i -= 1
                    i += 1

        for i in safe_bar_list, danger_bar_list, cloud_list0, cloud_list1, life_item_list:
            j = 0
            while j < len(i):
                if i[j][1][1] + i[j][0][0].get_height() <= 0:
                    del i[j]
                    j -= 1
                j += 1

        pygame.event.pump()
        keystate = pygame.key.get_pressed()
        event = pygame.event.poll()
        if not pygame.mouse.get_focused():
            focus_has_lost = True
            if Focus_Locked:
                if not no_ball_state:
                    pygame.mouse.set_pos(ball_list[1])
                else:
                    pygame.mouse.set_pos((0, 0))
        if keystate[K_ESCAPE]:
            pygame.quit()
            break
        if (not no_ball_state) and (not ball_crashed):
            if ball_move_step_x_keyboard_enabled and keystate[K_LEFT]:
                if ball_list[1][0] - ball_move_step_x_keyboard_value > background_left:
                    ball_list[1][0] -= ball_move_step_x_keyboard_value
                    ball_move_step_x_keyboard_state = -1
                    if ball_move_step_x_keyboard_state == -1: ball_move_step_x_keyboard_value += ball_move_step_x_keyboard_acceleration
                    ball_animation_value += 1
                    if ball_animation_value > 5: ball_animation_value = 0
                else:
                    ball_list[1][0] = background_left
                if pygame.mouse.get_focused(): pygame.mouse.set_pos(ball_list[1])
            elif ball_move_step_x_keyboard_enabled and keystate[K_RIGHT]:
                if ball_list[1][0] + ball_move_step_x_keyboard_value < background_left + background.get_width() - 40:
                    ball_list[1][0] += ball_move_step_x_keyboard_value
                    ball_move_step_x_keyboard_state = +1
                    if ball_move_step_x_keyboard_state == +1: ball_move_step_x_keyboard_value += ball_move_step_x_keyboard_acceleration
                    ball_animation_value -= 1
                    if ball_animation_value < 0: ball_animation_value = 5
                else:
                    ball_list[1][0] = background_left + background.get_width() - 40
                if pygame.mouse.get_focused(): pygame.mouse.set_pos(ball_list[1])
            elif ball_move_step_x_mouse_enabled and event.type == MOUSEMOTION:
                if Focus_Locked or (not focus_has_lost):
                    mouse_pos_x = pygame.mouse.get_pos()[0]
                    if mouse_pos_x < ball_list[1][0]:
                        if mouse_pos_x >= background_left:
                            ball_list[1][0] = mouse_pos_x
                            ball_animation_value += 1
                            if ball_animation_value > 5: ball_animation_value = 0
                        else:
                            ball_list[1][0] = background_left
                            if pygame.mouse.get_focused(): pygame.mouse.set_pos(ball_list[1])
                    elif mouse_pos_x > ball_list[1][0]:
                        if mouse_pos_x <= background_left + background.get_width() - 40:
                            ball_list[1][0] = mouse_pos_x
                            ball_animation_value -= 1
                            if ball_animation_value < 0: ball_animation_value = 5
                        else:
                            ball_list[1][0] = background_left + background.get_width() - 40
                            if pygame.mouse.get_focused(): pygame.mouse.set_pos(ball_list[1])
                else:
                    if pygame.mouse.get_focused(): pygame.mouse.set_pos(ball_list[1])
                    focus_has_lost = False
            else:
                ball_move_step_x_keyboard_state = 0
                ball_move_step_x_keyboard_value = ball_move_step_x_keyboard

        if (not no_ball_state) or ball_crashed:
            ball_collided = False
            for i in safe_bar_list:
                if i[1][1] + bar_move_step_value > 60 and i[1][1] - 40 < ball_list[1][
                    1] + ball_move_step_y_value and ceil(i[1][1] - 40 + bar_move_step_value - ball_list[1][1]) >= 0 and \
                        i[1][0] - 20 <= ball_list[1][0] < i[1][0] + i[0][0].get_width() - 20:
                    ball_list[1][1] = i[1][1] - 40
                    ball_collided = True
                    ball_move_step_y_value = ball_move_step_y
                    for j in life_item_list:
                        if j[1][0] - 40 <= ball_list[1][0] < j[1][0] + 40 and ceil(j[1][1]) == ceil(i[1][1]) - 40 and (
                                j[0][0] == life_item[0] or j[0][0] == life_item[1]):
                            if j[0][0] == life_item[0]:
                                j[0][0] = life_item[2]
                            else:
                                j[0][0] = life_item[3]
                            life_item_crashed = True
                            if life_items_gain < max_life_items_gain: life_items_gain += 1
                            break
                    break
            if not ball_collided:
                for i in danger_bar_list:
                    if (
                            i[1][1] + bar_move_step_value > 60 and
                            i[1][1] - 40 < ball_list[1][1] + ball_move_step_y_value and
                            ceil(i[1][1] - 40 + bar_move_step_value - ball_list[1][1]) >= 0 and
                            i[1][0] - 20 <= ball_list[1][0] < i[1][0] + i[0][0].get_width() - 20
                    ):
                        ball_list[1][1] = i[1][1] - 40
                        ball_collided = True
                        ball_move_step_y_value = ball_move_step_y
                        ball_list[0] = ball[6]
                        ball_crashed = True
                        if not danger_item_collided:
                            life_items_gain -= 1
                            danger_item_collided = True
                        break
            if not ball_collided:
                if ball_list[1][1] <= 20:
                    ball_collided = True
                    ball_move_step_y_value = ball_move_step_y
                    ball_list[0] = ball[6]
                    ball_crashed = True
                    if not danger_item_collided:
                        life_items_gain -= 1
                        danger_item_collided = True
            if not ball_collided:
                if ball_list[1][1] + ball_move_step_y_value > Screen_Height - 60:
                    ball_list[1][1] = Screen_Height - 60
                    ball_collided = True
                    ball_move_step_y_value = ball_move_step_y
                    ball_list[0] = ball[6]
                    ball_crashed = True
                    if not danger_item_collided:
                        life_items_gain -= 1
                        danger_item_collided = True
            if not ball_collided:
                ball_list[1][1] += ball_move_step_y_value
                score += ball_move_step_y_value + bar_move_step_value
                ball_move_step_y_value += ball_move_step_y_acceleration

        bar_move_step_value *= game_speed_factor
        cloud_move_step0_value *= game_speed_factor
        cloud_move_step1_value *= game_speed_factor
        life_item_create_condition *= life_item_create_condition_factor


from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.conf.urls import patterns, include, url
from django.http import HttpResponseRedirect
from wordgap.views import *
import settings

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',

    (r"^testjson/$", testjson),
    (r"^wordlist/$", wordlist),
    (r"^post/$", getjson),
    (r"^wordgap/$", testex),
    (r"^wordgap/(?P<filename>\w+)/(?P<pos>[a-z]{1})/(?P<wordnet>\w*)/$", testex),

    (r"^wordgap/result/$", result),
    (r"^wordgap/(?P<sentenceNo>\d+)/$", showSentence),
    #(r"^wordgap/(?P<sentenceNo>\d+)/(?P<merken>merken)/$", showSentence),
    (r"^wordgap/(?P<sentenceNo>\d+)/(?P<choice>\d{1})/$", showSentence),
    (r"^wordgap/(?P<sentenceNo>\d+)/(\d{1}/)*(?P<choice>\d{1})/$", showSentence),

    (r"^wordgap/result/$", result),

    (r"^ex/$", testex),
    (r"^ex/(?P<sentenceNo>\d+)/$", showSentence),
    #(r"^ex/(?P<sentenceNo>\d+)/(?P<merken>merken)/$", showSentence),
    (r"^ex/(?P<sentenceNo>\d+)/(?P<choice>\d{1})/$", showSentence),
    (r"^ex/(?P<sentenceNo>\d+)/(\d{1}/)*(?P<choice>\d{1})/$", showSentence),

    (r"^ex/result/$", result),

    # root
    (r"^$", lambda x: HttpResponseRedirect('/ex')),
    # Examples:
    # url(r'^$', 'wordgap.views.home', name='home'),
    # url(r'^wordgap/', include('wordgap.foo.urls')),

    # Uncomment the admin/doc line below to enable admin documentation:
     url(r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
     url(r'^admin/', include(admin.site.urls)),
    #(r'^static/(?P<path>.*)$', 'django.views.static.serve',{'document_root': settings.MEDIA_ROOT}),
    (r'^img/(?P<path>.*)$', 'django.views.static.serve',  {'document_root': settings.MEDIA_ROOT}),

    (r'^static/img/(?P<path>.*)$', 'django.views.static.serve',
        {'document_root': '/static', 'show_indexes': True}),
)
# for static files like images
urlpatterns += patterns('',
    (r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
    {'document_root': settings.MEDIA_ROOT,
    'show_indexes' : True}),
)


import os
from django.contrib.gis.utils import LayerMapping
from .models import Counties

countie_mapping = {
    'province': 'PROVINCE',
    'province_c': 'PROVINCE_C',
    'district': 'DISTRICT',
    'district_c': 'DISTRICT_C',
    'remarks': 'Remarks',
    'm_20110324': 'M_20110324',
    'd_name': 'D_NAME',
    'geom': 'MULTIPOLYGON',
}

county_shp = os.path .abspath(os.path.join(os.path.dirname(__file__),'data2/counties.shp'))

def run(verbose=True):
	lm = LayerMapping(Counties, county_shp, countie_mapping, transform= False, encoding='iso-8859-1')
	lm.save(strict=True,verbose=verbose)


from ray.rllib.agents.ddpg.ddpg_tf_model import DDPGTFModel
from xarl.models.adaptive_model_wrapper import get_tf_heads_model, get_heads_input, tf

class TFAdaptiveMultiHeadDDPG(DDPGTFModel):
    def __init__(self, obs_space, action_space, num_outputs, model_config, name, actor_hiddens=(256, 256), actor_hidden_activation="relu", critic_hiddens=(256, 256), critic_hidden_activation="relu", twin_q=False, add_layer_norm=False):
        inputs, last_layer = get_tf_heads_model(obs_space)
        super().__init__(obs_space=obs_space, action_space=action_space, num_outputs=last_layer.shape[1], model_config=model_config, name=name, actor_hiddens=actor_hiddens, actor_hidden_activation=actor_hidden_activation, critic_hiddens=critic_hiddens, critic_hidden_activation=critic_hidden_activation, twin_q=twin_q, add_layer_norm=add_layer_norm)
        self.heads_model = tf.keras.Model(inputs, last_layer)
        self.register_variables(self.heads_model.variables)

    def forward(self, input_dict, state, seq_lens):
        model_out = self.heads_model(get_heads_input(input_dict))
        return model_out, state


from confluent_kafka import Producer
from confluent_kafka.admin import AdminClient, NewTopic
from src import logger
from src.config import get_settings
from src.schemas import EntitiesResponse

settings = get_settings()

print(settings.kafka_bootstrap_servers)

async def create_topic():
    admin_client = AdminClient({"bootstrap.servers": settings.kafka_bootstrap_servers})
    new_topic = NewTopic(
        topic=settings.kafka_topic_name,
        num_partitions=settings.kafka_topic_partitions,
        replication_factor=settings.kafka_topic_replication_factor,
    )
    future_created = admin_client.create_topics([new_topic])
    for topic, future in future_created.items():
        try:
            future.result()
            logger.info("Topic %s created", topic)
        # pylint: disable=broad-exception-caught
        except Exception as ex:
            logger.error("Failed to create topic %s error= %s", topic, str(ex))

def delivery_report(err, msg):
    if err is not None:
        logger.error("Message delivery failed: %s", str(err))
    else:
        logger.debug("Message delivered to %s [%s]", msg.topic(), str(msg.partition()))

async def produce_event(data: EntitiesResponse):
    json_data = data.json()
    producer = Producer({"bootstrap.servers": settings.kafka_bootstrap_servers})
    producer.poll(0)
    producer.produce(
        settings.kafka_topic_name, json_data.encode("utf-8"), callback=delivery_report
    )
    producer.flush()


from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service
import time

FORM_LINK = 'https://docs.google.com/forms/d/e/1FAIpQLScOkQbo9fi5ea9ib2Pfs5BrLh8oGKvTnnGk3ekrVkTM0cxR0Q/viewform?usp=sf_link'

class GoogleForms:
    def __init__(self) -> None:
        self.driver = self.create_driver()

    def max_screen(self):
        self.driver.maximize_window()

    def create_driver(self):
        service = Service(executable_path='C:\Development\chromedriver.exe')
        option = webdriver.ChromeOptions()
        option.add_experimental_option('detach', True)
        option.add_experimental_option('excludeSwitches', ['enable-logging'])
        return webdriver.Chrome(service=service, options=option)

    def update_google_form(self, property_data: dict):
        for key in property_data:
            self.driver.get(url=FORM_LINK)
            time.sleep(2)
            addr = self.driver.find_element(
                By.XPATH, '//*[@id="mG61Hd"]/div[2]/div/div[2]/div[1]/div/div/div[2]/div/div[1]/div/div[1]/input')
            addr.send_keys(property_data[key]['address'])

            price = self.driver.find_element(
                By.XPATH, '//*[@id="mG61Hd"]/div[2]/div/div[2]/div[2]/div/div/div[2]/div/div[1]/div/div[1]/input')
            price.send_keys(property_data[key]['rent_price'])

            lnk = self.driver.find_element(
                By.XPATH, '//*[@id="mG61Hd"]/div[2]/div/div[2]/div[3]/div/div/div[2]/div/div[1]/div/div[1]/input')
            lnk.send_keys(property_data[key]['link_to_property'])

            self.driver.find_element(
                By.XPATH, '//*[@id="mG61Hd"]/div[2]/div/div[3]/div[1]/div[1]/div/span').click()
        self.driver.quit()


import sympy

def rec(input,file):
    if input.isnumeric() or input == "x":
        return input
    else:
        output = "("
        for s in input.split(" "):
            if s in ["+","-","*","/","=","x"]:
                output += s
            else:
                output += rec(file[s],file)
        return output+")"

def part2():
    file = {r.split(":")[0]:r.split(":")[1].replace("\n","").strip() for r in open('input.txt','r')}
    tmp = rec(file["root"],file)
    x = sympy.symbols('x')
    y = sympy.sympify(tmp[1:-1].split("=")[0])
    z = sympy.sympify(str(eval(tmp[1:-1].split("=")[1])))
    print(sympy.solve(sympy.Eq(y,z),x))

part2()


import cv2
import numpy as np

# Loading the Image
image = cv2.imread('19.BMP')
cv2.waitKey(0)

# Grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Denoising the image
denoised = cv2.fastNlMeansDenoising(gray, None,40,13,31)

# Canny edge detection
canny = cv2.Canny(denoised, 30, 200)

# Thresholding the image.
_, threshold = cv2.threshold(canny, 127, 255, cv2.THRESH_BINARY)

# Finding Contours on the Binary image
contours, hierarchy = cv2.findContours(threshold,
	cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.imshow('Threshold image: ', threshold)
cv2.waitKey(0)

print("Number of Contours found = " + str(len(contours)))

# Finding the max length in the Contours found
cnt = [cv2.arcLength(cnt,True) for cnt in contours]
a = contours[cnt.index(max(cnt))]

# Drawing the contour on the image
cv2.drawContours(image, [a], 0, (0, 255, 0), 3)
cv2.imshow('Contours', image)
cv2.waitKey(0)
cv2.destroyAllWindows()


"""Decoding functions using multiple attentions for RNN decoders.

See http://arxiv.org/abs/1606.07481

The attention mechanisms used in Neural Monkey are inherited from the
``BaseAttention`` class defined in this module.

Each attention object has the ``attention`` function which operates on the
``attention_states`` tensor.  The attention function receives the query tensor,
the decoder previous state and input, and its inner state, which could bear an
arbitrary structure of information. The default structure for this is the
``AttentionLoopState``, which contains a growing array of attention
distributions and context vectors in time. That's why there is the
``initial_loop_state`` function in the ``BaseAttention`` class.

Mainly for illustration purposes, the attention objects can keep their
*histories*, which is a dictionary populated with attention distributions in
time for every decoder, that used this attention object. This is because for
example the recurrent decoder is can be run twice for each sentence - once in
the *training* mode, in which the decoder gets the reference tokens on the
input, and once in the *running* mode, in which it gets its own outputs. The
histories object is constructed *after* the decoding and its construction
should be triggered manually from the decoder by calling the ``finalize_loop``
method.
"""
from typing import NamedTuple, Dict, Optional, Any, Tuple, Union

import tensorflow as tf

from neuralmonkey.model.stateful import TemporalStateful, SpatialStateful
from neuralmonkey.model.model_part import ModelPart, FeedDict
from neuralmonkey.dataset import Dataset

# pylint: disable=invalid-name
Attendable = Union[TemporalStateful, SpatialStateful]
AttentionLoopState = NamedTuple("AttentionLoopState",
                                [("contexts", tf.TensorArray),
                                 ("weights", tf.TensorArray)])
# pylint: enable=invalid-name

def empty_attention_loop_state() -> AttentionLoopState:
    """Create an empty attention loop state.

    The attention loop state is a technical object for storing the attention
    distributions and the context vectors in time. It is used with the
    ``tf.while_loop`` dynamic implementation of the decoder.

    This function returns an empty attention loop state which means there are
    two empty arrays, one for attention distributions in time, and one for
    the attention context vectors in time.
    """
    return AttentionLoopState(
        contexts=tf.TensorArray(
            dtype=tf.float32, size=0, dynamic_size=True,
            name="contexts"),
        weights=tf.TensorArray(
            dtype=tf.float32, size=0, dynamic_size=True,
            name="distributions", clear_after_read=False))

def get_attention_states(encoder: Attendable) -> tf.Tensor:
    if isinstance(encoder, TemporalStateful):
        return encoder.temporal_states

    elif isinstance(encoder, SpatialStateful):
        # pylint: disable=no-member
        shape = [s.value for s in encoder.spatial_states.get_shape()[1:]]
        # pylint: enable=no-member
        return tf.reshape(encoder.spatial_states,
                          [-1, shape[0] * shape[1], shape[2]])
    else:
        raise AssertionError("Unknown encoder type")

def get_attention_mask(encoder: Attendable) -> Optional[tf.Tensor]:
    if isinstance(encoder, TemporalStateful):
        if encoder.temporal_mask is None:
            raise ValueError("The encoder temporal mask should not be none")
        return encoder.temporal_mask

    elif isinstance(encoder, SpatialStateful):
        if encoder.spatial_mask is None:
            return None

        # pylint: disable=no-member
        shape = [s.value for s in encoder.spatial_mask.get_shape()[1:]]
        # pylint: enable=no-member
        return tf.reshape(encoder.spatial_mask, [-1, shape[0] * shape[1]])
    else:
        raise AssertionError("Unknown encoder type")

class BaseAttention(ModelPart):
    def __init__(self,
                 name: str,
                 save_checkpoint: str = None,
                 load_checkpoint: str = None) -> None:
        ModelPart.__init__(self, name, save_checkpoint, load_checkpoint)

        self.query_state_size = None  # type: tf.Tensor
        self._histories = {}  # type: Dict[str, tf.Tensor]

        self.train_mode = tf.placeholder(tf.bool, [], "train_mode")

    @property
    def histories(self) -> Dict[str, tf.Tensor]:
        return self._histories

    def attention(self,
                  query: tf.Tensor,
                  decoder_prev_state: tf.Tensor,
                  decoder_input: tf.Tensor,
                  loop_state: Any,
                  step: tf.Tensor) -> Tuple[tf.Tensor, Any]:
        """Get context vector for a given query."""
        raise NotImplementedError("Abstract method")

    def initial_loop_state(self) -> Any:
        """Get initial loop state for the attention object."""
        raise NotImplementedError("Abstract method")

    def finalize_loop(self, key: str, last_loop_state: Any) -> None:
        raise NotImplementedError("Abstract method")

    def feed_dict(self, dataset: Dataset, train: bool = False) -> FeedDict:
        return {self.train_mode: train}

    @property
    def context_vector_size(self) -> int:
        raise NotImplementedError("Abstract property")

    def visualize_attention(self, key: str) -> None:
        if key not in self.histories:
            raise ValueError(
                "Key {} not among attention histories".format(key))

        alignments = tf.expand_dims(
            tf.transpose(self.histories[key], perm=[1, 2, 0]), -1)

        tf.summary.image(self.name, alignments,
                         collections=["summary_att_plots"], max_outputs=256)


import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

ON = 255
OFF = 0

def randomGrid(N):
    return np.random.choice([ON, OFF] , N*N, p=[0.25, 0.75]).reshape(N, N)

def update(frameNum, img, grid, N):

    newGrid = grid.copy()
    for i in range(N): #for row
        total = 0
        for j in range(N): #for column

            #No edge cases
            if total == 0: #if first time through
                left_sum =    grid[(i-1)%N, (j-1)%N] + grid[i, (j-1)%N] +  grid[(i+1)%N, (j-1)%N] #j-1 column
                central_sum = grid[(i-1)%N, j]                          +  grid[(i+1)%N, j]      #j column
                right_sum =   grid[(i-1)%N, (j+1)%N] + grid[i, (j+1)%N] +  grid[(i+1)%N, (j+1)%N] #j+1 column
                total = int((left_sum + central_sum + right_sum)/255)
            else:
                left_sum =    central_sum + grid[i, (j-1)%N]
                central_sum = right_sum - grid[i, j]
                right_sum =   grid[(i-1)%N, (j+1)%N] + grid[i, (j+1)%N] +  grid[(i+1)%N, (j+1)%N]
                total = int((left_sum + central_sum + right_sum)/255)

            # apply Conway's rules
            if grid[i, j]  == ON:
                if (total < 2) or (total > 3):
                    newGrid[i, j] = OFF
            else:
                if total == 3:
                    newGrid[i, j] = ON

    # update data
    img.set_data(newGrid)
    grid[:] = newGrid[:]
    return img

def main():

    N = 150
    grid = randomGrid(N)

    updateInterval = 16 #60FPS baby
    fig, ax = plt.subplots()
    img = ax.imshow(grid, interpolation='nearest')
    ani = animation.FuncAnimation(fig, update, fargs=(img, grid, N ), interval=updateInterval)
    plt.show()

main()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Feb 24 03:23:30 2020

@author: angellica
"""

from sklearn.model_selection import train_test_split

def train_dummy(dummy, features, target_feature, df):
    input_x = df[features]
    input_y = df[target_feature]

    X_train, X_test, y_train, y_test = train_test_split(input_x, input_y, test_size=0.033, random_state = 0, stratify = input_y, shuffle = True)

    # First round: running dummy classifier for non injected features
    y_score = dummy.fit(X_train, y_train).predict_proba(X_test)
    y_pred = dummy.predict(X_test)

    return dummy, y_score, y_pred, y_train, X_train, X_test, y_train, y_test

def split_test_train(features, target_feature, df):
    input_x = df[features]
    input_y = df[target_feature]

    X_train, X_test, y_train, y_test = train_test_split(input_x, input_y, test_size=0.033, random_state = 0, stratify = input_y, shuffle = True)

    return X_train, X_test, y_train, y_test


#!/usr/bin/python

__author__="marcus"
__date__ ="$Aug 20, 2011 12:14:18 PM$"

import web
import StringIO
from string import split
from os.path import basename
import eigenfaces
import time
import os

urls = (
    '/(.*)', 'index'
)

web.config.debug = True    # Debug true causa problema quando usado junto com sessoes.

gallery_dir = os.environ['HOME'] + "/robot_/gallery/"
erase_cache_file = True
recurso_nome = "FaceRecognition"
recurso = { \
    "status" : "ready", \
    "local_face" : "", \
    "threshold" : "", \
    "id" : 0 \
    }

class index:

    # ========== Inicializacao unica por classe =================
    # Variaveis declaradas aqui sao usadas na classe usando self.

#    testimg = ""
#    imgsdir = ""
#    threshold = 3.0
#    egfnum = 6
    # ============ Final da Inicializacao unica por classe ======

    def __init__(self):
        global erase_cache_file
        # Apagando o arquivo na primeira execucao.
        if erase_cache_file == True:
            cachefile=os.path.join(gallery_dir,"saveddata.cache")
            try:
                os.remove(cachefile)
            except:
                erase_cache_file = False
        erase_cache_file = False

    def GET(self, name):
        web.header('Content-Type', 'application/xml; charset=utf-8')
        global recurso

        return self.to_xml(recurso)

    def POST(self, name):
        t0 = int(time.time() * 1000)

        global recurso
        # Atualizando recurso com dados do post.
        self.from_xml(web.data())

        # ToDo: Sinalizador. Permite apenas uma transferencia em andamento por vez.
#       # Processamento
        result = self.recognize(recurso.copy())

        web.debug("POST time: " + str(int(time.time() * 1000) - t0) + "ms")

        self.reset_resource()

        return result

    def reset_resource(self):
        global recurso
        recurso['status'] = 'ready'
        recurso['local_face'] = ""
        recurso['threshold'] = ""
        recurso['id'] = 0

    def recognize(self, resource):
        # ToDo: Validacao dos parametros.

        global gallery_dir

        self.testimg = resource['local_face']
        self.imgsdir = gallery_dir
        self.threshold = float(resource['threshold'])
#        self.egfnum = int(resource['engenfaces'])
        parts = split(basename(self.testimg),'.')
        extn = parts[len(parts) - 1]
        web.debug("to match:" + str(self.testimg) + " to all " \
            + str(extn) + " images in directory:" + self.imgsdir)
        self.facet = eigenfaces.FaceRec()
#        self.egfnum = self.set_selected_eigenfaces_count(self.egfnum,extn)
        self.imgnamelist=self.facet.parsefolder(self.imgsdir,extn)
#        web.debug("number of eigenfaces used:" + str(self.egfnum))
#        self.facet.checkCache(self.imgsdir,extn,self.imgnamelist,self.egfnum,self.threshold)
        self.facet.checkCache(self.imgsdir,extn,self.imgnamelist,self.threshold)
#        web.debug("number of eigenfaces used:" + str(self.facet.eigenfaces_calc))
#        mindist,matchfile = self.facet.findmatchingimage(self.testimg,self.egfnum,self.threshold)
        mindist,matchfile = self.facet.findmatchingimage(self.testimg,self.threshold)
        if mindist < 1e-10:
            mindist=0
        if not matchfile:
            result = "<matches></matches><dist></dist>"
        else:
            result = "<matches>"+basename(matchfile)+"</matches><dist>"+str(mindist)+"</dist>"

        web.debug(result)
        return '<result>' + result + '</result>'

#    def set_selected_eigenfaces_count(self,selected_eigenfaces_count,ext):
#        #call eigenfaces.parsefolder() and get imagenamelist
#        self.imgnamelist=self.facet.parsefolder(self.imgsdir,ext)
#        numimgs=len(self.imgnamelist)
#        if(selected_eigenfaces_count >= numimgs  or selected_eigenfaces_count == 0):
#            selected_eigenfaces_count=numimgs/2
#        return selected_eigenfaces_count

    def from_xml(self, xml):
        #print xml
        # ToDo: Remover tudo que nao estiver dentro da tag do recurso
        global recurso
        recurso['status'] = 'reading xml data'
        for item in recurso.items():
            key, value = item
            # Ignorando atributos 'status' e 'id'.
            if key != 'status' and key != 'id':
                inicio = xml.find("<" + key + ">")
                if inicio >= 0:
                    final = xml.find("</" + key + ">")
                    if inicio >= 0 and final > inicio:
                        stringXml = xml[inicio + len(key) + 2 : final]
                        if len(stringXml) > 0: # Ignorando chaves vazias.
                            # Diferenciando valor (string ou int)
                            if isinstance(recurso[key], str):
                                recurso[key] = stringXml
                            else:
                                recurso[key] = int(stringXml)

#                            web.debug("key:value = " + key + " : " + str(recurso[key]))

    def to_xml(self, resource):
        """ Transform a dict into a XML, writing to a stream """
        stream = StringIO.StringIO()
#        stream.write("<?xml version='1.0' encoding='UTF-8'?>")
        stream.write('<%s>' %  recurso_nome)

        for item in resource.items():
            key, value = item
            if isinstance(value, str) or isinstance(value, unicode):
                stream.write('\n<%s>%s</%s>' % (key, value, key))
            else:
                stream.write('\n<%s>%d</%s>' % (key, value, key))

        stream.write('\n</%s>' % recurso_nome)
        stream.seek(0)
        return stream.read()

app = web.application(urls, globals())

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


import numpy as np
import math as m
import matplotlib.pyplot as plt
import queue
import pandas as pd

NOISE = 0
UNASSIGNED = -1

def load_data():
    """
    导入数据
    :return: 数据
    """
    points = []
    fileIn = open("network_point.csv")
    for line in fileIn.readlines():
        temp=[]
        #line.strip()把末尾的'\n'去掉
        lineArr = line.strip().split(',')
        temp.append(float(lineArr[1]))
        temp.append(float(lineArr[2]))
        temp.append(float(lineArr[0]))
        points.append(temp)
        #dataSet.append([float(lineArr[0]), float(lineArr[1])])
    fileIn.close()
    points = np.array(points)
    print(points)
    return points

def dist(a, b):
    """
    计算两个向量的距离
    :param a: 向量1
    :param b: 向量2
    :return: 距离
    """
    return m.sqrt(np.power(a-b, 2).sum())

def neighbor_points(data, pointId, radius):
    """
    得到邻域内所有样本点的Id
    :param data: 样本点
    :param pointId: 核心点
    :param radius: 半径
    :return: 邻域内所用样本Id
    """
    points = []
    for i in range(len(data)):
        if dist(data[i, 0: 2], data[pointId, 0: 2]) < radius:
            points.append(i)
    return np.asarray(points)

def to_cluster(data, clusterRes, pointId, clusterId, radius, minPts):
    """
    判断一个点是否是核心点，若是则将它和它邻域内的所用未分配的样本点分配给一个新类
    若邻域内有其他核心点，重复上一个步骤，但只处理邻域内未分配的点，并且仍然是上一个步骤的类。
    :param data: 样本集合
    :param clusterRes: 聚类结果
    :param pointId:  样本Id
    :param clusterId: 类Id
    :param radius: 半径
    :param minPts: 最小局部密度
    :return:  返回是否能将点PointId分配给一个类
    """
    points = neighbor_points(data, pointId, radius)
    points = points.tolist()

    q = queue.Queue()

    if len(points) < minPts:
        clusterRes[pointId] = NOISE
        return False
    else:
        clusterRes[pointId] = clusterId
    for point in points:
        if clusterRes[point] == UNASSIGNED:
            q.put(point)
            clusterRes[point] = clusterId

    while not q.empty():
        neighborRes = neighbor_points(data, q.get(), radius)
        if len(neighborRes) >= minPts:                      # 核心点
            for i in range(len(neighborRes)):
                resultPoint = neighborRes[i]
                if clusterRes[resultPoint] == UNASSIGNED:
                    q.put(resultPoint)
                    clusterRes[resultPoint] = clusterId
                elif clusterRes[clusterId] == NOISE:
                    clusterRes[resultPoint] = clusterId
    return True

def dbscan(data, radius, minPts):
    """
    扫描整个数据集，为每个数据集打上核心点，边界点和噪声点标签的同时为
    样本集聚类
    :param data: 样本集
    :param radius: 半径
    :param minPts:  最小局部密度
    :return: 返回聚类结果， 类id集合
    """
    clusterId = 1
    nPoints = len(data)
    clusterRes = [UNASSIGNED] * nPoints
    for pointId in range(nPoints):
        if clusterRes[pointId] == UNASSIGNED:
            if to_cluster(data, clusterRes, pointId, clusterId, radius, minPts):
                clusterId = clusterId + 1
    return np.asarray(clusterRes), clusterId

def plotRes(data, clusterRes, clusterNum):
    nPoints = len(data)
    scatterColors = ['black', 'blue', 'green', 'yellow', 'red', 'purple', 'orange', 'brown']
    for i in range(clusterNum):
        color = scatterColors[i % len(scatterColors)]
        x1 = [];  y1 = []
        for j in range(nPoints):
            if clusterRes[j] == i:
                x1.append(data[j, 0])
                y1.append(data[j, 1])
        plt.scatter(x1, y1, c=color, alpha=1, marker='+')

if __name__ == '__main__':
    data = load_data()
    cluster = np.asarray(data[:, 2])
    clusterRes, clusterNum = dbscan(data, 0.5 ,5)#这里改变DBSCAN的超参数
#    clusterRes, clusterNum = dbscan(data, 1 ,5)
#    clusterRes, clusterNum = dbscan(data, 1 ,2.5)
    cluster_DBSCAN=list(clusterRes)
    print(len(cluster_DBSCAN))
    print('clusterNumber=',clusterNum)

    #把聚类结果写入Clust_DBSCAN.csv中
    b = []
    for i in range(len(cluster_DBSCAN)):
        markIndex = cluster_DBSCAN[i]
        b.append(markIndex)
    a = []
    for i in range(len(cluster_DBSCAN)):
        a.append(i+1)

    #字典中的key值即为csv中列名
    dataframe = pd.DataFrame({'row':a,'type':b})

    #将DataFrame存储为csv,index表示是否显示行名，default=True
    dataframe.to_csv("Clust_DBSCAN.csv",index=False,sep=',')

    plotRes(data, clusterRes, clusterNum)
    plt.show()


import random

from textual.reactive import Reactive
from textual.views import GridView

from swept.cell import BOMB_CHAR, Cell, CellStatus
from swept.config import BOMB_PERCENT, N_COLS, N_ROWS
from swept.enums import GameStatus
from swept.exceptions import CantToggleFlag, CantUncover

class CellGrid(GridView):
    """
    Minesweeper-like game.
    """

    game_status = Reactive(GameStatus.IN_PROGRESS)

    def watch_game_status(self, game_status: GameStatus) -> None:
        """Control grid based on status."""
        if game_status == GameStatus.LOST:
            self.uncover_bombs()
        elif game_status == GameStatus.WON:
            for btn in self.cell_btns:
                if btn.status == CellStatus.FLAGGED:
                    btn.status = CellStatus.FLAGGED_WON

    def on_mount(self) -> None:
        """
        Event when widget is first mounted.
        """
        self.cell_btns = [
            Cell("", style=Cell.COVERED_CELL, name=f"{idx}")
            for idx in range(N_COLS * N_ROWS)
        ]
        self.reset_game()

        # set basic grid settings
        self.grid.set_gap(1, 1)
        self.grid.set_gutter(2)
        self.grid.set_align("center", "center")

        # create rows / columns / areas
        self.grid.add_column("col", max_size=6, repeat=N_COLS)
        self.grid.add_row("row", max_size=3, repeat=N_ROWS)

        self.grid.place(*self.cell_btns)

    def reset_game(self) -> None:
        """Reset game."""
        n_bombs = len(self.cell_btns) * BOMB_PERCENT // 100
        bombs = [True] * n_bombs + [False] * (len(self.cell_btns) - n_bombs)
        random.shuffle(bombs)

        for btn, bomb in zip(self.cell_btns, bombs):
            btn.value = BOMB_CHAR if bomb else ""

        for idx, btn in enumerate(self.cell_btns):
            if btn.value != BOMB_CHAR:
                btn.value = str(self.count_adjacent_bombs(idx))
            self.log(btn.value)
            btn.status = CellStatus.COVERED

    def uncover_cell(self, cell_idx: int) -> None:
        """Flip a cell."""
        cell = self.cell_btns[cell_idx]

        try:
            cell.uncover()
        except CantUncover:
            return

        # propagate 0 cell uncovering
        if cell.value == "0":
            for adj_idx in self._adjacent_idxs(cell_idx):
                self.uncover_cell(adj_idx)

    def uncover_bombs(self) -> None:
        """Uncover all bombs."""
        for btn in self.cell_btns:
            if btn.value == BOMB_CHAR and btn.status != CellStatus.EXPLODED:
                btn.status = CellStatus.UNCOVERED

    def uncover_adjacent(self, cell_idx: int) -> None:
        """Uncover adjacent cells if all bombs around a specific cell have been identified."""
        try:
            expected_bombs = int(self.cell_btns[cell_idx].label)
        except ValueError:
            return

        seen_bombs = sum(
            1
            for adj_idx in self._adjacent_idxs(cell_idx)
            if self.cell_btns[adj_idx].status == CellStatus.FLAGGED
        )

        if expected_bombs == seen_bombs:
            for adj_idx in self._adjacent_idxs(cell_idx):
                self.uncover_cell(adj_idx)

    def flag_cell(self, cell_idx: int) -> None:
        """Flag a cell where the player thinks is a bomb."""
        cell = self.cell_btns[cell_idx]

        try:
            cell.toggle_flag()
        except CantToggleFlag:
            return

    def win_condition(self) -> bool:
        """Compute if the game has been won."""
        return all(
            cell.status in [CellStatus.UNCOVERED, CellStatus.FLAGGED]
            for cell in self.cell_btns
        )

    def lose_condition(self) -> bool:
        """Compute if the game has been lost."""
        return any(cell.status == CellStatus.EXPLODED for cell in self.cell_btns)

    def _adjacent_idxs(self, idx: int) -> list[int]:
        """Compute all adjacent valid indices of a cell."""
        adjacents = []

        col = idx % N_COLS
        row = idx // N_COLS

        if col != 0 and row != 0:
            adjacents.append(idx - N_COLS - 1)
        if col != 0:
            adjacents.append(idx - 1)
        if col != 0 and row != N_ROWS - 1:
            adjacents.append(idx + N_COLS - 1)
        if row != 0:
            adjacents.append(idx - N_COLS)
        if row != N_ROWS - 1:
            adjacents.append(idx + N_COLS)
        if col != N_COLS - 1 and row != 0:
            adjacents.append(idx - N_COLS + 1)
        if col != N_COLS - 1:
            adjacents.append(idx + 1)
        if col != N_COLS - 1 and row != N_ROWS - 1:
            adjacents.append(idx + N_COLS + 1)

        return adjacents

    def count_adjacent_bombs(self, idx: int) -> int:
        """
        Compute the number of adjacent bombs to a cell.
        """
        return sum(
            1
            for adj_idx in self._adjacent_idxs(idx)
            if self.cell_btns[adj_idx].value == BOMB_CHAR
        )


from django.shortcuts import get_object_or_404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Topup
from .serializers import TopupsSerializer
from vouchers.models import Voucher
from users.models import User
from topups.serializers import TopupsSerializer

class TopupsList(APIView):
    def get(self, request):
        topups = Topup.objects.all()
        serializer = TopupsSerializer(topups, many=True)
        return Response(serializer.data)

    def post(self, request):
        print(request.data['voucher_code'])
        voucher_code = request.data['voucher_code']
        user_id = request.data['user_id']

        try:
            voucher = Voucher.objects.get(voucher_code=voucher_code, is_active=1)
        except Voucher.DoesNotExist:
            response_data = {}
            response_data['error'] = "Error"
            response_data['message'] = "Incorrect Voucher Entered"
            return Response(response_data, status=status.HTTP_404_NOT_FOUND)

        print(voucher.amount)
        amount_purchased = voucher.amount

        try:
            user = User.objects.get(id=user_id)
        except User.DoesNotExist:
            response_data = {}
            response_data['error'] = "Error"
            response_data['message'] = "User doesn't exist in database"
            return Response(response_data, status=status.HTTP_404_NOT_FOUND)

        user.amount +=amount_purchased
        user.save()

        voucher.is_active = 0
        voucher.save()

        topup_data = {}
        topup_data['user_id'] = user_id
        topup_data['amount'] = amount_purchased
        topup_data['payment_type'] = "VCH"
        topup_data['voucher_id'] = voucher.id

        topup_serializer = TopupsSerializer(data=topup_data)
        if topup_serializer.is_valid():
            topup_serializer.save()
            return Response(topup_serializer.data, status=status.HTTP_201_CREATED)
        return Response(topup_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        print(topup_data)

        response_data = {}
        response_data['success'] = "Success"
        response_data['message'] = "Topup Successful"
        return Response(response_data, status=status.HTTP_200_OK)


'''

-Medium-

Given an array of strings words, find the longest string in words such that
every prefix of it is also in words.

For example, let words = ["a", "app", "ap"]. The string "app" has
prefixes "ap" and "a", all of which are in words.
Return the string described above. If there is more than one string with

the same length, return the lexicographically smallest one, and if
no string exists, return "".

Example 1:

Input: words = [“k”,”ki”,”kir”,”kira”, “kiran”]

Output: “kiran”

Explanation: “kiran” has prefixes “kira”, “kir”, “ki”, and “k”, and all of them appear in words.

Example 2:

Input: words = [“a”, “banana”, “app”, “appl”, “ap”, “apply”, “apple”]

Output: “apple”

Explanation: Both “apple” and “apply” have all their prefixes in words. However, “apple” is lexicographically smaller, so we return that.

Example 3:

Input: words = [“abc”, “bc”, “ab”, “qwe”]

Output: “”

Constraints:

1 <= words.length <= 10^5
1 <= words[i].length <= 10^5
1 <= sum(words[i].length) <= 10^5
'''

from collections import defaultdict

class TrieNode(defaultdict):
    def __init__(self):
        super().__init__(TrieNode)
        self.terminal = False

class Solution(object):

    def longestWord(self, words):
        self.ans = ""
        root = TrieNode()
        for word in words:
            node = root
            n = len(word)
            for c in word:
                node = node[c]
            node.terminal = True
        def dfs(node, sb):
            if node.terminal and len(sb) > len(self.ans):
                self.ans = sb
            for c in sorted(node.keys()):
                if node[c].terminal:
                    dfs(node[c], sb+c)
        dfs(root, '')
        return self.ans

if __name__ == '__main__':
    print(Solution().longestWord(["k","ki","kir","kira", "kiran"]))
    print(Solution().longestWord(["a", "banana", "app", "appl", "ap", "apply", "apple"]))
    print(Solution().longestWord(["abc", "bc", "ab", "qwe"]))


#coding=utf-8
import onnx
import numpy as np
from onnx import helper
from onnx import numpy_helper

class Tool(object):
    # 初始化onnx模型
    def __init__(self, onnx_model_path):
        self.model = onnx.load(onnx_model_path)
        self.model = onnx.shape_inference.infer_shapes(self.model)
        self.inputs = []
        self.outputs = []

    # 保存onnx模型
    def export(self, save_path):
        onnx.checker.check_model(self.model)
        self.model = onnx.shape_inference.infer_shapes(self.model)
        onnx.save(self.model, save_path)

    # 获取onnx模型的输入，返回一个列表
    def get_input_names(self):
        set_input = set()
        set_initializer = set()
        for ipt in self.model.graph.input:
            set_input.add(ipt.name)
        for x in model.graph.initializer:
            set_initializer.add(x.name)
        return list(set_input - set_initializer)

    # 为onnx模型增加batch维度
    def set_model_input_batch(self, index=0, name=None, batch_size=4):
        model_input = None
        if name is not None:
            for ipt in self.model.graph.input:
                if ipt.name == name:
                    model_input = ipt
        else:
            model_input = self.model.graph.input[index]
        if model_input:
            tensor_dim = model_input.type.tensor_type.shape.dim
            tensor_dim[0].ClearField("dim_param")
            tensor_dim[0].dim_value = batch_size
        else:
            print('get model input failed, check index or name')

    # 为onnx模型的输入设置形状
    def set_model_input_shape(self, index=0, name=None, shape=None):
        model_input = None
        if name is not None:
            for ipt in self.model.graph.input:
                if ipt.name == name:
                    model_input = ipt
        else:
            model_input = self.model.graph.input[index]
        if model_input:
            if shape is not None:
                tensor_shape_proto = model_input.type.tensor_type.shape
                tensor_shape_proto.ClearField("dim")
                tensor_shape_proto.dim.extend([])
                for d in shape:
                    dim = tensor_shape_proto.dim.add()
                    dim.dim_value = d
            else:
                print('get input shape failed, check input')
        else:
            print('get model input failed, check index or name')

    # 通过名字获取onnx模型中的计算节点
    def get_node_by_name(self, name):
        for node in self.model.graph.node:
            if node.name == name:
                return node

    # 通过op的类型获取onnx模型的计算节点
    def get_nodes_by_optype(self, typename):
        nodes = []
        for node in self.model.graph.node:
            if node.op_type == typename:
                nodes.append(node)
        return nodes

    # 通过名字获取onnx模型计算节点的权重
    def get_weight_by_name(self, name):
        for weight in self.model.graph.initializer:
            if weight.name == name:
                return weight

    # 设置权重，注意这个weight是TensorProto类型，`https://github.com/onnx/onnx/blob/b1e0bc9a31eaefc2a9946182fbad939843534984/onnx/onnx.proto#L461`
    def set_weight(self, weight, data_numpy=None, all_ones=False, all_zeros=False):
        if data_numpy is not None:
            raw_shape = tuple([i for i in weight.dims])
            new_shape = np.shape(data_numpy)
            if weight.data_type == 8:
                print("Can NOT handle string data type right now...")
                exit()
            if new_shape != raw_shape:
                print("Warning: the new weight shape is not consistent with original shape!")
                weight.dims[:] = list(new_shape)
                for model_input in self.model.graph.input:
                    if model_input.name == weight.name:
                        # copy from onnx.helper...
                        tensor_shape_proto = model_input.type.tensor_type.shape
                        tensor_shape_proto.ClearField("dim")
                        tensor_shape_proto.dim.extend([])
                        for d in new_shape:
                            dim = tensor_shape_proto.dim.add()
                            dim.dim_value = d

            weight.ClearField("float_data")
            weight.ClearField("int32_data")
            weight.ClearField("int64_data")
            weight.raw_data = data_numpy.tobytes()
        else:
            if all_ones:
                wr = numpy_helper.to_array(weight)
                wn = np.ones_like(wr)
            elif all_zeros:
                wr = numpy_helper.to_array(weight)
                wn = np.zeros_like(wr)
            else:
                print("You must give a data_numpy to set the weight, or set the all_ones/all_zeros flag.")
                exit()
            weight.ClearField("float_data")
            weight.ClearField("int32_data")
            weight.ClearField("int64_data")
            weight.raw_data = wn.tobytes()

    # 通过名字设置ONNX节点的权重
    def set_weight_by_name(self, name, data_numpy=None, all_ones=False, all_zeros=False):
        weight = self.get_weight_by_name(name)
        self.set_weight(weight, data_numpy, all_ones, all_zeros)

    # 移除ONNX模型中的目标节点
    def remove_node(self, target_node):
        '''
            删除只有一个输入和输出的节点
        '''
        node_input = target_node.input[0]
        node_output = target_node.output[0]
        # 将后继节点的输入设置为目标节点的前置节点
        for node in self.model.graph.node:
            for i, n in enumerate(node.input):
                if n == node_output:
                    node.input[i] = node_input

        target_names = set(target_node.input) & set([weight.name for weight in self.model.graph.initializer])
        self.remove_weights(target_names)
        target_names.add(node_output)
        self.remove_inputs(target_names)
        self.remove_value_infos(target_names)
        self.model.graph.node.remove(target_node)

    # 移除ONNX模型中指定节点的权重
    def remove_weights(self, name_list):
        rm_list = []
        for weight in self.model.graph.initializer:
            if weight.name in name_list:
                rm_list.append(weight)
        for weight in rm_list:
            self.model.graph.initializer.remove(weight)

    # 移除ONNX模型中指定的输入节点
    def remove_inputs(self, name_list):
        rm_list = []
        for input_t in self.model.graph.input:
            if input_t.name in name_list:
                rm_list.append(input_t)
        for input_t in rm_list:
            self.model.graph.input.remove(input_t)

    # 移除ONNX模型中指定的输入输出节点
    def remove_value_infos(self, name_list):
        rm_list = []
        for value_info in self.model.graph.value_info:
            if value_info.name in name_list:
                rm_list.append(value_info)
        for value_info in rm_list:
            self.model.graph.value_info.remove(value_info)

    # 给ONNX模型中的目标节点设置指定属性
    def set_node_attribute(self, target_node, attr_name, attr_value):
        flag = False
        for attr in target_node.attribute:
            if (attr.name == attr_name):
                if attr.type == 1:
                    attr.f = attr_value
                elif attr.type == 2:
                    attr.i = attr_value
                elif attr.type == 3:
                    attr.s = attr_value
                elif attr.type == 4:
                    attr.t = attr_value
                elif attr.type == 5:
                    attr.g = attr_value
                # NOTE: For repeated composite types, we should use something like
                # del attr.xxx[:]
                # attr.xxx.extend([n1, n2, n3])
                elif attr.type == 6:
                    attr.floats[:] = attr_value
                elif attr.type == 7:
                    attr.ints[:] = attr_value
                elif attr.type == 8:
                    attr.strings[:] = attr_value
                else:
                    print("unsupported attribute data type with attribute name")
                    return False
                flag = True

        if not flag:
            # attribute not in original node
            print("Warning: you are appending a new attribute to the node!")
            target_node.attribute.append(helper.make_attribute(attr_name, attr_value))
            flag = True
        return flag

    def chunk_at(self, target_node):
        r_nodes = [target_node]
        r_input_names = [input_n for input_n in target_node.input]
        r_count = len(r_nodes) + len(r_input_names)

        while True:
            for node in self.model.graph.node:
                # print("nn", node.output)
                if node in r_nodes:
                    continue
                for o in node.output:
                    if o in r_input_names:
                        r_nodes.append(node)
                        r_input_names.extend([input_n for input_n in node.input])
                        continue
            n_count = len(r_nodes) + len(r_input_names)
            if n_count == r_count:
                break
            r_count = n_count

        print("debug r count", r_count)

        d_nodes = []
        d_inputs = []
        d_weights = []
        d_value_infos = []
        for node in self.model.graph.node:
            if node not in r_nodes:
                d_nodes.append(node)
        for model_input in self.model.graph.input:
            if model_input.name not in r_input_names:
                d_inputs.append(model_input)
        for weight in self.model.graph.initializer:
            if weight.name not in r_input_names:
                d_weights.append(weight)
        for value_info in self.model.graph.value_info:
            if value_info.name not in r_input_names:
                d_values.append(value_info)
        for node in d_nodes:
            self.model.graph.node.remove(node)
        for model_input in d_inputs:
            self.model.graph.input.remove(model_input)
        for weight in d_weights:
            self.model.graph.initializer.remove(weight)
        for value_info in d_value_infos:
            self.model.graph.value_info.remove(value_info)

        target_node.output[0] = self.model.graph.output[0].name
        # remove other outputs if model has multi-output
        d_outputs = []
        for i, output in enumerate(self.model.graph.output):
            if i != 0 :
                d_outputs.append(output)
        for output in d_outputs:
            self.model.graph.output.remove(output)

    # 在指定节点前插入flatten node
    def insert_flatten_before(self, target_node):
        # get target_node inputs
        node_input = target_node.input[0]
        # create new node
        node_name = "flatten_test"
        flatten_node = helper.make_node('Flatten', inputs=[node_input], outputs=[node_name], name=node_name)
        # set target_node inputs to new node outputs
        target_node.input[0] = node_name
        for target_node_index, _target_node in enumerate(self.model.graph.node):
            if _target_node == target_node:
                self.model.graph.node.insert(target_node_index, flatten_node)
                break

    # 在指定节点target_node前插入一个新的OP
    def insert_op_before(self, node_name, target_node, input_idx=0, *args, **kwargs):
        '''
        op_name
        weight_dict
        attr_dict
        ......
        NOTE:
        you must ensure the output shape match the input shape of target_node
        '''
        # get target_node inputs
        node_input = target_node.input[input_idx]
        weight_input = []
        weight_input_vi = []
        weight_initializer = []
        if "weight_dict" in kwargs:
            for weight_name, weight_numpy in kwargs["weight_dict"].items():
                weight_input.append(weight_name)
                weight_input_vi.append(
                        helper.make_tensor_value_info(
                            name=weight_name,
                            elem_type=onnx.mapping.NP_TYPE_TO_TENSOR_TYPE[weight_numpy.dtype],
                            shape=weight_numpy.shape
                        )
                )
                weight_initializer.append(
                    helper.make_tensor(
                            name=weight_name,
                            data_type=onnx.mapping.NP_TYPE_TO_TENSOR_TYPE[weight_numpy.dtype],
                            dims=weight_numpy.shape,
                            vals=weight_numpy.tobytes(),
                            raw=True
                    )
                )
        # create new node
        new_op_node = helper.make_node(
                                kwargs["op_name"],
                                inputs=[node_input, *weight_input],
                                outputs=[node_name],
                                name=node_name,
                                **kwargs["attr_dict"]
                            )
        # set target_node input to new node outputs
        target_node.input[input_idx] = node_name
        # TODO: change other nodes input into the new node?
        # iterator all the nodes in the graph and find
        # which node's input equals the original target_node input
        # ...
        # add new node and weight input into the graph
        for target_node_index, _target_node in enumerate(self.model.graph.node):
            if _target_node == target_node:
                self.model.graph.node.insert(target_node_index, new_op_node)
                break
        self.model.graph.input.extend(weight_input_vi)
        self.model.graph.initializer.extend(weight_initializer)

    # 将target_node添加到ONNX模型中作为输出节点
    def add_extra_output(self, target_node, output_name):
        target_output = target_node.output[0]
        extra_shape = []
        for vi in self.model.graph.value_info:
            if vi.name == target_output:
                extra_elem_type = vi.type.tensor_type.elem_type
                for s in vi.type.tensor_type.shape.dim:
                    extra_shape.append(s.dim_value)
        extra_output = helper.make_tensor_value_info(
                                output_name,
                                extra_elem_type,
                                extra_shape
                            )
        identity_node = helper.make_node('Identity', inputs=[target_output], outputs=[output_name], name=output_name)
        self.model.graph.node.append(identity_node)
        self.model.graph.output.append(extra_output)


import os.path

from records import Record
from tabulate import tabulate

class Directory:
    def __init__(self):
        """
        Конструктор для создания справочника.
        """
        self.records = []
        self.next_pk = 1

    def add_record(self, record: Record):
        """
        Добавление записи в справочник.
        :param record: Запись
        """
        while any(r.pk == self.next_pk for r in self.records):
            self.next_pk += 1
        record.pk = self.next_pk
        self.records.append(record)
        self.next_pk += 1

    def edit_record(self, pk, **kwargs):
        """
        Редактирование существующей записи.
        :param pk: Первичный ключ записи
        :param kwargs: Словарь с новыми значениями атрибутов
        """
        record = self.get_record_by_pk(pk)
        if record:
            record.edit(**kwargs)
        else:
            print("Запись с указанным PK не найдена.")

    def get_record_by_pk(self, pk):
        """
        Получение записи по её PK.
        :param pk: Первичный ключ записи
        :return: Объект записи или None, если запись не найдена
        """
        for record in self.records:
            if record.pk == pk:
                return record
        return None

    def search_records(self, **kwargs):
        """
        Поиск записей по характеристикам.
        :param kwargs: Словарь с характеристиками для поиска
        :return: Список кортежей (PK, запись) найденных записей
        """
        matching_records = []
        for record in self.records:
            match = False
            for key, value in kwargs.items():
                record_value = getattr(record, key, None)
                if record_value and value.lower() in record_value.lower():
                    match = True
                    break
            if match:
                matching_records.append((record.pk, record))
        return matching_records

    def print_page(self, page_number, page_size=10):
        """
        Вывод страницы с записями на экран.
        :param page_number: Номер страницы
        :param page_size: Количество записей на странице
        """
        start_index = (page_number - 1) * page_size
        end_index = start_index + page_size
        records_to_display = self.records[start_index:end_index]

        table_data = []
        for record in records_to_display:
            table_data.append([record.pk, f"{record.surname} {record.name} {record.patronymic}",
                               record.organization, record.work_phone, record.cell_phone])

        headers = ["PK", "ФИО", "Организация", "Рабочий телефон", "Сотовый телефон"]

        print(tabulate(table_data, headers=headers, tablefmt="grid"))

    def save_to_file(self, filename='yellow_pages.txt', ):
        """
        Сохранение данных справочника в текстовый файл.
        :param filename: Имя файла, по умолчанию в корень папки с программой в ффайл yellow_pages.txt
        """
        with open(filename, "w", encoding="utf-8") as file:
            for record in self.records:
                file.write(f"{record.pk}; {record.surname}; {record.name}; {record.patronymic}; {record.organization}; {record.work_phone}; {record.cell_phone}\n")

    @classmethod
    def load_from_file(cls, filename='yellow_pages.txt'):
        """
        Загрузка данных справочника из текстового файла.
        :param filename: Имя файла
        :return: Экземпляр справочника с загруженными данными
        """
        directory = cls()
        if os.path.exists(filename):
            with open(filename, "r", encoding="utf-8") as file:
                for line in file:
                    pk, surname, name, patronymic, organization, work_phone, cell_phone = line.strip().split("; ")
                    record = Record(surname, name, patronymic, organization, work_phone, cell_phone)
                    directory.add_record(record)
        return directory


import tkinter as tk

import cv2

import Utilities as utl

class LabeledActionsFrame(tk.LabelFrame):
    def __init__(self, master, *args, **kwargs):
        tk.LabelFrame.__init__(self, master, *args, **kwargs)

        self.master = master
        self.action_listbox = tk.Listbox(self)
        self.action_listbox.pack(fill="both", expand=True)

        self.action_listbox.bind("<Double-1>", self.action_listbox_double_clicked)

    def action_listbox_double_clicked(self, event):
        self.master.master.master.tools_frame.playing_controller_frame.pause_button_clicked()
        canvas = self.master.master.master.canvas_frame.video_canvas
        video_cap = self.master.master.master.tools_frame.settings_frame.video_cap
        current_frame_number_entry = self.master.master.master.\
                                                    tools_frame.playing_controller_frame.current_frame_number_entry
        selection = self.action_listbox.curselection()
        action_id, action_name, start, end = self.action_listbox.get(selection[0]).split(', ')
        start = int(start)
        video_cap.set(cv2.CAP_PROP_POS_FRAMES, start)
        has_frame, frame = video_cap.read()

        current_frame_number_entry.delete(0, tk.END)
        current_frame_number_entry.insert(0, start)

        utl.update_canvas_from_cv_image(canvas, frame)


from sklearn.preprocessing import OneHotEncoder

ohe = OneHotEncoder(handle_unknown='ignore', sparse=False)
OH_cols_train = pd.DataFrame(ohe.fit_transform(X_train[low_cardinality_cols]))
OH_cols_valid = pd.DataFrame(ohe.transform(X_valid[low_cardinality_cols]))

OH_cols_train.columns = ohe.get_feature_names(low_cardinality_cols)
OH_cols_valid.columns = ohe.get_feature_names(low_cardinality_cols)

OH_cols_train.index = X_train.index
OH_cols_valid.index = X_valid.index

num_X_train = X_train.drop(object_cols, axis=1)
num_X_valid = X_valid.drop(object_cols, axis=1)

OH_X_train = pd.concat([num_X_train, OH_cols_train], axis=1)
OH_X_valid = pd.concat([num_X_valid, OH_cols_valid], axis=1)


import time
from confluent_kafka import Consumer
from utils.kafka_config import *
from confluent_kafka.schema_registry.avro import AvroDeserializer
from confluent_kafka.schema_registry import SchemaRegistryClient
from confluent_kafka.serialization import SerializationContext, MessageField

## create kafka consumer class to listen to tweets
class KafkaConsumer(object):
    def __init__(self, topic_name,start_from_beginning=False):
        self.topic_name = topic_name

        if start_from_beginning:
            self.consumer = Consumer({'bootstrap.servers': brokers, 'group.id': '0', 'auto.offset.reset': 'earliest'})
        else:
            self.consumer = Consumer({'bootstrap.servers': brokers, 'group.id': '0'})
        self.consumer.subscribe([self.topic_name])

        #check if successfully subscribed to topic
        topic_metadata = self.consumer.list_topics(topic=self.topic_name)
        if self.topic_name in set(t.topic for t in iter(topic_metadata.topics.values())):
            print(f'Successfully subscribed to topic {self.topic_name}')
        else:
            print(f'Failed to subscribe to topic {self.topic_name}')

    def consume(self):
        print('starting to consume messages from topic {}'.format(self.topic_name))
        while True:
            msg = self.consumer.poll(1.0)
            if msg is None:
                print('no message received by consumer')
            elif msg.error() is not None:
                print("error from consumer")
            else:
                print('consumed message {}'.format(msg.value().decode('utf-8')))
            time.sleep(1)

## Create Consumer class with AvroSerializer and schemaregistryclient to listen to tweets
class AvroKafkaConsumer(KafkaConsumer):
    def __init__(self, topic_name,start_from_beginning=False,schema_path=None):
        super().__init__(topic_name,start_from_beginning)

        # Load Avro schema from .avsc file
        with open(schema_path, "r") as f:
            schema_str = f.read()
        # Connect to Schema Registry
        self.schema_registry_client = SchemaRegistryClient({"url": schema_registry_url})
        # Create Avro Deserializer
        self.avro_deserializer = AvroDeserializer(self.schema_registry_client, schema_str)

    def consume(self):
        print('starting to consume messages from topic {}'.format(self.topic_name))
        while True:
            msg = self.consumer.poll(1.0)
            if msg is None:
                print('no message received by consumer')
            elif msg.error() is not None:
                print("error from consumer")
            else:
                print('consumed message {}'.format(self.avro_deserializer(msg.value(), SerializationContext(msg.topic(), MessageField.VALUE))))
            time.sleep(1)