import pickle
import socket
import threading
import time
import tkinter as tk
# importing the choosecolor package
from tkinter import colorchooser, ttk

from player_class_online_version import Player
from prop_class_for_online_version import my_property_class, row_coordinates, column_coordinates, place_num, prop_id, \
    prop_info, place_id_place_to_pos

client = socket.socket()
client.connect(("127.0.0.1", 9999))

container = tk.Tk()

# setting width and height of tkinter window so as to fit screen!
width = container.winfo_screenwidth()  # width of screen
height = container.winfo_screenheight()  # height of screen
container.winfo_toplevel().geometry("%dx%d%+d%+d" % (width, height, 0, 0))

# intro page of the game where one can join or create room, select their favourite color for the game
start_frame = tk.Frame(container, width=width, height=height)
start_frame.grid(row=0, column=0, sticky="nsew")

# make a grid on the container so as to make placing easier- you can ignore this just gui stuff
tk.Frame(start_frame, width=width / 7, height=height / 7).grid(row=0, column=0)
tk.Frame(start_frame, width=width / 7, height=height / 7).grid(row=0, column=1)
tk.Frame(start_frame, width=width / 7, height=height / 7).grid(row=0, column=2)
tk.Frame(start_frame, width=width / 7, height=height / 7).grid(row=0, column=3)
tk.Frame(start_frame, width=width / 7, height=height / 7).grid(row=0, column=4)
tk.Frame(start_frame, width=width / 7, height=height / 7).grid(row=0, column=5)
tk.Frame(start_frame, width=width / 7, height=height / 7).grid(row=0, column=6)
tk.Frame(start_frame, width=width / 7, height=height / 7).grid(row=0, column=7)

font = ("Courier", 13)

def intro_ask_what_to_do():
    global two_btns_label, create_room_btn, join_room_btn
    two_btns_label = tk.Label(start_frame, text="What do you want to do?", font=font)
    two_btns_label.grid(row=2, column=2, columnspan=3)
    # give our client a choice of creating or joining a room
    create_room_btn = tk.Button(start_frame, text="Create Room", command=lambda: create_room())
    create_room_btn.grid(row=3, column=2)
    join_room_btn = tk.Button(start_frame, text="Join Room", command=lambda: join_room())
    join_room_btn.grid(row=3, column=4)

intro_ask_what_to_do()

def create_room():
    global player_desig
    player_desig = "host"
    two_btns_label.grid_forget()
    join_room_btn.grid_forget()
    create_room_btn.grid_forget()
    client.send(pickle.dumps("create room"))
    ask_username()

def join_room():
    global player_desig, recv_rooms_list_threaqd_running
    recv_rooms_list_threaqd_running = False
    player_desig = "player"
    two_btns_label.grid_forget()
    join_room_btn.grid_forget()
    create_room_btn.grid_forget()
    client.send(pickle.dumps("join room"))
    ask_room_num()

def ask_room_num():
    global room_num_entry, ok_but_room_num, room_label  # , room_num_display_frame
    # room_num_display_frame = tk.Frame(container)
    # room_num_display_frame.grid()
    if recv_rooms_list_threaqd_running == False:
        recv_rooms_list_thread_OBJECT = recv_rooms_list_thread()
        recv_rooms_list_thread_OBJECT.start()

    room_label = tk.Label(start_frame, text="Choose the room which you want to join!", font=font)
    room_label.grid(row=2, column=2, columnspan=3)
    ok_but_room_num = tk.Button(start_frame, text="Okay", font=font, command=lambda: ok_but_room_num_clkd())
    ok_but_room_num.grid(row=4, column=3)

class recv_rooms_list_thread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        recv_rooms_list_threaqd_running = True

    def run(self):

        # display a list of players on the screen
        # it would be in the form of a treeview (of ttk)

        # define our treeview

        global rooms_view
        rooms_view = ttk.Treeview(start_frame, selectmode="browse")

        # format our columns
        rooms_view["columns"] = ("Room Number", "Host Name", "No. of Players")
        rooms_view.column("#0", width=0)
        rooms_view.column("Room Number", width=150, minwidth=50, anchor="w")
        rooms_view.column("Host Name", width=150, minwidth=40, anchor="w")
        rooms_view.column("No. of Players", width=100, minwidth=20, anchor="w")

        # create headings
        rooms_view.heading("#0", text="")
        rooms_view.heading("Room Number", text="Room Number", anchor="w")
        rooms_view.heading("Host Name", text="Host Name", anchor="w")
        rooms_view.heading("No. of Players", text="No. of Players", anchor="w")

        # pack to the screen
        rooms_view.grid(row=5, column=3)

        # we will add data as and when we recv stuff

        # list of players we have taken note of
        noted_rooms = []
        # contains the n_players of all room nums recved so as later we can change the display when n-players change
        noted_n_players = {}

        stringvars = {}
        global rooms_list
        stat_list = ["error", "joined successfully", "room doesn't exist", "room locked"]

        while True:
            time.sleep(0.3)
            rooms_list = pickle.loads(client.recv(1024))
            print(rooms_list)

            if rooms_list in stat_list:
                analyze_stat(rooms_list)
                break

            elif rooms_list[0] == "room disbanded":
                try:
                    for child in rooms_view.get_children():
                        print(child)
                        if child == rooms_list[1]:
                            rooms_view.delete(child)
                            break
                            # todo:
                            #   what if after removal of a room there are no rooms existing
                except:
                    # it may happen as the client was sent the room disband msg before tree view childs were established
                    pass

            else:
                for room in rooms_list:
                    if room[0] not in noted_rooms:

                        stringvars.update({room[0]: tk.StringVar()})
                        stringvars[room[0]].set(str(room[2]))
                        # add data for the player in treeview

                        rooms_view.insert(parent="", index="end", text="", iid=room[0],
                                          values=(room[0], room[1], stringvars[room[0]].get()))

                        # add the player in noted players so we do not double display the player
                        noted_rooms.append(room[0])
                        # add n_players with corresponding room num
                        noted_n_players.update({room[0]: room[2]})

                    else:
                        # this means we have noted the room already, so just check if we need to update all no. of
                        #  players in the display
                        # will also update room num if num has decreased
                        if noted_n_players[room[0]] != room[2]:
                            # so this code will run when we recved a new num for no. of players
                            # update display
                            stringvars[room[0]].set(room[2])

                        else:
                            # means nothing to change
                            # this is not possible as we only send data when we have a change
                            pass

def ok_but_room_num_clkd():
    try:
        s = rooms_view.selection()[0]
        selected = rooms_view.focus()
        room = rooms_view.item(selected, "values")
        room = room[0]
        # if there is none selected then below code will not run
        ok_but_room_num.grid_forget()
        rooms_view.grid_forget()
        room_label.grid_forget()

        client.send(pickle.dumps(room))

    except IndexError:
        print("None selected")

def analyze_stat(status):
    if str(status) == "error":
        # for now only
        quit()

    if str(status) == "joined successfully":
        # ask and then send the username
        # ask for username
        ask_username()

    if str(status) == "room doesn't exist":
        # ask client to enter a valid room no.
        ask_room_num()

    if str(status) == "unable to join temp":
        # ask client to wait for some time and then try to join again (this is the most rare to happen)
        ask_room_num()

    if str(status) == "room locked":
        # ask client to enter another room num
        print("room is either full or locked by the host!")
        ask_room_num()

    if str(status) == "room disbanded":
        show_room_disbanded_label()
        intro_ask_what_to_do()

def ask_username():
    # ask for username
    global ok_but_for_username, username_entry, username_label
    username_label = tk.Label(start_frame, text="Enter your username", font=font)
    username_label.grid(row=2, column=3)
    username_entry = tk.Entry(start_frame)
    ok_but_for_username = tk.Button(start_frame, text="Okay", font=font, command=lambda: ok_but_for_username_clicked())
    username_entry.grid(row=3, column=3)
    ok_but_for_username.grid(row=4, column=3)

def ok_but_for_username_clicked():
    global username
    username_label.grid_forget()
    ok_but_for_username.grid_forget()
    username_entry.grid_forget()

    username = username_entry.get()
    username = str(username)

    client.send(pickle.dumps(username))
    response = pickle.loads(client.recv(1024))
    if response == "occupied username":
        ask_username()
    else:
        container.title(username)
        check_on_new_thread_npl = recv_new_players_list_thread()
        check_on_new_thread_npl.start()

def show_room_disbanded_label():
    room_disbanded_label = tk.Label(start_frame,
                                    text=f"Your host{child.values[0]} left.\n So the room is disbanded\n Please join another room or host one.")
    room_disbanded_label.grid(row=1, column=3)
    container.after(3600 * 8, room_disbanded_label.grid_forget())

class recv_new_players_list_thread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        # display a list of players on the screen
        # it would be in the form of a treeview (of ttk)

        # define our treeview
        time.sleep(1)
        global people_view
        people_view = ttk.Treeview(start_frame, selectmode="none")

        # format our columns
        people_view["columns"] = ("Name", "Designation", "Chance")
        people_view.column("#0", width=0)
        people_view.column("Name", width=150, minwidth=50, anchor="w")
        people_view.column("Designation", width=150, minwidth=40, anchor="w")
        people_view.column("Chance", width=100, minwidth=20, anchor="w")

        # create headings
        people_view.heading("#0", text="")
        people_view.heading("Name", text="Player Name", anchor="w")
        people_view.heading("Designation", text="Designation", anchor="w")
        people_view.heading("Chance", text="Chance", anchor="w")

        # pack to the screen
        people_view.grid(row=5, column=3)

        # we will add data as and when we recv stuff

        # accept new players list as new players do join and the list needs to be updated

        global check_for_new_players_list_stat, start_game_btn, player_desig

        start_btn_shown = False

        # list of players we have taken note of
        noted_players = []

        while True:
            new_players_list = client.recv(1024)
            if new_players_list:
                new_players_list = pickle.loads(new_players_list)
                print(new_players_list)
                items = people_view.get_children()
                print("ITEMS", items)

                if new_players_list == "start game":
                    people_view.grid_forget()
                    break

                elif new_players_list[0] == "player disconnected":
                    # delete the player disconnected
                    # we save each child by its -name(as id)
                    for child in people_view.get_children():
                        if child == new_players_list[0]:
                            if my_item.values[1] == "host":
                                people_view.grid_forget()
                                show_room_disbanded_label()
                                intro_ask_what_to_do()

                            else:
                                noted_players.remove(my_item.values[0])
                                people_view.delete(child)
                                break

                else:
                    # only display start btn when more than one player is there in the room and also dont show again
                    # if already on grid!
                    if len(new_players_list) > 1 and start_btn_shown == False and player_desig == "host":
                        start_game_btn = tk.Button(start_frame, text="Start Game", command=lambda: start_game_host())
                        start_game_btn.grid(row=2, column=1)
                        start_btn_shown = True

                    # incase a player joins and then leaves
                    if len(new_players_list) == 1 and start_btn_shown is True:
                        start_game_btn.grid_forget()
                        start_btn_shown = False

                    for player in new_players_list:
                        if player not in noted_players:

                            # if player index in the list is zero it means he is a host
                            if new_players_list[0] == player:
                                desig = "Host"

                            else:
                                desig = "Player"

                            # add data for the player in treeview
                            # new_players_list.index(player) returns the index of the item in the list
                            people_view.insert(parent="", index="end", text="", iid=player,
                                               values=(player, desig, new_players_list.index(player) + 1))

                            # add the player in noted players so we do not double display the player
                            noted_players.append(player)

                        else:
                            pass

        recv_details_thread = threading.Thread(target=recv_game_details)
        recv_details_thread.start()

def start_game_host():
    start_game_btn.grid_forget()
    client.send(pickle.dumps("start the game"))

def recv_game_details():
    global data_holder
    print(threading.enumerate())
    data_holder = pickle.loads(client.recv(2048))
    print("\n", data_holder, "\n")
    display_thread = threading.Thread(target=display_game_screen())
    display_thread.start()
    cc_thread = threading.Thread(target=choose_color())
    cc_thread.start()

def choose_color():
    # this blocks the execution of all the threads so a work around is made , u will see later

    # variable to store hexadecimal code of color
    color_code = colorchooser.askcolor(title="Choose color")
    print(color_code)
    if color_code[1] is None:
        choose_color()
    else:
        # scr = sendable color tuple
        scr = (username, color_code[1])

        # send our server the color our client chose
        client.send(pickle.dumps(scr))
        get_color_updates()

def get_color_updates():
    global created_objs
    created_objs = {}
    created_objs_list = []
    print(threading.enumerate())

    while True:

        npc = pickle.loads(client.recv(1024))

        data_holder["game info"][npc[0]]["color"] = npc[1]
        created_objs.update({npc[0]: Player(main_frame, status_frame, data_holder, npc[0])})
        created_objs_list.append(npc)

        print(len(created_objs_list), len(data_holder["players list"]))

        if len(created_objs_list) == len(data_holder["players list"]):
            for player in created_objs.values():
                player.status_frame_display(sf_width, sf_height)
            final_stage_tweaks()
            break

def display_game_screen():
    start_frame.grid_forget()
    global main_frame, status_frame, width, height
    main_frame = tk.Frame(container)

    main_frame.grid(row=0, column=0, sticky="nsew")
    width = main_frame.winfo_screenwidth()  # width of screen
    height = main_frame.winfo_screenheight()  # height of screen
    width -= 325
    height -= 345
    width = width / 9
    height = height / 9

    # top lane

    free_parking = my_property_class(main_frame, "Free Parking", 0, 0, 160, 140)
    free_parking.update_dicto(free_parking, 20)

    strand = my_property_class(main_frame, "Strand", 0, 1, width, 140, "firebrick1", 18, 220,
                               90, 250, 700, 875, 1050, 150, 150, 110, "s")
    strand.update_dicto(strand, 21)

    chance2 = my_property_class(main_frame, "Chance", 0, 2, width, 140)
    chance2.update_dicto(chance2, 22)

    fleet_street = my_property_class(main_frame, "fleet street", 0, 3, width, 140, "firebrick1", 18, 220,
                                     90, 250, 700, 875, 1050, 150, 150, 110, "s")
    fleet_street.update_dicto(fleet_street, 23)

    trafalagar_square = my_property_class(main_frame, "trafalagar square", 0, 4, width, 140, "firebrick1", 20, 240,
                                          100, 300, 750, 925, 1100, 150, 150, 120, "s")
    trafalagar_square.update_dicto(trafalagar_square, 24)

    fenchurch_st_station = my_property_class(main_frame, "fenchurch st station", 0, 5, width, 140)
    fenchurch_st_station.update_dicto(fenchurch_st_station, 25)

    licester_square = my_property_class(main_frame, "licester square", 0, 6, width, 140, "yellow", 22, 290,
                                        110, 330, 800, 975, 1150, 150, 150, 130, "s")
    licester_square.update_dicto(licester_square, 26)

    coventry_street = my_property_class(main_frame, "coventry street", 0, 7, width, 140, "yellow", 22, 290,
                                        110, 330, 800, 975, 1150, 150, 150, 130, "s")
    coventry_street.update_dicto(coventry_street, 27)

    water_works = my_property_class(main_frame, "water works", 0, 8, width, 140)
    water_works.update_dicto(water_works, 28)

    piccadilly = my_property_class(main_frame, "piccadilly", 0, 9, width, 140, "yellow", 24, 280,
                                   120, 360, 850, 1025, 1200, 150, 150, 140, "s")
    piccadilly.update_dicto(piccadilly, 29)

    go_to_jail = my_property_class(main_frame, "go_to_jail", 0, 10, 160, 140)
    go_to_jail.update_dicto(go_to_jail, 30)

    # right lane
    regent_street = my_property_class(main_frame, "regent street", 1, 10, 160, height, "green", 26, 300,
                                      130, 390, 900, 1100, 1275, 200, 200, 150, "w")
    regent_street.update_dicto(regent_street, 31)

    oxford_street = my_property_class(main_frame, "oxford street", 2, 10, 160, height, "green", 26, 300,
                                      130, 390, 900, 1100, 1275, 200, 200, 150, "w")
    oxford_street.update_dicto(oxford_street, 32)

    community_chest3 = my_property_class(main_frame, "community_chest 3", 3, 10, 160, height)
    community_chest3.update_dicto(community_chest3, 33)

    bond_street = my_property_class(main_frame, "bond street", 4, 10, 160, height, "green", 28, 320,
                                    150, 450, 1000, 1200, 1400, 200, 200, 160, "w")
    bond_street.update_dicto(bond_street, 34)

    liverpool_st_station = my_property_class(main_frame, "liverpool_st_station", 5, 10, 160, height)
    liverpool_st_station.update_dicto(liverpool_st_station, 35)

    chance3 = my_property_class(main_frame, "Chance", 6, 10, 160, height)
    chance3.update_dicto(chance3, 36)

    park_lane = my_property_class(main_frame, "park_lane", 7, 10, 160, height, "dark blue", 35, 350,
                                  175, 500, 1100, 1300, 1500, 200, 200, 175, "w")
    park_lane.update_dicto(park_lane, 37)

    super_tax = my_property_class(main_frame, "super_tax", 8, 10, 160, height)
    super_tax.update_dicto(super_tax, 38)

    mayfair = my_property_class(main_frame, "mayfair", 9, 10, 160, height, "dark blue", 50, 400,
                                200, 600, 1400, 1700, 2000, 200, 200, 200, "w")
    mayfair.update_dicto(mayfair, 39)

    # lower lane

    just_visiting = my_property_class(main_frame, "just_visting", 10, 0, 160, 140)
    just_visiting.update_dicto(just_visiting, 10)

    pentoville_road = my_property_class(main_frame, "pentoville road", 10, 1, width, 140, "light blue", 8, 120,
                                        40, 100, 300, 450, 600, 50, 50, 60, "n")
    pentoville_road.update_dicto(pentoville_road, 9)

    euston_road = my_property_class(main_frame, "euston road", 10, 2, width, 140, "light blue", 6, 100,
                                    30, 90, 270, 400, 550, 50, 50, 50, "n")
    euston_road.update_dicto(euston_road, 8)

    chance1 = my_property_class(main_frame, "chance", 10, 3, width, 140)
    chance1.update_dicto(chance1, 7)

    the_angel_islington = my_property_class(main_frame, "the angel islington", 10, 4, width, 140, "light blue", 6, 100,
                                            30, 90, 270, 400, 550, 50, 50, 50, "n")
    the_angel_islington.update_dicto(the_angel_islington, 6)

    kings_cross_station = my_property_class(main_frame, "kings cross station", 10, 5, width, 140)
    kings_cross_station.update_dicto(kings_cross_station, 5)

    income_tax = my_property_class(main_frame, "income tax!", 10, 6, width, 140)
    income_tax.update_dicto(income_tax, 4)

    white_chapal_road = my_property_class(main_frame, "white chapal road", 10, 7, width, 140, "brown", 4, 60,
                                          20, 60, 180, 320, 450, 50, 50, 30, "n")
    white_chapal_road.update_dicto(white_chapal_road, 3)

    community_chest1 = my_property_class(main_frame, "community chest 1", 10, 8, width, 140)
    community_chest1.update_dicto(community_chest1, 2)

    old_kent_road = my_property_class(main_frame, "old kent road", 10, 9, width, 140, "brown", 2, 60,
                                      10, 30, 90, 160, 250, 50, 50, 30, "n")
    old_kent_road.update_dicto(old_kent_road, 1)

    go_box = my_property_class(main_frame, "go box", 10, 10, 160, 140)
    go_box.update_dicto(go_box, 0)

    # left lane

    pall_mall = my_property_class(main_frame, "pall mall", 9, 0, 160, height, "pink", 10, 140,
                                  50, 150, 450, 625, 750, 100, 50 * 2, 70, "e")
    pall_mall.update_dicto(pall_mall, 11)

    electric_company = my_property_class(main_frame, "electric company", 8, 0, 160, height)
    electric_company.update_dicto(electric_company, 12)

    white_hall = my_property_class(main_frame, "white hall", 7, 0, 160, height, "pink", 10, 140,
                                   50, 150, 450, 625, 750, 100, 50 * 2, 70, "e")
    white_hall.update_dicto(white_hall, 13)

    northumber_ld_avenue = my_property_class(main_frame, "northumberl'd avenue", 6, 0, 160, height, "pink", 12, 160, 60,
                                             180, 500, 700, 900, 100, 100, 80, "e")
    northumber_ld_avenue.update_dicto(northumber_ld_avenue, 14)

    marylebone_station = my_property_class(main_frame, "marlyebone station", 5, 0, 160, height)
    marylebone_station.update_dicto(marylebone_station, 15)

    bow_street = my_property_class(main_frame, "bow street", 4, 0, 160, height, "orange", 14, 180,
                                   70, 200, 550, 750, 950, 100, 50 * 2, 90, "e")
    bow_street.update_dicto(bow_street, 16)

    community_chest2 = my_property_class(main_frame, "community chest", 3, 0, 160, height)
    community_chest2.update_dicto(community_chest2, 17)

    marlborough_street = my_property_class(main_frame, "marlborough street", 2, 0, 160, height, "orange", 14, 180,
                                           70, 200, 550, 750, 950, 100, 50 * 2, 90, "e")
    marlborough_street.update_dicto(marlborough_street, 18)

    vine_street = my_property_class(main_frame, "vine street", 1, 0, 160, height, "orange", 16, 200,
                                    80, 220, 600, 800, 1000, 100, 50 * 2, 100, "e")
    vine_street.update_dicto(vine_street, 19)

    monopoly_dis = tk.Label(main_frame, text="Monopoly", bg="tomato1", fg="white")
    monopoly_dis.grid(row=5, column=5)

    global sf_width, sf_height
    sf_width = 8 * width
    sf_height = 3 * height
    status_frame = tk.LabelFrame(main_frame, text="Status Box", bg="light green", fg="black",
                                 highlightbackground="black", highlightthickness=1, width=sf_width, height=sf_height)
    status_frame.grid(rowspan=4, columnspan=9, row=1, column=1)

def final_stage_tweaks():
    global data_holder, rd_obj
    global data_holder, rd_obj, chance_label
    del data_holder["color responses"]
    print(data_holder)
    rd_obj = roll_dice_class()

    seek_chance()

    recv_data_updates_thread = threading.Thread(target=recv_data_updates())
    recv_data_updates_thread.start()

def forget_update_reader():
    global update_reader
    update_reader.grid_forget()

def recv_data_updates():
    global dice_roll, update_reader, data_holder
    update_reader = tk.Label(main_frame, font=font,
                             bg="light blue")

    print("recving data updates")
    while True:
        time.sleep(0.2)
        data_update = pickle.loads(client.recv(1024))
        print(data_update)

        if data_update[0] == "conn error":
            data_holder = data_update[2]
            created_objs[data_update[1]].player_left(data_holder, created_objs)
            prop_id["white chapal road"].player_left(data_holder, data_update[1])
            del created_objs[data_update[1]]

        elif len(data_update) == 3:
            # save old position
            global old_pos, data_reader
            chance_num = data_holder["chance"]
            chance_person = data_holder["inverted chances"][chance_num]
            old_pos = data_holder["game info"][chance_person]["position"]
            print(old_pos)

            data_holder["game info"][data_update[0]][data_update[1]] = data_update[2]
            print(data_holder)
            update_caller(data_update)

        elif len(data_update) == 2:
            data_holder[data_update[0]] = data_update[1]
            print(data_holder)

        elif len(data_update) == 4:

            if data_update[1] == "coudn't buy":
                print("couldnt buy")
                # t = data_update[0] + " " + data_update[1] + "\n " + data_update[2] + " " + data_update[3]
                # update_reader["text"] = t
                # update_reader.grid(columnspan=3, rowspan=3, row=6, column=7)

            if data_update[2] == "update" and data_update[1] == "properties":
                # means we have to add something of the dicto about properties
                data_holder["game info"][data_update[0]][data_update[1]].update({data_update[3]: {
                    "houses": 0, }})

                prop_info[data_update[3]]["owner"] = data_update[0]
                # update_reader = tk.Label(main_frame, text=data_update[0] + " \nsuccessfully bought-\n" + data_update[3],
                #                         font=font,
                #                         bg="light blue")
                # update_reader.grid(columnspan=3, row=6, column=7)
                # update_reader["text"] = data_update[0] + " \nsuccessfully bought-\n" + data_update[3]
                # update_reader.grid(columnspan=3, rowspan=3, row=6, column=7)

                created_objs[data_update[0]].property_update(data_update)
                created_objs[data_update[0]].prop_num_label["text"] = "Properties in hand: " + str(
                    len(data_holder["game info"][data_update[0]]["properties"]))

                # to show in prop card
                prop_id[place_id_place_to_pos[data_update[3]]].owner_label["text"] = "Owner: " + str(
                    prop_info[data_update[3]]["owner"])

        else:
            if data_update == ("end my turn"):
                if rd_obj.end_btn_shown == True:
                    rd_obj.end_turn_btn.grid_forget()
                # we are sure that info box 1 will be on grid
                prop_id[new_pos].info_box1.grid_forget()
                # we are not sure if info box 2 will be displayed so
                prop_id[new_pos].info_box2.grid()
                # then forget
                prop_id[new_pos].info_box2.grid_forget()

                if prop_id[new_pos].buy_btn_shown == True:
                    prop_id[new_pos].buy_btn.grid()

                # update_reader.grid(row=6, column=8)
                # update_reader.grid_forget()

                created_objs[call_to].rd_label.grid_forget()

                seek_chance()

            if data_update == ("chance missed"):
                # so that a new cylce of while loop
                # thus a timeout can the be set for the player whose chance is next
                client.send(pickle.dumps(None))
                # chance_label["text"] = data_holder["inverted chances"][data_holder["chance"]] + " missed chance"
                seek_chance()

            # if data_update == ("RC"):
            #    time.sleep(0.4)
            #    client.send(pickle.dumps(("RC")))

            if data_update[1] == "trade proposal":
                if data_update[0] == username:
                    pass
                elif data_update[3] == username:
                    created_objs[username].recv_trade_request()
                else:
                    created_objs[username].watch_trade()

            if data_update[1] == "trade declined":
                created_objs[username].trade_declined()

            if data_update[1] == "trade finalised":
                created_objs[username].trade_finalised()

def seek_chance():
    global chance_label
    if data_holder["chance"] == data_holder["player chances"][username]:
        print("My Chance")
        # chance_label = tk.Label(main_frame, text="It's your chance", font=font)
        # chance_label.grid(row=6, column=9, rowspan=2)
        rd_obj.show_dice_btn()
        # other things will be handled by the server and our data update method

    else:
        print("not my chance")
        # chance_label = tk.Label(main_frame,
        #                        text=str(data_holder["inverted chances"][data_holder["chance"]]) + "'s chance",
        #                        font=font)
        # chance_label.grid(row=6, column=9, rowspan=2)

def update_caller(data_update):
    global created_objs, call_to
    # gives the name of player so that we can call that person from created objects dictionary
    call_to = data_update[0]
    print("calling update for", call_to)
    print("what is to be changed", data_update[1])
    print("what it will be changed to", data_update[2])

    # we may have to change- position, money, any other stat in status bo,etc

    # for position change
    if data_update[1] == "position":
        global new_pos
        global new_pos, chance_label
        # chance_label.grid_forget()
        new_pos = data_update[2]
        created_objs[call_to].update_data_holder(data_holder)
        created_objs[call_to].update_position(row_coordinates, column_coordinates, place_num, old_pos, data_update[2],
                                              place_id_place_to_pos, prop_id, data_update[0], username, client, rd_obj)

        # show end turn btns after token is moved and only if it is your chance ___ ofc
        # if data_update[0] == username:
        #   rd_obj.show_end_turn_btns()

        # just this and our work is done

    if data_update[1] == "money":
        time.sleep(0.4)
        created_objs[call_to].money_label["text"] = "Money: " + str(data_update[2])

# use when needed , gets dice roll
def get_dice_roll(new_pos, old_pos):
    dice_roll = new_pos - old_pos
    if dice_roll > 12:
        dice_roll = 40 - dice_roll

    # more on the way

    return dice_roll

class roll_dice_class:

    def __init__(self):
        self.end_btn_shown = False

    def show_dice_btn(self):
        # to make testing easier the random process of rolling dice is removed so as to get more controll in dice rolled
        self.roll_dice_d = tk.Entry(main_frame)
        self.roll_dice_d.grid(row=6, column=6)

        self.okay = tk.Button(main_frame, command=lambda: self.virtual_dice(), text=f"Okay")
        self.okay.grid(row=7, column=6)

        self.timer_label = tk.Label(main_frame, text=f"Click Before 30 seconds", )
        self.timer_label.grid(row=6, column=7)
        self.responded = False
        timer_thread = threading.Thread(target=self.roll_dice_timer())
        timer_thread.start()

    def roll_dice_timer(self):
        t = 30
        while True:
            if self.responded == False:
                t -= 1

                self.timer_label["text"] = f"Click Before \n{t} seconds"
                time.sleep(1)

                if t == 0:
                    self.timer_label['text'] = "You missed you chance!"
                    self.roll_dice_d.grid_forget()
                    self.okay.grid_forget()
                    container.after(3600 * 3, lambda: self.timer_label.grid_forget())
                    break

            else:
                self.timer_label.grid_forget()
                break

    def virtual_dice(self):
        self.responded = True
        # self.roll_dice_d.grid_forget()
        # self.dice_roll1 = random.randint(1, 6)
        # self.dice_roll2 = random.randint(1, 6)
        # self.dice_roll = self.dice_roll1 + self.dice_roll2
        self.roll_dice_d.grid_forget()
        self.okay.grid_forget()
        self.dice_roll = int(self.roll_dice_d.get())
        self.show_dice = tk.StringVar()
        self.label_dice = "Dice Roll = " + str(self.dice_roll)
        self.show_dice.set(self.label_dice)

        position = data_holder["game info"][username]["position"]
        position += self.dice_roll
        # last place is no.39 , so limit position within 0 to 39
        if position > 39:
            # todo:
            #   reward 200 to complete round
            position -= 39

        # so that server makes responded to true
        # client.send(pickle.dumps("rolled"))
        # send our server so it munches down the data
        client.send(pickle.dumps((username, "position", position)))
        # then the data muncher on our side will recv and update the screen

        self.show_end_turn_btns()

    def show_end_turn_btns(self):
        self.end_btn_shown = True
        self.end_turn_btn = tk.Button(main_frame, text="End Turn!", font=font, command=lambda: self.end_turn_clicked())
        self.end_turn_btn.grid(row=6, column=6)

    def end_turn_clicked(self):
        self.end_btn_shown = False
        # display btns when necessary only
        self.end_turn_btn.grid_forget()
        client.send(pickle.dumps(("end my turn")))
        my_property_class.grid_forget_buy_btn()

container.mainloop()


principal_str = input("How much did you or do you intend to borrow?\n")
annual_rate_str = input("What is the annual rate?\n")
years_str = input("What is the loan term?\n")
no_payments_made_str = input("Have you made any payments so far?\n")

principal = float(principal_str)
annual_rate = float(annual_rate_str)
years = float(years_str)
no_payments_made = float(no_payments_made_str)

no_payments = years * 12
monthly_rate = annual_rate / 12

def monthly_payment_calc(principal,monthly_rate,no_payments):

    if monthly_rate == 0:
        monthly_payment = principal/no_payments
    else:
        rP = monthly_rate * principal
        rN = (1 + monthly_rate)**(-1 * no_payments)
        monthly_payment = rP/(1-rN)

    return monthly_payment

#test
monthly_payment = monthly_payment_calc(principal,monthly_rate,no_payments)
print("Your monthly payment is or will be ${monthly_payment}".format(monthly_payment=monthly_payment))

def interest(principal, monthly_rate, monthly_payment, no_payments_made, no_payments):

    total_interest = no_payments * monthly_payment - principal

    rpc = principal * monthly_rate - monthly_payment
    rn = (1 + monthly_rate)**(no_payments_made)
    cn = monthly_payment * no_payments_made
    cumilitive_interest = rpc*(rn-1)/monthly_rate + cn

    return total_interest, cumilitive_interest

#test
total_interest, cumilitive_interest = interest(principal, monthly_rate, monthly_payment, no_payments_made, no_payments)
print("You have paid ${interest} in interest so far.".format(interest=cumilitive_interest))
print("Your total interest at the end of the loan term will be ${tot_int}".format(tot_int = total_interest))


from nltk.corpus.reader.util import *
from nltk.corpus.reader.xmldocs import XMLCorpusReader

from .tokenize import AncientGreekPunktVar
from nltk.corpus.reader.api import *
from nltk.tokenize import *

from MyCapytain.resources.texts.local.capitains.cts import CapitainsCtsText
from MyCapytain.common.constants import Mimetypes, XPATH_NAMESPACES

class CapitainCorpusReader(CorpusReader):
    """
    Reader for corpora that consist of MyCapitain-compliant documents.
    Sentences and words can be tokenized using the default tokenizers,
    or by custom tokenizers specified as parameters to the constructor.

    For sentence tokenization, the default tokenizer is set to  use
    the Ancient Greek sentence-delimiting punctuation.
    """

    # CorpusView = StreamBackedCorpusView
    """Here we should create a corpus viewer, but it was too hard..."""

    def __init__(self, root, fileids,
                 word_tokenizer=WordPunctTokenizer(),
                 sent_tokenizer=PunktSentenceTokenizer(lang_vars=AncientGreekPunktVar()),
                 exclude_tags=['tei:note'],
                 encoding='utf8'):
        """
        Construct a new citable corpus reader for a set of documents
        located at the given root directory.

        Parameters
        ----------
        root : str
            The root directory for this corpus.
        fileids : str or list
            A list or regexp specifying the fileids in this corpus.
        word_tokenizer : nltk Tokenizer
            Tokenizer for breaking sentences or paragraphs into words
        sent_tokenizer : nltk Tokenizer
            Tokenizer for breaking paragraphs into sentences.
            Defaults with The Ancient Greek sentence-ending punctuation!
        exclude_tags : list
            TEI tags whose text should not be extracted.
        """

        CorpusReader.__init__(self, root, fileids, encoding)
        self._word_tokenizer = word_tokenizer
        self._sent_tokenizer = sent_tokenizer
        # we copy the list with list() to avoid the notorious problem with mutable default args
        self._tags_to_exclude = list(exclude_tags)

    def _get_citable_text(self, fileid):
        """
        Parameters
        ----------
        fileid: str
            The file identifier of the file to read

        Returns
        -------
        CapitainsCtsText object

        """

        with open(self._root.join(fileid)) as f:
            text = CapitainsCtsText(resource=f)
        return text

    def _set_fileids(self, fileids):
        """If fileids is None, then return the whole corpus;
        if it is a single file then return a 1-element list

        Returns
        -------
        list
            of file pointer(s)

        """
        if fileids is None:
            fileids = self._fileids
        elif isinstance(fileids, string_types):
            fileids = [fileids]
        return fileids

    def raw(self, fileids=None):
        """Returns the given file(s) as a single string.

        Parameters
        ----------
        fileids : None, list, str, path
            file identifier or pointer. If None, then the whole corpus is returned

        Returns
        -------
        str

        """
        fileids = self._set_fileids(fileids)

        raw_texts = []
        for f in fileids:
            text = self._get_citable_text(f)
            raw_texts.extend(self._read_paras(text))

        return concat(raw_texts)

    def words(self, fileids=None):
        """
        :return: the given file(s) as a list of words
            and punctuation symbols.
        :rtype: list(str)
        """
        fileids = self._set_fileids(fileids)
        words = []
        for f in fileids:
            text = self._get_citable_text(f)
            words.extend(self._read_words(text))
        return words

    def sents(self, fileids=None):
        """
        :return: the given file(s) as a list of
            sentences or utterances, each encoded as a list of word
            strings.
        :rtype: list(list(str))
        """
        if self._sent_tokenizer is None:
            raise ValueError('No sentence tokenizer for this corpus')

        fileids = self._set_fileids(fileids)
        sents = []
        for f in fileids:
            text = self._get_citable_text(f)
            sents.extend(self._read_sents(text))

        return sents

    def cite_words(self, fileid):
        """
        Parameters
        ----------
        fileid : str
            the file name of the text you want to get citable words from

        Returns
        -------
        list(tuple(str,str))
            the text as list of tuple (cite, token)

        """
        if not isinstance(fileid, string_types):
            raise TypeError('Expected a single file identifier string')
        text = self._get_citable_text(fileid)
        return self._read_words(text, include_cites=True)

    def cite_sents(self, fileid):
        """
        Parameters
        ----------
        fileid : str
            the file name of the text you want to get citable words from

        Returns
        -------
        list(list(tuple(str,str)))
            the text as list of lists (sentences); each sentence is a list of tuples (cite, token)

        """
        if not isinstance(fileid, string_types):
            raise TypeError('Expected a single file identifier string')
        text = self._get_citable_text(fileid)
        return self._read_sents(text, include_cites=True)

    def corpus_cite_words(self):
        """
        Get text identifier, tokens and citations for all the tokens in all the files of the corpus.

        WARNING:
        the file id's must be formatted using a cts compatible format: auth_id.work_id

        Returns
        -------
        list (tuple)
            list of (text_id, cite, token)

        """
        import os
        cite_words = []
        for f in self.fileids():
            txt_ids = os.path.basename(f).split(".")[:2]
            _words = [(".".join(txt_ids), w[0], w[1]) for w in self.cite_words(f)]
            cite_words.extend(_words)
        return cite_words

    def paras(self, fileids=None):
        """
        Returns a series of sections, corresponding to the last citeable level identified
        by Capitain. It does not do much more than what the Capitain API does, but it may
        be helpful for some use cases.

        :return: the given file(s) as a list of
            sections.
        :rtype: list (str)
        """
        fileids = self._set_fileids(fileids)
        paras = []
        for f in fileids:
            text = self._get_citable_text(f)
            paras.extend(self._read_paras(text))
        return paras

    def _read_words(self, capitain_file, include_cites=False):
        secs = self._read_paras(capitain_file, include_cites)
        text = " ".join(secs) if not include_cites else "".join(secs[1])
        if include_cites:
            spans = self._word_tokenizer.span_tokenize(text)
            words = self._word_tokenizer.tokenize(text)
            cite_words = []
            for span,word in zip(spans, words):
                c = self._return_cite(span, secs[0])
                cite_words.append((c, word))
            return cite_words
        else:
            text = "".join(concat(secs))
            return self._word_tokenizer.tokenize(text)

    def _read_sents(self, capitain_file, include_cites=False):
        secs = self._read_paras(capitain_file, include_cites)

        text = "".join(secs) if not include_cites else "".join(secs[1])
        rawsents = self._sent_tokenizer.tokenize(text)
        sents = [self._word_tokenizer.tokenize(s) for s in rawsents]

        if not include_cites:
            return sents
        else:
            # get the cite_words and regroup them with sents
            sizes = [len(s) for s in sents]
            _cite_words = self._read_words(capitain_file, include_cites=True)
            it = iter(_cite_words)
            cite_sents = [[next(it) for _ in range(size)] for size in sizes]
            return cite_sents

    def _return_cite(self, span, cites):
        for c in cites:
            if span[-1] <= c[-1]:
                return c[0]

    def _read_paras(self, capitain_file, include_cites=False):
        """

        Parameters
        ----------
        capitain_file : CapitainsCtsText
            the cts object to read text and cites from
        include_cites : bool
            whether to return text only or refs + text

        Returns : list
        -------
            list of textual sections, or list of references and texts

        """
        paras = []
        refs = []
        b, e = 0, 0
        for ref in capitain_file.getReffs(level=len(capitain_file.citation)):
            psg = capitain_file.getTextualNode(subreference=ref, simple=True)
            t = psg.export(Mimetypes.PLAINTEXT, exclude=self._tags_to_exclude) + " "
            paras.append(t)
            e += len(t)
            refs.append((ref, b, e))
            b = e
        if include_cites:
            return refs, paras
        else:
            return paras


import tensorflow as tf
from tensorflow.python.data import Dataset

from socialdetector.utility import is_listing, glob_iterator, path_glob_iterator

def print_ds(ds):
    print(list(ds.as_numpy_iterator()))

def datasets_concatenate(datasets):
    ds = datasets[0]
    for d in datasets[1:]:
        ds = ds.concatenate(d)
    return ds

def split_image_fn(tile_size, strides=None):
    t = [1, *tile_size, 1]
    r = [1 for _ in t]
    if strides is None:
        s = t
    else:
        s = [1, *strides, 1]

    def split(image):
        patches = tf.image.extract_patches(image, sizes=t, strides=s, rates=r, padding='VALID')
        return tf.reshape(patches[0], (-1, *tile_size, *image.shape[3:]))

    return split

def tf_print(*args):
    tf.print(*args)
    return args[0]

def str_endswith(end_regex):
    rg = ".*" + end_regex + "$"
    return lambda x: tf.strings.regex_full_match(x, rg, name="tf_ends_with")

def datasets_interleave(datasets, block_length=None, cycle_length=None):
    datasets = tuple(datasets)
    if cycle_length is not None:
        return datasets_concatenate(
            [datasets_interleave(datasets[i:i + cycle_length], block_length=block_length) for i in
             range(0, len(datasets), cycle_length)])

    choices = Dataset.range(len(datasets))

    if block_length is not None:
        if not is_listing(block_length):
            block_length = tuple(block_length for _ in range(len(datasets)))
        choices = datasets_concatenate(
            [Dataset.from_tensors(tf.convert_to_tensor(i, dtype=tf.int64)).repeat(block_length[i]) for i in
             range(len(datasets))])

    return tf.data.experimental.choose_from_datasets(datasets, choices.cache().repeat())

def glob_dataset(pattern, recursive=True):
    return Dataset.from_generator(lambda: glob_iterator(pattern, recursive=recursive), output_types=tf.string)

def path_glob_dataset(path, pattern, recursive=True):
    return Dataset.from_generator(lambda: path_glob_iterator(path, pattern, recursive=recursive),
                                  output_types=tf.string)


import numpy as np

##########################################################
# INPUT description:
# Your algorithms receive 4 inputs:
# I <- an initial feasible basis
# c <- a numpy array that you will use as your objective function
# A,b <- a matrix and vector describing the constraint
#
#      A.dot(x) = b
#
# OUTPUT description:
# You algorithms should return two things:
# 1. the value of the optimal solution v.
#     - Assuming an optimal solution x, get this with c.dot(x).
#     - Alternatively, you can use c[I].dot(xI), where xI
#       is the vector obtained from the optimal basis.
# 2. an optimal solution x
#     - This should be in the form of a numpy array.
#     - Assuming an optimal basis I and associated
#       inverse of A restricted to index set I, called AI,
#       you can construct it with:
#
#       x = np.zeros(c.shape[0])
#       x[I] = AI.dot(b)
#
# return them with the statement: return (v, x)
##########################################################

##########################################################
# Implement the simplex algorithm here.
##########################################################
def simplex(I, c, A, b):
    rows = len(A)
    cols = len(A[0])
    zero = -(10 ** (-12))
    AI = np.linalg.inv(A[:,I])
    x = AI.dot(b)
    found = False
    n = 0

    while True:
        AI = np.linalg.inv(A[:,I])
        for j in range(cols):
            temp = c[:,I].dot(AI)
            temp = temp.dot(A[:,j])
            temp = c[j] - temp

            if (temp < zero):
                found = True
                break

        if not(found):
            break

        found = False
        dJ = -(AI.dot(A[:,j]))
        for i in range(len(I)):
            if (dJ[i] < zero):
                iStar = i
                aStar =  -(x[i] / dJ[i])
                break

        for i in range(len(I)):
            temp = -(x[i] / dJ[i])

            if (temp < aStar) and (dJ[i] < zero):
                iStar = i
                aStar = temp
        for i in range(len(I)):
            x[i] = x[i] + (aStar * dJ[i])

        x[iStar] = aStar
        I[iStar] = j

    x = np.zeros(c.shape[0])
    AI = np.linalg.inv(A[:,I])
    x[I] = AI.dot(b)
    v = c.dot(x)
    return (v, x)


# -*- coding: utf-8 -*-
import logging
import datetime
from odoo import models, fields, api

_logger = logging.getLogger(__name__)

class product_configurator_check(models.Model):
    _inherit = 'product.template'

    check = fields.Selection([
        ('no', '未確認'),
        ('yes', '確認済'),
    ], default='no',
        string="確認",
        tracking=True)

    def write(self, values):
        flg = self._origin.check
        print(values)
        # _logger.debug('Create a %s with vals %s', self._name, values)
        if self._origin.check == 'no' and values.get("check") == 'yes':
            values['check'] = 'yes'
        else:
            if 'taxes_id' in values or 'image_1920' in values or 'sequence' in values:
                values['check'] = 'yes'
            else:
                values['check'] = 'no'
        res = super(product_configurator_check, self).write(values)
        return res


from math import ceil
base64_img_uuid = 'd34c301e-10c3-11e4-9b79-5f67ca448df0'

initial_vms = ['1.fifo', '1.manager.leofs', '2.manager.leofs', '1.gateway.leofs', '1.storage.leofs']

hyper_min_ram_min = 8
hyper_min_disk_min = 10

hyper_min_ram_good = 32
hyper_min_disk_good = 100

vm_sizing_min = {
    'fifo_zone_disk' :   15,
    'fifo_zone_mem'  : 3072,
    'leo_mngr_disk'  :    5,
    'leo_mngr_mem'   :  512,
    'leo_gate_disk'  :    5,
    'leo_gate_mem'   : 1024,
    'leo_store_disk' :   40,
    'leo_store_mem'  : 1024,
}

vm_sizing_good = {
    'fifo_zone_disk' :   40,
    'fifo_zone_mem'  : 4096,
    'leo_mngr_disk'  :   10,
    'leo_mngr_mem'   : 1024,
    'leo_gate_disk'  :   10,
    'leo_gate_mem'   : 2048,
    'leo_store_disk' :   40,
    'leo_store_mem'  : 1024,
}

user_script = '"user-script" : "/usr/sbin/mdata-get root_authorized_keys > ~root/.ssh/authorized_keys ; /usr/sbin/mdata-get root_authorized_keys > ~admin/.ssh/authorized_keys; chmod 700 /root/.ssh; chmod 600 /root/.ssh/authorized_keys" '

def fifoZoneCount(hypervisorCount):
    if hypervisorCount == 1 or hypervisorCount == 2:
        return 1
    elif hypervisorCount == 3:
        return 3
    elif hypervisorCount == 4:
        return 4
    elif hypervisorCount > 1000: # formula below is only good for upto 1000
        return 50
    elif hypervisorCount > 4:
        a = 3.5986571221740977
        b = 0.10270953891690970
        c = -0.000056316603749656695
        result = a + (b * hypervisorCount) + (c * pow(hypervisorCount, 2))
        return ceil(result)
    return false


import matplotlib.pyplot as plt
import numpy as np

def getConfusedImage(img,key):
    img_arr = np.reshape(img,(65536,1))
    k = np.array(img_arr[:,0],dtype=int)
    confusedImg = np.zeros((65536,),dtype=int)

    for i in range(len(k)):
        confusedImg[i] = img_arr[key[i],0]

    confusedImg = np.reshape(confusedImg,(256,256))

    return confusedImg


from abc import ABC, abstractmethod
from typing import Any
from pandasai.helpers.env import is_running_in_console
from ..helpers.df_info import polars_imported

from pandasai.exceptions import MethodNotImplementedError

class IResponseParser(ABC):
    @abstractmethod
    def parse(self, result: dict) -> Any:
        """
        Parses result from the chat input
        Args:
            result (dict): result contains type and value
        Raises:
            ValueError: if result is not a dictionary with valid key

        Returns:
            Any: Returns depending on the user input
        """
        raise MethodNotImplementedError

class ResponseParser(IResponseParser):
    _context = None

    def __init__(self, context) -> None:
        """
        Initialize the ResponseParser with Context from SmartDataLake
        Args:
            context (Context): context contains the config, logger and engine
        """
        self._context = context

    def parse(self, result: dict) -> Any:
        """
        Parses result from the chat input
        Args:
            result (dict): result contains type and value
        Raises:
            ValueError: if result is not a dictionary with valid key

        Returns:
            Any: Returns depending on the user input
        """
        if not isinstance(result, dict) or not all(
            key in result for key in ["type", "value"]
        ):
            raise ValueError("Unsupported result format")

        if result["type"] == "dataframe":
            return self.format_dataframe(result)
        elif result["type"] == "plot":
            return self.format_plot(result)
        else:
            return self.format_other(result)

    def format_dataframe(self, result: dict) -> Any:
        """
        Format dataframe generate against a user query
        Args:
            result (dict): result contains type and value
        Returns:
            Any: Returns depending on the user input
        """
        from ..smart_dataframe import SmartDataframe

        df = result["value"]
        if self._context.engine == "polars" and polars_imported:
            import polars as pl

            df = pl.from_pandas(df)

        return SmartDataframe(
            df,
            config=self._context._config.__dict__,
            logger=self._context.logger,
        )

    def format_plot(self, result: dict) -> Any:
        """
        Display matplotlib plot against a user query
        Args:
            result (dict): result contains type and value
        Returns:
            Any: Returns depending on the user input
        """
        import matplotlib.pyplot as plt
        import matplotlib.image as mpimg

        # Load the image file
        try:
            image = mpimg.imread(result["value"])
        except FileNotFoundError:
            raise FileNotFoundError(f"The file {result['value']} does not exist.")
        except OSError:
            raise ValueError(f"The file {result['value']} is not a valid image file.")

        # Display the image
        plt.imshow(image)
        plt.axis("off")
        plt.show(block=is_running_in_console())
        plt.close("all")

    def format_other(self, result) -> Any:
        """
        Returns the result generated against a user query other than dataframes
        and plots
        Args:
            result (dict): result contains type and value
        Returns:
            Any: Returns depending on the user input
        """
        return result["value"]


import argparse
import csv
import sys

def dict_reader(csvfile):
    return csv.DictReader(
        csvfile, delimiter=',', quotechar='|', fieldnames=['signature'])

def dotPackageToSlashPackage(pkg):
    return pkg.replace('.', '/')

def slashPackageToDotPackage(pkg):
    return pkg.replace('/', '.')

def isSplitPackage(splitPackages, pkg):
    return splitPackages and (pkg in splitPackages or '*' in splitPackages)

def matchedByPackagePrefixPattern(packagePrefixes, prefix):
    for packagePrefix in packagePrefixes:
        if prefix == packagePrefix:
            return packagePrefix
        elif prefix.startswith(packagePrefix) and prefix[len(
                packagePrefix)] == '/':
            return packagePrefix
    return False

def validate_package_prefixes(splitPackages, packagePrefixes):
    # If there are no package prefixes then there is no possible conflict
    # between them and the split packages.
    if len(packagePrefixes) == 0:
        return

    # Check to make sure that the split packages and package prefixes do not
    # overlap.
    errors = []
    for splitPackage in splitPackages:
        if splitPackage == '*':
            # A package prefix matches a split package.
            packagePrefixesForOutput = ', '.join(
                map(slashPackageToDotPackage, packagePrefixes))
            errors.append(
                'split package "*" conflicts with all package prefixes %s\n'
                '    add split_packages:[] to fix' % packagePrefixesForOutput)
        else:
            packagePrefix = matchedByPackagePrefixPattern(
                packagePrefixes, splitPackage)
            if packagePrefix:
                # A package prefix matches a split package.
                splitPackageForOutput = slashPackageToDotPackage(splitPackage)
                packagePrefixForOutput = slashPackageToDotPackage(packagePrefix)
                errors.append(
                    'split package %s is matched by package prefix %s' %
                    (splitPackageForOutput, packagePrefixForOutput))
    return errors

def validate_split_packages(splitPackages):
    errors = []
    if '*' in splitPackages and len(splitPackages) > 1:
        errors.append('split packages are invalid as they contain both the'
                      ' wildcard (*) and specific packages, use the wildcard or'
                      ' specific packages, not a mixture')
    return errors

def produce_patterns_from_file(file, splitPackages=None, packagePrefixes=None):
    with open(file, 'r') as f:
        return produce_patterns_from_stream(f, splitPackages, packagePrefixes)

def produce_patterns_from_stream(stream,
                                 splitPackages=None,
                                 packagePrefixes=None):
    splitPackages = set(splitPackages or [])
    packagePrefixes = list(packagePrefixes or [])
    # Read in all the signatures into a list and remove any unnecessary class
    # and member names.
    patterns = set()
    for row in dict_reader(stream):
        signature = row['signature']
        text = signature.removeprefix('L')
        # Remove the class specific member signature
        pieces = text.split(';->')
        qualifiedClassName = pieces[0]
        pieces = qualifiedClassName.rsplit('/', maxsplit=1)
        pkg = pieces[0]
        # If the package is split across multiple modules then it cannot be used
        # to select the subset of the monolithic flags that this module
        # produces. In that case we need to keep the name of the class but can
        # discard any nested class names as an outer class cannot be split
        # across modules.
        #
        # If the package is not split then every class in the package must be
        # provided by this module so there is no need to list the classes
        # explicitly so just use the package name instead.
        if isSplitPackage(splitPackages, pkg):
            # Remove inner class names.
            pieces = qualifiedClassName.split('$', maxsplit=1)
            pattern = pieces[0]
        else:
            # Add a * to ensure that the pattern matches the classes in that
            # package.
            pattern = pkg + '/*'
        patterns.add(pattern)

    # Remove any patterns that would be matched by a package prefix pattern.
    patterns = list(
        filter(lambda p: not matchedByPackagePrefixPattern(packagePrefixes, p),
               patterns))
    # Add the package prefix patterns to the list. Add a ** to ensure that each
    # package prefix pattern will match the classes in that package and all
    # sub-packages.
    patterns = patterns + list(map(lambda x: x + '/**', packagePrefixes))
    # Sort the patterns.
    patterns.sort()
    return patterns

def main(args):
    args_parser = argparse.ArgumentParser(
        description='Generate a set of signature patterns '
        'that select a subset of monolithic hidden API files.')
    args_parser.add_argument(
        '--flags',
        help='The stub flags file which contains an entry for every dex member',
    )
    args_parser.add_argument(
        '--split-package',
        action='append',
        help='A package that is split across multiple bootclasspath_fragment modules'
    )
    args_parser.add_argument(
        '--package-prefix',
        action='append',
        help='A package prefix unique to this set of flags')
    args_parser.add_argument('--output', help='Generated signature prefixes')
    args = args_parser.parse_args(args)

    splitPackages = set(map(dotPackageToSlashPackage, args.split_package or []))
    errors = validate_split_packages(splitPackages)

    packagePrefixes = list(
        map(dotPackageToSlashPackage, args.package_prefix or []))

    if not errors:
        errors = validate_package_prefixes(splitPackages, packagePrefixes)

    if errors:
        for error in errors:
            print(error)
        sys.exit(1)

    # Read in all the patterns into a list.
    patterns = produce_patterns_from_file(args.flags, splitPackages,
                                          packagePrefixes)

    # Write out all the patterns.
    with open(args.output, 'w') as outputFile:
        for pattern in patterns:
            outputFile.write(pattern)
            outputFile.write('\n')

if __name__ == '__main__':
    main(sys.argv[1:])


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

import string
N = int(input())

while(N > 0):
    text = input()
    text = text[::-1]
    result = ''
    alf = string.ascii_lowercase

    for key,letter in enumerate(text):
        if((letter.lower() in alf)):
            a = chr(ord(letter)+3)
        else:
            a = letter

        if(key >= (len(text)//2)):
            a = chr(ord(a)-1)

        result += a

    print(result)
    N -=1


#!/bin/python

from ROOT import *
gROOT.SetBatch(True)
import os
from stackPlots import *
from samples import *

gROOT.ProcessLine(".L ~/tdrstyle.C")
gROOT.ProcessLine("setTDRStyle()")

samples = [ "znunu" , "ttbar" , "Wjets" , "QCD" ]
vars = [ "HT" , "MHT" , "MET" , "mT2" , "mT2_zeroMass" ,
         "alphaT" , "alphaT_dHThemi" , "mRazor" , "dRazor" ,
         "mEff" , "NJets" , "NLeptons" , "dPhi" ,
         "dEta" , "sumJetMass" , "leadJetPt", "baselineYields"
         ]

for s in allSig :
    s.norm=True
    s.stack=False

for s in allBkg:
    s.norm=True
    s.stack=False
    s.lineColor=s.fillColor
    s.fillColor=0

can = TCanvas("can","can",500,500)
for var in vars :

    #stackPlots(sampleChoices=allsamples , inputFile="genericPlotter.root" , x=var)
    f = TFile("genericPlotter.root")
    leg = TLegend(0.6,0.6,0.9,0.9)
    leg.SetBorderSize(0)
    leg.SetFillColor(0)

    first = True
    max=0
    for s in allsamples :
        s.histo = f.Get(var+"_"+s.histoTag)
        if s.histo == None : continue
        s.histo.Scale(1./s.histo.Integral())
        if s.histo.GetMaximum() > max :
            max = s.histo.GetMaximum()
        s.setStyle()
        if first :
            s.histo.Draw("HIST")
            first=False
        else :
            s.histo.Draw("HIST,SAME")
        leg.AddEntry(s.histo,s.legLabel,"f")

    allsamples[0].histo.SetMaximum(max*1.5)

    leg.Draw()
    can.SaveAs("{0}_compareShapes.png".format(var))


#################################################################
# Wikipedia Search for Historical Firm Founding Dates
# firm-founding-wiki-search.py
# Author: Meredith M. Paker, merpaker@gmail.com
# Last edited: 17 November, 2017
# This script uses python's Wikipedia package search functionality
#     to link a historical firm with its suggested Wikipedia information
#     in order to predict the correct founding date for the firm.
#################################################################

import wikipedia
import re

### IMPORT COMPANY LIST ###

company_list = open('CompanyList.txt', encoding='utf-16')
company_list_text = company_list.read()
company_list.close()
company_set = company_list_text.split('\n')

wiki_output = open('WikipediaFoundingDates.txt', mode='a', encoding='utf-8')

### CYCLE THROUGH EACH COMPANY ###

for company in company_set:

	# Search for company on wikipedia
	isWikiPage = 1
	try:
		search_results = wikipedia.search(company)[0]
	except IndexError as f:
		print("Error: {0}".format(f))
		search_results = ""
		isWikiPage = 0

	# Make new wikipedia object for the company
	if isWikiPage == 1:
		try:
			company_wiki = wikipedia.page(search_results)
		except wikipedia.exceptions.DisambiguationError as e:
			print("Error: {0}".format(e))
			isWikiPage = 0

	# Save the plain text of the wiki page
	if isWikiPage == 1:
		wiki_text = company_wiki.content
	else:
		wiki_text = ""

	# Parse plain text paragraphs into sentences
	from nltk.tokenize import sent_tokenize
	wiki_sentences = sent_tokenize(wiki_text)

	# Store full set of sentences
	wiki_sentences_full = wiki_sentences*1

	# Delete sentences without the company name
	for i in reversed(range(len(wiki_sentences))):
		if company not in wiki_sentences[i]:
			del wiki_sentences[i]

	# Store set of sentences with company name
	wiki_sentences_company = wiki_sentences*1

	# Delete sentences without "founded" or "established" from
	# set of sentences with company name

	for i in reversed(range(len(wiki_sentences))):
		if ("founded" or "established") not in wiki_sentences[i]:
			del wiki_sentences[i]

	# Store set of sentences with company name and founding
	wiki_sentences_founded = wiki_sentences*1

	# Generate output string
	company_output = company
	company_output += "; "
	company_output += search_results
	company_output += "; "

	# Search for years in all three scopes: full page, company sentences, founded/established
	# Put all years in output string
	# Update best-guess as appropriate
	# Update flag if best guess is from full page
	best_guess = 9000
	conf = 0
	# Full wikipedia page search
	for i in range(len(wiki_sentences_full)):
		d = re.findall('\d{4}', wiki_sentences_full[i])
		for j in range(len(d)):
			if int(d[j]) > 1600:
				if int(d[j]) < 1913:
					company_output += d[j]
					company_output += ", "
					if not wiki_sentences_company:
						if int(d[j]) < best_guess:
							best_guess = int(d[j])
						conf = 1
	company_output += "; "

	# Search in sentences with company name
	for i in range(len(wiki_sentences_company)):
		d = re.findall('\d{4}', wiki_sentences_company[i])
		for j in range(len(d)):
			if int(d[j]) > 1600:
				if int(d[j]) < 1913:
					company_output += d[j]
					company_output += ", "
					if not wiki_sentences_founded:
						if int(d[j]) < best_guess:
							best_guess = int(d[j])
						conf = 2
	company_output += "; "

	# Search in sentences with company name & "founded" or "established"
	for i in range(len(wiki_sentences_founded)):
		d = re.findall('\d{4}', wiki_sentences_founded[i])
		for j in range(len(d)):
			if int(d[j]) > 1600:
				if int(d[j]) < 1913:
					company_output += d[j]
					company_output += ", "
					if int(d[j]) < best_guess:
						best_guess = int(d[j])
					conf = 3
	company_output += "; "

	company_output += str(conf)
	company_output += "; "
	company_output += str(best_guess)

	print(company_output)
	wiki_output.write(company_output)

# So final company_output string will be as follows:

# company name, wikipedia page or blank, date(s) from full page,
# dates from sentences with company name, dates from sentences with
# company name and "founded" or "established", confidence in predicted
# founded year, best guess at founded year

wiki_output.close()


import sys

input = sys.stdin.readline

# 2331 반복수열
# a 부터 시작하여 각 자릿수의 p제곱을 더한 수가 다음수가 되는 수열에서
# 반복구간을 제외한 수열의 길이를 구하는 문제
# 처음 중복된 수가 나타난 인덱스를 구하여 해결
def sol2331():
    a, p = map(int, input().split())
    nums = {}
    idx = 0
    while a not in nums:
        nums[a] = idx
        idx += 1
        tmp = 0
        while a:
            tmp += (a % 10) ** p
            a //= 10
        a = tmp
    return nums[a]


import os
import sys

from qisys import ui
import qisys.sh
import qisys.parsers
import qisys.worktree
import qisrc.parsers
import qisrc.worktree

def configure_parser(parser):
    """Configure parser for this action """
    qisys.parsers.worktree_parser(parser)
    qisrc.parsers.groups_parser(parser)
    parser.add_argument("manifest_url", nargs="?")
    parser.add_argument("-b", "--branch", dest="branch",
        help="Use this branch for the manifest")
    parser.add_argument("--no-review", dest="review", action="store_false",
        help="Do not sync the review remotes")
    parser.add_argument("--all", dest="all", action="store_true",
        help="Do not use the default group, and clone all the projects "
             "of the manifest")
    parser.add_argument("--clone",
        help="Use the given worktree to do faster local clones")
    parser.set_defaults(branch="master", all=False, review=True)

def do(args):
    """Main entry point"""
    root = args.worktree or os.getcwd()
    qisys.sh.mkdir(root, recursive=True)
    worktree = qisys.worktree.WorkTree(root)
    git_worktree = qisrc.worktree.GitWorkTree(worktree)
    worktree_clone = None
    if args.clone:
        candidate_clone_path = qisys.sh.to_native_path(args.clone)
        dot_qi = os.path.join(candidate_clone_path, ".qi")
        git_xml = os.path.join(dot_qi, "git.xml")
        if not os.path.exists(git_xml):
            mess = """\
Invalid --clone argument
Worktree in {0} does not appear to be a valid qisrc worktree
({1} does not exist)
"""
            sys.exit(mess.format(args.clone, git_xml))
        candidate_worktree = qisys.worktree.WorkTree(candidate_clone_path)
        worktree_clone = qisrc.worktree.GitWorkTree(candidate_worktree)
    if args.manifest_url:
        if os.path.isdir(args.manifest_url):
            args.manifest_url = qisys.sh.to_native_path(args.manifest_url)
        ok = git_worktree.configure_manifest(args.manifest_url,
                                        groups=args.groups,
                                        branch=args.branch,
                                        review=args.review,
                                        all_repos=args.all,
                                        worktree_clone=worktree_clone)
        if not ok:
            sys.exit(1)

    ui.info(ui.green, "New qisrc worktree initialized in",
            ui.reset, ui.bold, root)


import sys
import os

sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
import struct
import socket
import config
import util.simsocket as simsocket
from config import Type
from typing import List, Tuple, Dict

class UDP:
    def __init__(self, sock: simsocket) -> None:
    # def __init__(self, sock: None) -> None:
        self.HEADER_LEN = struct.calcsize(config.headerType)
        self.BUF_SIZE = 1400
        self.MAGIC = 52305
        self.TEAM = config.TEAM
        self.sock = sock
        # self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    def pack(self, type1: int, data: bytes, seq: int, ack: int, sf: int, rwnd: int = 0):
        a = (
                struct.pack(
                    config.headerType,
                    self.MAGIC,
                    self.TEAM,
                    type1,
                    struct.calcsize(config.headerType),
                    self.HEADER_LEN + len(data),
                    seq,
                    ack,
                    sf,
                    rwnd,
                )
                + data
        )
        return a

    def unpack(self, package: bytes):
        return (
            struct.unpack(config.headerType, package[: self.HEADER_LEN]),
            package[self.HEADER_LEN:],
        )

    def send(self, package: bytes, addr: Tuple[str, int]):
        # _, _, type1, _, totalLen, seq, ack, sf, rwnd = struct.unpack(config.headerType, package[: self.HEADER_LEN])
        # print(f"SEND {addr[1]}: dataLen:{totalLen - self.HEADER_LEN} seq:{seq} ack:{ack} sf:{sf} rwnd:{rwnd}")
        self.sock.sendto(package, addr)

    def sendSegment(self, type1: Type, data: bytes, seq: int, ack: int, sf: int, rwnd: int = 0, addr: Tuple[str, int] = None):
        self.send(self.pack(type1.value, data, seq, ack, sf, rwnd), addr)

    def recv(self):
        package, addr = self.sock.recvfrom(self.BUF_SIZE)
        header, data = self.unpack(package)
        return header, data, addr

# UDP = UDP(None)
# # # a = UDP.pack(1, b"123", 1, 1, 1, 1)
# a = b'\xccQ\x01\x00\x00\x15\x00)\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;h\x11\x08G\x94\x1b\x84\xe8\xd0T\x17\xa5\xb2`\x91"\xa5c\x14'
# # # print(a)
# print(UDP.unpack(a))


from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.preprocessing import FunctionTransformer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.ensemble import AdaBoostClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.naive_bayes import MultinomialNB
from sklearn import metrics
import pylab as py
import pickle
from scipy.sparse import hstack
from scipy.sparse import coo_matrix
from tqdm import tqdm
from scipy import sparse
import csv, random, numpy, os, re, scipy, gensim
from sklearn.neural_network import MLPClassifier
from sklearn import tree
from langdetect import detect
from sklearn.ensemble import RandomForestClassifier
from csv import DictReader
import numpy as np
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
import matplotlib.pyplot as plt
import seaborn as sns
from xgboost import XGBClassifier

# import score

import nltk
import ssl

try:
    _create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
    pass
else:
    ssl._create_default_https_context = _create_unverified_https_context

nltk.download('punkt')
nltk.download('wordnet')

class DataSet():
    def __init__(self, path=""):
        self.path = path

        print("Reading dataset")
        bodies = "train_bodies.csv"
        stances = "train_stances.csv"

        self.stances = self.read(stances)
        articles = self.read(bodies)
        self.articles = dict()

        #make the body ID an integer value
        for s in self.stances:
            s['Body ID'] = int(s['Body ID'])

        #copy all bodies into a dictionary
        for article in articles:
            self.articles[int(article['Body ID'])] = article['articleBody']

        print("Total stances: " + str(len(self.stances)))
        print("Total bodies: " + str(len(self.articles)))

    def read(self,filename):
        rows = []
        with open(self.path + "" + filename, "r", encoding='utf-8') as table:
            r = DictReader(table)

            for line in r:
                rows.append(line)
        return rows

dataset = DataSet()

def read_ids(file,base):
    ids = []
    with open(base+""+file,"r") as f:
        for line in f:
            ids.append(int(line))
        return ids

def split(dataset, base=""):
    if not (os.path.exists(""+"training_ids.txt")
            and os.path.exists(""+"dev_ids.txt") and os.path.exists(""+"test_ids.txt")):
        raise Exception("There is an error and the dataset reader cannot find the "
                        "{training_ids|test_ids|dev_ids}.txt file. Please make sure your python paths "
                        "are configured correctly")

    training_ids = read_ids("training_ids.txt",base)
    dev_ids = read_ids("dev_ids.txt",base)
    test_ids = read_ids("test_ids.txt",base)

    #return the stances that meet these criteria
    training_stances = []
    dev_stances = []
    test_stances = []

    for stance in dataset.stances:
        if stance['Body ID'] in training_ids:
            training_stances.append(stance)
        elif stance['Body ID'] in dev_ids:
            dev_stances.append(stance)
        elif stance['Body ID'] in test_ids:
            test_stances.append(stance)

    return {"training":training_stances, "dev":dev_stances, "test": test_stances}

print("\n[1] Loading data..")
data_splits = split(dataset)
# in the format: Stance, Headline, BodyID
training_data = data_splits['training']
dev_data = data_splits['dev']
test_data = data_splits['test'] # currently 0 test points

# Change the number of training examples used.
N = int(len(training_data) * 1.0)
training_data = training_data[:N]

print("\t-Training size:\t", len(training_data))
print("\t-Dev size:\t", len(dev_data))
print("\t-Test data:\t", len(test_data))

# Get the bodies of training data points
def get_bodies(data):
    bodies = []
    for i in range(len(data)):
        bodies.append(dataset.articles[data[i]['Body ID']])
    return bodies

# Get the headlines of training data points
def get_headlines(data):
    headlines = []
    for i in range(len(data)):
        headlines.append(data[i]['Headline'])
    return headlines

# Get bodies and headlines for dev and training data
training_bodies = get_bodies(training_data)
training_headlines = get_headlines(training_data)
dev_bodies = get_bodies(dev_data)
dev_headlines = get_headlines(dev_data)
test_bodies = get_bodies(test_data)
test_headlines = get_headlines(test_data)

print(len(training_bodies))
print(len(training_headlines))
print(len(dev_bodies))
print(len(dev_headlines))
print(len(test_bodies))
print(len(test_headlines))

# Function for extracting tf-idf vectors (for both the bodies and the headlines).
# https://www.kaggle.com/adamschroeder/countvectorizer-tfidfvectorizer-predict-comments

def extract_tfidf(training_headlines, training_bodies, dev_headlines="", dev_bodies="", test_headlines="", test_bodies=""):
    # Body vectorisation
    body_vectorizer = TfidfVectorizer(ngram_range=(1, 2), lowercase=True, stop_words='english')#, max_features=1024)
    bodies_tfidf = body_vectorizer.fit_transform(training_bodies)

    # Headline vectorisation
    headline_vectorizer = TfidfVectorizer(ngram_range=(1, 2), lowercase=True, stop_words='english')#, max_features=1024)
    headlines_tfidf = headline_vectorizer.fit_transform(training_headlines)

    with open('body_vectorizer.pk', 'wb') as b:
        pickle.dump(body_vectorizer, b)

    with open('headline_vectorizer.pk', 'wb') as h:
        pickle.dump(headline_vectorizer, h)

    # Tranform dev/test bodies and headlines using the trained vectorizer (trained on training data)
    bodies_tfidf_dev = body_vectorizer.transform(dev_bodies)
    headlines_tfidf_dev = headline_vectorizer.transform(dev_headlines)

    bodies_tfidf_test = body_vectorizer.transform(test_bodies)
    headlines_tfidf_test = headline_vectorizer.transform(test_headlines)

    feature_names = np.array(body_vectorizer.get_feature_names())
    sorted_by_idf = np.argsort(body_vectorizer.idf_)
    print('Features with lowest and highest idf in the body vector:\n')
    # The token which appears maximum times but it is also in all documents, has its idf the lowest
    print("Features with lowest idf:\n{}".format(
    feature_names[sorted_by_idf[:10]]))
    # The tokens can have the most idf weight because they are the only tokens that appear in one document only
    print("\nFeatures with highest idf:\n{}".format(
    feature_names[sorted_by_idf[-10:]]))

    # Combine body_tfdif with headline_tfidf for every data point.
    training_tfidf = scipy.sparse.hstack([bodies_tfidf, headlines_tfidf])
    dev_tfidf = scipy.sparse.hstack([bodies_tfidf_dev, headlines_tfidf_dev])
    test_tfidf = scipy.sparse.hstack([bodies_tfidf_test, headlines_tfidf_test])

    return training_tfidf, dev_tfidf, test_tfidf

lemmatizer = nltk.WordNetLemmatizer()

# Tokenisation, Normalisation, Capitalisation, Non-alphanumeric removal, Stemming-Lemmatization
def preprocess(string):
    # to lowercase, non-alphanumeric removal
    step1 = " ".join(re.findall(r'\w+', string, flags=re.UNICODE)).lower()
    step2 = [lemmatizer.lemmatize(t).lower() for t in nltk.word_tokenize(step1)]

    return step2

# Function for extracting word overlap
def extract_word_overlap(headlines, bodies):
    word_overlap = []
    for i, (headline, body) in tqdm(enumerate(zip(headlines, bodies))):
        preprocess_headline = preprocess(headline)
        preprocess_body = preprocess(body)

        # Lenght of common words b/w body and headline / Length of all the words of body & headline
        features = len(set(preprocess_headline).intersection(preprocess_body)) / float(len(set(preprocess_headline).union(preprocess_body)))
        word_overlap.append(features)

        # Convert the list to a sparse matrix (in order to concatenate the cos sim with other features)
        word_overlap_sparse = scipy.sparse.coo_matrix(numpy.array(word_overlap))
    return word_overlap_sparse

# Function for extracting the cosine similarity between bodies and headlines.
def extract_cosine_similarity(headlines, bodies):
    vectorizer = TfidfVectorizer(ngram_range=(1,2), lowercase=True, stop_words='english')#, max_features=1024)

    cos_sim_features = []
    for i in range(0, len(bodies)):
        body_vs_headline = []
        body_vs_headline.append(bodies[i])
        body_vs_headline.append(headlines[i])
        tfidf = vectorizer.fit_transform(body_vs_headline)

        cosine_similarity = (tfidf * tfidf.T).A
        cos_sim_features.append(cosine_similarity[0][1])

    # Convert the list to a sparse matrix (in order to concatenate the cos sim with other features)
    cos_sim_array = scipy.sparse.coo_matrix(numpy.array(cos_sim_features))

    return cos_sim_array

# Function for combining features of various types (lists, coo_matrix, np.array etc.)
def combine_features(tfidf_vectors, cosine_similarity, word_overlap):
    combined_features =  sparse.bmat([[tfidf_vectors, word_overlap.T, cosine_similarity.T]])
    return combined_features

# Function for extracting features
# Feautres: 1) Word Overlap, 2) TF-IDF vectors, 3) Cosine similarity, 4) Word embeddings
def extract_features(train, dev, test):
# Get bodies and headlines for dev and training data
    training_bodies = get_bodies(training_data)
    training_headlines = get_headlines(training_data)
    dev_bodies = get_bodies(dev_data)
    dev_headlines = get_headlines(dev_data)
    test_bodies = get_bodies(test_data)
    test_headlines = get_headlines(test_data)

    # Extract tfidf vectors
    print("\t-Extracting tfidf vectors..")
    training_tfidf, dev_tfidf, test_tfidf = extract_tfidf(training_headlines, training_bodies, dev_headlines, dev_bodies, test_headlines, test_bodies)
    print("\t-Tfidf vectors extracted..")

    # Extract word overlap
    print("\t-Extracting word overlap..")
    training_overlap = extract_word_overlap(training_headlines, training_bodies)
    dev_overlap = extract_word_overlap(dev_headlines, dev_bodies)
    test_overlap = extract_word_overlap(test_headlines, test_bodies)
    print("\t-Word overlap extracted..")

#     # Extract cosine similarity between bodies and headlines.
    print("\t-Extracting cosine similarity..")
    training_cos = extract_cosine_similarity(training_headlines, training_bodies)
    dev_cos = extract_cosine_similarity(dev_headlines, dev_bodies)
    test_cos = extract_cosine_similarity(test_headlines, test_bodies)
    print("\t-Cosine similarity extracted..")

    # Combine the features
    training_features = combine_features(training_tfidf, training_cos, training_overlap)
    dev_features = combine_features(dev_tfidf, dev_cos, dev_overlap)
    test_features = combine_features(test_tfidf, test_cos, test_overlap)
    print("\t-Combined features returned..")

    return training_features, dev_features, test_features

# Feature extraction
print("[2] Extracting features.. ")
# extract_features(training_data, dev_data, test_data)
training_features, dev_features, test_features = extract_features(training_data, dev_data, test_data)

classes = ['agree', 'disagree', 'discuss', 'unrelated']

def report_score(test,pred,algo):
    #accuracy calculation
    accuracy = accuracy_score(test,pred)
    print('\n Accuracy_score for %s = %s \n'%(algo,accuracy))

    #confusion_matrix
    mat = confusion_matrix(test,pred)
    fig, ax = plt.subplots(figsize=(11,11))
    ax.set_title("Confusion Matrix for %s" %algo)
    sns.heatmap(mat.T, square=True, annot=True, fmt='d', cbar=True,cmap="icefire",
                xticklabels=classes,yticklabels=classes,linewidths=.3, ax=ax)
    plt.xlabel('True label')
    plt.ylabel('Predicted label');

    #classification report
    cls = classification_report(test,pred, target_names=classes)
    print(cls)

# Creating targets
targets_tr = [a['Stance'] for a in training_data]
targets_dev = [a['Stance'] for a in dev_data]
targets_test = [a['Stance'] for a in test_data]

def change(f):
    if f == 'unrelated':
        return 0
    elif f == 'disagree':
        return 1
    elif f == 'discuss':
        return 2
    elif f == 'agree':
        return 3
    else:
        return 0

y = [change(x) for x in targets_tr]
y_test = [change(x) for x in targets_test]

def predict(self, text):
        predicted = self.logR_pipeline.predict([text])
        predicedProb = self.logR_pipeline.predict_proba([text])[:,1]
        return bool(predicted), float(predicedProb)

# Fitting model
print("[3] Fitting model..")
print("\t-Logistic Regression")
lr = LogisticRegression(C = 1.0, class_weight='balanced', solver="lbfgs", max_iter=150)
y_pred_lr = lr.fit(training_features, targets_tr).predict(test_features)
# Evaluation
print("[4] Evaluating model..")
report_score(targets_test, y_pred_lr,'Logistic Regression')
print("\t-Done with Logistic Regression")

pickle.dump(lr, open('stance.pkl', 'wb'))
print('successfully saved model file')


from pico2d import *
import os

TUK_WIDTH, TUK_HEIGHT = 1200, 900
os.chdir('d:\\2021184011_2DGP_project\\Sprite_use')

open_canvas(TUK_WIDTH, TUK_HEIGHT)
character = load_image('Unit3Motion_MoveAa1.png')
enemy1 = load_image('Unit14Motion_MoveA.png')
enemy2 = load_image('Unit15Motion_MoveA.png')
enemy3 = load_image('Unit22Motion_MoveA.png')
x, y = TUK_WIDTH // 2, TUK_HEIGHT // 2
character.clip_draw(0, 0, 39, 67, 100, 100,50,80)
enemy1.clip_draw(0, 0, 122, 150, 300, 100,60,90)
enemy2.clip_draw(0, 0, 112, 118, 500, 100,110,120)
enemy3.clip_draw(0, 0, 105, 119, 700, 100,110,120)
update_canvas()
delay(50)
close_canvas()


class Solution:
    def getRow(self, rowIndex: int) -> List[int]:
        dp = [[1] for _ in range(rowIndex+1)]

        for i in range(1, rowIndex+1):
            for j in range(1, i):
                dp[i].append(dp[i-1][j-1] + dp[i-1][j])
            else:
                dp[i].append(1)

        return dp[rowIndex]

# intution, use the code for pascal's triangle 1, however this is a only return the index of the dp 2d array
# but rowIndex is still the same as n rows to be generated, so essentially the same code here
# since the first row is always 1, initialise a dp 2d list to have 1 as the starting value
# due to range not being inclusive because of 0 indexed, rowIndex of 3 actually means 4 lists, therefore we need to
# calculate rowIndex+1 amount of rows


import re, os, pandas, pickle
from pandas import DataFrame, read_pickle
from CSutils import emojiDict, ask, cleanTweet, millis
from QueryTwitter import getRawTwitterDataFrames

saveFolder = os.path.join('.', 'data', 'EmojiFrames')

def main():
	if ask("Make NEW EmojiFrames from raw DataFrames? (WARN: file collision causes overwrite)"):
		skip = ask("Skip all the prompts and just save automatically?")
		for eFrame in getEmojiFramesFromRawDFs():
			print("NEW EmojiFrame:", eFrame.emojiName, end='')
			print(" shape is", eFrame.frame.shape)
			if not skip and ask("Print this", eFrame.emojiName, "EmojiFrame?"):
				print(eFrame)
			if skip or ask("Save this", eFrame.emojiName, "EmojiFrame?"):
				eFrame.save()
	if ask("See existing EmojiFrames?"):
		start = millis()
		print("Loading EmojiFrames takes... ", end='')
		eFrames = list(getExistingEmojiFrames())
		print(millis()-start, "ms", sep='')
		for ef in eFrames:
			print("EmojiFrame:", ef.emojiName, "shape is", ef.frame.shape)

def getEmojiFramesFromRawDFs():
	for fname, df in getRawTwitterDataFrames():
		emojiName = fname.split('.')[0]
		if emojiName in emojiDict:
			ef = EmojiFrame(emojiName, df)
			yield ef
		else:
			print("Can't tell if emoji:", fname)

def getExistingEmojiFrames():
	efFiles = os.listdir(path=saveFolder)
	eFrames = list()
	for fname in efFiles:
		if re.match("ef_.*\\.p", fname):
			filepath = os.path.join(saveFolder, fname)
			with open(filepath, 'rb') as fileObj:
				try:
					eFrame = pickle.load(fileObj)
					if eFrame.emojiName in emojiDict:
						yield eFrame
					else:
						print("Can't tell if emoji:", eFrame.emojiName)
				except Exception as e:
					print("Error while loading EmojiFrame:", fname)
					print("Error:", e)
					print("Skipping".ljust(70, "."))

class EmojiFrame:
	def __init__(self, emojiName, rawDataFrame):
		self.emojiName = emojiName
		self.emojiSymbol = emojiDict[emojiName]
		goodData = self.getGoodData(rawDataFrame)
		self.frame = DataFrame(data=goodData)
		self.dropDuplicateTweets()
		print("EmojiFrame created:", emojiName, "with shape", self.frame.shape)

	def shape(self):
		return self.frame.shape

	def getCleanTweets(self):
		return self.frame['cleanTweet']

	def getCleanTweetsList(self):
		return self.getCleanTweets().values.tolist()

	def dropDuplicateTweets(self):
		original = self.frame.shape[0]
		self.frame.drop_duplicates(subset='cleanTweet', inplace=True)
		now = self.frame.shape[0]
		print("Dropping duplicates: %s -> %s tweets" % (original, now))

	def save(self, filepath=None):
		if filepath == None:
			filepath = os.path.join(saveFolder, 'ef_'+self.emojiName+'.p')
		with open(filepath, "wb") as fileObject:
			pickle.dump(self, fileObject)
		print("Saved:", filepath)

	def __repr__(self):
		width = 120
		title = ("EmojiFrame: "+self.emojiName).center(width//4)
		output = [title.center(width, '#')]
		with pandas.option_context('display.max_rows', 10, 'display.width', width):
			output.append(repr(self.frame))
		return '\n'.join(output)

	def getGoodData(self, rawFrame: DataFrame):
		goodData = dict()
		goodData['tweetID'] = rawFrame['id']
		goodData['dateCreated'] = rawFrame['created_at']
		rawTweets = rawFrame['full_text']
		goodData['rawTweet'] = rawTweets
		goodData['userName'] = [d['screen_name'] for d in rawFrame['user']]
		goodData['cleanTweet'] = [cleanTweet(t) for t in rawTweets]
		goodData['isRetweet'] = ["RT " in t for t in rawTweets]
		return goodData

if __name__ == '__main__':
	main()


from PyQt5.QtCore import pyqtSignal, QObject, pyqtSlot, QRunnable
from send2trash import send2trash, TrashPermissionError
import shutil
import uuid
import os

ON_SUCCESS = 1
ON_CANCEL = 2
ON_ERROR = 3

class TransferSignals(QObject):
    """
    Defines the signals available from a running worker thread.
    Supported signals are:
    finished
    `str` transfer id
    progress
    `int` indicating % progress
    """
    __slots__ = ()

    finished = pyqtSignal(str)
    progress = pyqtSignal(str, int)
    transferred = pyqtSignal(str, float)
    duplicate = pyqtSignal(str)

class Transfer(QRunnable):
    """
    File transfer runnable
    Runs on a different thread
    inherits:
        QRunnable
    parameters:
        `src`: str file path
        `dst`: str file/dir path
        `size`: float `src` file size in bytes
    """
    __slots__ = (
        "src", "dst", "size",
        "signals", "running", "job_id")

    def __init__(self, src, dst, size):
        super().__init__()
        self.src = src
        self.dst = dst
        # create dst file
        if os.path.isdir(dst):
            self.dst = os.path.join(dst, _basename(src))
        self.size = size
        self.signals = TransferSignals()
        self.running = 0
        # Give this job a unique ID.
        self.job_id = str(uuid.uuid4())

    @pyqtSlot()
    def run(self):
        # run the specified function
        if file_exists(self.src, self.dst):
            # end prematurely and emit dst
            print(f"File already exists '{self.dst}'")
            self.signals.duplicate.emit(self.dst)
            self.signals.progress.emit(self.job_id, 100)
            self.signals.finished.emit(self.job_id)

        else:
            self.copy(self.src, self.dst)

    def _copyfileobj_readinto(self, fsrc, fdst, length=1048576):
        """
        readinto()/memoryview()-based variant of copyfileobj()
        *fsrc* must support readinto() method and both files must be
        open in binary mode.
        """
        print(f"Transferring, method: readinto, buffer: {length}")
        progress = 0
        self.running = 1
        # localize variable access to minimize overhead
        fsrc_readinto = fsrc.readinto
        fdst_write = fdst.write
        with memoryview(bytearray(length)) as mv:
            try:
                while 1:
                    n = fsrc_readinto(mv)
                    if not n:
                        self.signals.finished.emit(self.job_id)
                        self.running = 0
                        print("Successful transfer")
                        return ON_SUCCESS

                    elif n < length:
                        with mv[:n] as smv:
                            fdst.write(smv)
                    else:
                        fdst_write(mv)
                    progress += n
                    percentage = (progress * 100) / self.size
                    self.signals.transferred.emit(self.job_id, progress)
                    self.signals.progress.emit(self.job_id, percentage)
                    # handle cancel
                    if not self.running:
                        print("Cancelled transfer")
                        self.signals.progress.emit(self.job_id, 100)
                        self.signals.finished.emit(self.job_id)
                        return ON_CANCEL
            except Exception as e:
                print(f"Error in transferring: {str(e)}")
                self.running = 0
                self.signals.progress.emit(self.job_id, 100)
                self.signals.finished.emit(self.job_id)
                return ON_ERROR

    def _copyfileobj(self, fsrc, fdst, length=1048576):
        """
        copy data from file-like object fsrc to file-like object fdst
        return success
        """
        print(f"Transferring, method: copy-buffer, buffer: {length}")
        progress = 0
        self.running = 1
        # localize variables to avoid overhead
        fsrc_read = fsrc.read
        fdst_write = fdst.write
        try:
            while 1:
                buff = fsrc_read(length)
                if not buff:
                    self.signals.finished.emit(self.job_id)
                    self.running = 0
                    # break and return success
                    print("Successful transfer")
                    return ON_SUCCESS

                fdst_write(buff)
                progress += len(buff)
                percentage = (progress * 100) / self.size
                self.signals.transferred.emit(self.job_id, progress)
                self.signals.progress.emit(self.job_id, percentage)
                # handle cancel
                if not self.running:
                    print("Cancelled transfer")
                    self.signals.progress.emit(self.job_id, 100)
                    self.signals.finished.emit(self.job_id)
                    return ON_CANCEL

        except Exception as e:
            print(f"Error in transferring: {str(e)}")
            self.running = 0
            self.signals.progress.emit(self.job_id, 100)
            self.signals.finished.emit(self.job_id)
            return ON_ERROR

    def _copyfile(self, src, dst):
        """ check if file exists, if same filesystem, else prepare file objects """

        try:
            # prepare file objects for read/write
            with open(src, 'rb') as fsrc:
                with open(dst, 'wb') as fdst:
                    if self.size > 0:
                        return self._copyfileobj_readinto(fsrc, fdst, length=min(1048576, self.size))
                    # copy files with 0 sizes
                    return self._copyfileobj(fsrc, fdst)
        except PermissionError:
            self.signals.progress.emit(self.job_id, 100)
            self.signals.finished.emit(self.job_id)
            return ON_ERROR

    def copy(self, src, dst):
        """ rename folders and prepare files for copying """

        done = self._copyfile(src, dst)
        if done == ON_SUCCESS:
            # copy file, then copy file stats
            self.copy_stat(src, dst)
        if done == ON_CANCEL:
            # clean up incomplete dst file

            print(f"Deleting incomplete file '{dst}'")
            delete_file(dst)
        return done

    def copy_stat(self, src, dst):
        try:
            shutil.copystat(src, dst)
        except Exception as e:
            print(f"Stats error: {e}")

def _basename(path):
    """ strip trailing slash and return basename """
    # A basename() variant which first strips the trailing slash, if present.
    # Thus we always get the last component of the path, even for directories.
    # borrowed from shutil.py
    sep = os.path.sep + (os.path.altsep or '')
    return os.path.basename(path.rstrip(sep))

def file_exists(src, dst) -> bool:
    """ compare file properties """
    if os.path.isdir(dst):
        dst = os.path.join(dst, _basename(src))
    if os.path.exists(dst):
        # return (os.path.getsize(src) == os.path.getsize(dst))
        return True
    return False

def delete_file(filename, trash=False):
    """
    permanently delete a file if `trash` is False
    """
    if trash:
        try:
            send2trash(filename)
        except TrashPermissionError as e:
            print(f"Cannot trash file: {e}")
    else:
        try:
            os.unlink(filename)
        except Exception as e:
            print(f"Cannot remove file: {e}")

def convert_bytes(num: float) -> str:
    """ format bytes to respective units for presentation (max GB) """
    try:
        if num >= 1073741824:
            return f"{round(num / 1073741824, 2)} GB"
        elif num >= 1048576:
            return f"{round(num / 1048576, 2)} MB"
        elif num >= 1024:
            return f"{round(num / 1024, 2)} KB"
        else:
            return f"{num} Bytes"
    except Exception:
        return "NaN"