import random
import itertools
from collections import Counter
from tkinter import *
from PIL import ImageTk, Image  #  only non_standard dependency you need to DL
import threading
import queue
import time

def main():
    class Card(object):
        def __init__(self, value, suit):
            self.value = value
            self.suit = suit
            self.showing = True

        def __repr__(self):
            value_name = ""
            suit_name = ""
            if self.showing:
                if self.value == 0:
                    value_name = "Two"
                if self.value == 1:
                    value_name = "Three"
                if self.value == 2:
                    value_name = "Four"
                if self.value == 3:
                    value_name = "Five"
                if self.value == 4:
                    value_name = "Six"
                if self.value == 5:
                    value_name = "Seven"
                if self.value == 6:
                    value_name = "Eight"
                if self.value == 7:
                    value_name = "Nine"
                if self.value == 8:
                    value_name = "Ten"
                if self.value == 9:
                    value_name = "Jack"
                if self.value == 10:
                    value_name = "Queen"
                if self.value == 11:
                    value_name = "King"
                if self.value == 12:
                    value_name = "Ace"
                if self.suit == 0:
                    suit_name = "Diamonds"
                if self.suit == 1:
                    suit_name = "Clubs"
                if self.suit == 2:
                    suit_name = "Hearts"
                if self.suit == 3:
                    suit_name = "Spades"
                return value_name + " of " + suit_name
            else:
                return "[CARD]"

    class StandardDeck(list):
        def __init__(self):
            super().__init__()
            suits = list(range(4))
            values = list(range(13))
            [[self.append(Card(i, j)) for j in suits] for i in values]

        def __repr__(self):
            return f"Standard deck of cards\n{len(self)} cards remaining"

        def shuffle(self):
            random.shuffle(self)
            print("\n\n--deck shuffled--")

        def deal(self, location, times=1):
            for i in range(times):
                location.cards.append(self.pop(0))

        def burn(self):
            self.pop(0)

    class Player(object):
        def __init__(self, name=None):
            self.name = name
            self.chips = 0
            self.stake = 0
            self.stake_gap = 0
            self.cards = []
            self.score = []
            self.fold = False
            self.ready = False
            self.all_in = False
            self.list_of_special_attributes = []
            self.win = False

        def __repr__(self):
            name = self.name
            return name

    class Game(object):
        def __init__(self):
            self.need_raise_info = False
            self.game_over = False
            self.acting_player = Player()
            self.possible_responses = []
            self.round_counter = 0
            self.cards = []
            self.pot = 0
            self.pot_dict = {}
            self.pot_in_play = 0
            self.list_of_player_names = []
            self.dealer = Player()
            self.small_blind = Player()
            self.big_blind = Player()
            self.first_actor = Player()
            self.winners = []
            self.deck = StandardDeck()
            self.list_of_scores_from_eligible_winners = []
            self.setup = ask_app("Start?")
            while True:
                try:
                    self.number_of_players = len(self.setup["players"])
                    break
                except ValueError:
                    print("Invalid response")
            if 1 < self.number_of_players < 11:
                pass
            else:
                print("Invalid number of players")
                main()
            self.list_of_players = [Player(name) for name in self.setup["players"] if name != ""]
            while True:
                try:
                    self.starting_chips = int(self.setup["chips"][0])
                    if self.starting_chips > 0:
                        break
                    print("Invalid number, try greater than 0")
                except ValueError:
                    print("Invalid response")
                    continue
            for player in self.list_of_players:
                player.chips = self.starting_chips
            self.ready_list = []
            while True:
                try:
                    self.small_blind_amount = int(self.setup["chips"][1])
                    if self.starting_chips > self.small_blind_amount > 0:
                        break
                    print("Invalid number: try bigger than zero, smaller than starting chips")
                except ValueError:
                    print("Invalid response")
                    continue
            while True:
                try:
                    self.big_blind_amount = int(self.setup["chips"][2])
                    if self.starting_chips > self.big_blind_amount > self.small_blind_amount:
                        break
                    print("Invalid number: try bigger than small blind, smaller than starting chips")
                except ValueError:
                    print("Invalid response")
                    continue
            self.winner = None
            self.action_counter = 0
            self.attribute_list = ["d", "sb", "bb", "fa"]
            self.highest_stake = 0
            self.fold_list = []
            self.not_fold_list = []
            self.round_ended = False
            self.fold_out = False
            self.list_of_scores_eligible = []
            self.list_of_players_not_out = list(set(self.list_of_players))
            self.number_of_player_not_out = int(len(list(set(self.list_of_players))))

        def print_game_info(self):
            pass

        def print_round_info(self):
            print("\n")
            for player in self.list_of_players:
                print("\n")
                print(f"Name: {player.name}")
                print(f"Cards: {player.cards}")
                print(f"Player score: {player.score}")
                print(f"Chips: {player.chips}")
                print(f"Special Attributes: {player.list_of_special_attributes}")
                if player.fold:
                    print(f"Folded")
                if player.all_in:
                    print(f"All-in")
                print(f"Stake: {player.stake}")
                print(f"Stake-gap: {player.stake_gap}")
                print("\n")
            print(f"Pot: {self.pot}")
            print(f"Community cards: {self.cards}")
            print("\n")

        def establish_player_attributes(self):
            address_assignment = 0
            self.dealer = self.list_of_players_not_out[address_assignment]
            self.dealer.list_of_special_attributes.append("dealer")
            address_assignment += 1
            address_assignment %= len(self.list_of_players_not_out)
            self.small_blind = self.list_of_players_not_out[address_assignment]
            self.small_blind.list_of_special_attributes.append("small blind")
            address_assignment += 1
            address_assignment %= len(self.list_of_players_not_out)
            self.big_blind = self.list_of_players_not_out[address_assignment]
            self.big_blind.list_of_special_attributes.append("big blind")
            address_assignment += 1
            address_assignment %= len(self.list_of_players_not_out)
            self.first_actor = self.list_of_players_not_out[address_assignment]
            self.first_actor.list_of_special_attributes.append("first actor")
            self.list_of_players_not_out.append(self.list_of_players_not_out.pop(0))

        def deal_hole(self):
            for player in self.list_of_players_not_out:
                self.deck.deal(player, 2)

        def deal_flop(self):
            self.deck.burn()
            self.deck.deal(self, 3)

        def deal_turn(self):
            self.deck.burn()
            print("\n--card burned--")
            self.deck.deal(self, 1)
            print(f"\nCommunity Cards: {self.cards}")

        def deal_river(self):
            self.deck.burn()
            print("\n--card burned--")
            self.deck.deal(self, 1)
            print(f"\n\nCommunity Cards: {self.cards}")

        def hand_scorer(self, player):
            seven_cards = player.cards + self.cards
            all_hand_combos = list(itertools.combinations(seven_cards, 5))
            list_of_all_score_possibilities = []
            for i in all_hand_combos:
                suit_list = []
                value_list = []
                for j in i:
                    suit_list.append(j.suit)
                    value_list.append(j.value)
                initial_value_check = list(reversed(sorted(value_list)))
                score1 = 0
                score2 = 0
                score3 = 0
                score4 = initial_value_check.pop(0)
                score5 = initial_value_check.pop(0)
                score6 = initial_value_check.pop(0)
                score7 = initial_value_check.pop(0)
                score8 = initial_value_check.pop(0)
                list_of_pair_values = []
                other_cards_not_special = []
                pair_present = False
                pair_value = int
                value_counter = dict(Counter(value_list))
                for value_name, count in value_counter.items():
                    if count == 2:
                        pair_present = True
                        pair_value = value_name
                        list_of_pair_values.append(value_name)
                if pair_present:
                    for value in value_list:
                        if value not in list_of_pair_values:
                            other_cards_not_special.append(value)
                    other_cards_not_special = list(reversed(sorted(other_cards_not_special)))
                    if len(set(list_of_pair_values)) == 1:
                        score1 = 1
                        score2 = max(list_of_pair_values)
                        try:
                            score3 = other_cards_not_special.pop(0)
                            score4 = other_cards_not_special.pop(0)
                            score5 = other_cards_not_special.pop(0)
                            score6 = other_cards_not_special.pop(0)
                            score7 = other_cards_not_special.pop(0)
                            score8 = other_cards_not_special.pop(0)
                        except IndexError:
                            pass
                    if len(set(list_of_pair_values)) == 2:
                        list_of_pair_values = list(reversed(sorted(list_of_pair_values)))
                        score1 = 2
                        score2 = list_of_pair_values.pop(0)
                        score3 = list_of_pair_values.pop(0)
                        try:
                            score4 = other_cards_not_special.pop(0)
                            score5 = other_cards_not_special.pop(0)
                            score6 = other_cards_not_special.pop(0)
                            score7 = other_cards_not_special.pop(0)
                            score8 = other_cards_not_special.pop(0)
                        except IndexError:
                            pass
                three_of_a_kind_value = int
                other_cards_not_special = []
                three_of_a_kind_present = False
                for value_name, count in value_counter.items():
                    if count == 3:
                        three_of_a_kind_present = True
                        three_of_a_kind_value = value_name
                if three_of_a_kind_present:
                    for value in value_list:
                        if value != three_of_a_kind_value:
                            other_cards_not_special.append(value)
                    other_cards_not_special = list(reversed(sorted(other_cards_not_special)))
                    score1 = 3
                    score2 = three_of_a_kind_value
                    try:
                        score3 = other_cards_not_special.pop(0)
                        score4 = other_cards_not_special.pop(0)
                        score5 = other_cards_not_special.pop(0)
                        score6 = other_cards_not_special.pop(0)
                        score7 = other_cards_not_special.pop(0)
                        score8 = other_cards_not_special.pop(0)
                    except IndexError:
                        pass
                if sorted(value_list) == list(range(min(value_list), max(value_list) + 1)):
                    score1 = 4
                    score2 = max(value_list)
                if sorted(value_list) == [0, 1, 2, 3, 12]:
                    score1 = 4
                    score2 = 3
                if len(set(suit_list)) == 1:
                    score1 = 5
                    score2 = max(value_list)
                if three_of_a_kind_present and pair_present:
                    score1 = 6
                    score2 = three_of_a_kind_value
                    score3 = pair_value
                four_of_a_kind_value = int
                other_card_value = int
                four_of_a_kind = False
                for value_name, count in value_counter.items():
                    if count == 4:
                        four_of_a_kind_value = value_name
                        four_of_a_kind: True
                for value in value_list:
                    if value != four_of_a_kind_value:
                        other_card_value = value
                if four_of_a_kind:
                    score1 = 7
                    score2 = four_of_a_kind_value
                    score3 = other_card_value
                if sorted(value_list) == [0, 1, 2, 3, 12] and len(set(suit_list)) == 1:
                    score1 = 8
                    score2 = 3
                if sorted(value_list) == list(range(min(value_list), max(value_list) + 1)) and len(set(suit_list)) == 1:
                    score1 = 8
                    score2 = max(value_list)
                    if max(value_list) == 12:
                        score1 = 9
                list_of_all_score_possibilities.append([score1, score2, score3, score4, score5, score6, score7, score8])
            best_score = max(list_of_all_score_possibilities)
            player.score = best_score

        def score_all(self):
            for player in self.list_of_players_not_out:
                self.hand_scorer(player)

        def find_winners(self):
            if self.fold_out:
                for player in list(set(self.winners)):
                    player.chips += int((self.pot / len(list(set(self.winners)))))
                    print(f"{player.name} wins {int((self.pot / len(list(set(self.winners)))))} chips!")
            else:
                list_of_stakes = []
                for player in self.list_of_players_not_out:
                    list_of_stakes.append(player.stake)
                list_of_stakes = list(set(list_of_stakes))
                list_of_stakes = sorted(list_of_stakes)
                for stake in list_of_stakes:
                    print(stake)
                for player in self.list_of_players_not_out:
                    print(player.name)
                    print(player.stake)
                print(self.list_of_players_not_out)
                list_of_players_at_stake = []
                list_of_list_of_players_at_stake = []
                for i in range(len(list_of_stakes)):
                    for player in self.list_of_players_not_out:
                        if player.stake >= list_of_stakes[i]:
                            list_of_players_at_stake.append(player)
                    list_of_list_of_players_at_stake.append(list(set(list_of_players_at_stake)))
                    list_of_players_at_stake.clear()
                print(list_of_list_of_players_at_stake)
                list_of_pot_seeds = []
                for i in list_of_stakes:
                    list_of_pot_seeds.append(i)
                list_of_pot_seeds.reverse()
                for i in range(len(list_of_pot_seeds)):
                    try:
                        list_of_pot_seeds[i] -= list_of_pot_seeds[i + 1]
                    except IndexError:
                        pass
                list_of_pot_seeds.reverse()
                list_of_pots = []
                for i in range(len(list_of_pot_seeds)):
                    print(len(list_of_list_of_players_at_stake[i]))
                for i in range(len(list_of_pot_seeds)):
                    list_of_pots.append(list_of_pot_seeds[i] * len(list_of_list_of_players_at_stake[i]))
                for i in range(len(list_of_pots)):
                    winners = []
                    self.list_of_scores_eligible.clear()
                    for player in list_of_list_of_players_at_stake[i]:
                        if player.fold:
                            pass
                        else:
                            self.list_of_scores_eligible.append(player.score)
                    max_score = max(self.list_of_scores_eligible)
                    for player in list_of_list_of_players_at_stake[i]:
                        if player.fold:
                            pass
                        else:
                            if player.score == max_score:
                                player.win = True
                                winners.append(player)
                    prize = int(list_of_pots[i] / len(winners))
                    for player in winners:
                        print(f"{player.name} wins {prize} chips!")
                        player.chips += prize
                        self.pot -= prize
                for player in self.list_of_players_not_out:
                    if player.win:
                        print(
                            "\n" + player.name + ": " + str(
                                player.cards) + "\t<-WINNER WINNER WINNER WINNER WINNER WINNER "
                                                "WINNER WINNER" + "\n\t" + score_interpreter(player))
                    elif player.fold:
                        print("\n" + player.name + ": " + str(player.cards) + "\n\t" + "[FOLDED]")
                    else:
                        print("\n" + player.name + ": " + str(player.cards) + "\n\t" + score_interpreter(player))
                    print(f"\tScoreCode: {player.score}")
                    print(f"Pot: {self.pot}")
                [print(player.name, player.chips) for player in self.list_of_players_not_out]

        def clear_board(self):
            self.possible_responses.clear()
            self.cards.clear()
            self.deck = StandardDeck()
            self.deck.shuffle()
            self.pot = 0
            self.pot_dict.clear()
            self.winners.clear()
            self.list_of_scores_from_eligible_winners.clear()
            self.action_counter = 0
            self.highest_stake = 0
            self.fold_list.clear()
            self.not_fold_list.clear()
            self.fold_out = False
            self.list_of_scores_eligible.clear()
            self.round_ended = False
            for player in self.list_of_players:
                player.score.clear()
                player.cards.clear()
                player.stake = 0
                player.stake_gap = 0
                player.ready = False
                player.all_in = False
                player.fold = False
                player.list_of_special_attributes.clear()
                player.win = False

        def end_round(self):
            self.list_of_players_not_out = list(set(self.list_of_players_not_out))
            for player in self.list_of_players_not_out:
                if player.chips <= 0:
                    self.list_of_players_not_out.remove(player)
                    print(f"{player.name} is out of the game!")
            self.number_of_player_not_out = len(set(self.list_of_players_not_out))
            if self.number_of_player_not_out == 1:
                self.game_over = True
                self.winner = self.list_of_players_not_out[0]
                print(f"Game is over: {self.winner} wins with {self.winner.chips}!")
                quit()
            new_round = str(ask_app("Start a new round? (yes/no)"))
            if new_round == "yes":
                print("\n\n\t\t\t\t--ROUND OVER--")
                print("\n\n\t\t\t--STARTING NEW ROUND--\n")
                self.round_counter += 1
                pass
            else:
                quit()
            time.sleep(0.3)
            self.clear_board()

        def answer(self, player):
            player.stake_gap = self.highest_stake - player.stake
            if player.all_in or player.fold or self.fold_out:
                return True
            if player.chips <= 0:
                print(f"{player.name} is all in!")
                player.all_in = True
            print(f"Highest stake: {self.highest_stake}")
            print(f"Put in at least {player.stake_gap} to stay in.\nDon't Have that much? You'll have to go all-in!")
            print(f"Chips available: {player.chips}")
            self.possible_responses.clear()
            if player.stake_gap > 0:
                self.possible_responses.append("fold")
                if player.stake_gap == player.chips:
                    self.possible_responses.append("all_in_exact")
                if player.stake_gap > player.chips:
                    self.possible_responses.append("all_in_partial")
                if player.stake_gap < player.chips:
                    self.possible_responses.append("call_exact")
                    self.possible_responses.append("call_and_raise")
                    self.possible_responses.append("call_and_all_in")
            if player.stake_gap == 0:
                self.possible_responses.append("check")
                self.possible_responses.append("raise")
                self.possible_responses.append("fold")
                self.possible_responses.append("all_in")
            while True:
                print(self.possible_responses)
                response = str(ask_app(f"{player}'s action\n->", self))
                if response not in self.possible_responses:
                    print("Invalid response")
                    continue
                if response == "all_in_partial":
                    player.stake += player.chips
                    self.pot += player.chips
                    player.stake_gap -= player.chips
                    player.chips = 0
                    print(f"{player.name} is all-in!")
                    player.all_in = True
                    return True
                if response == "all_in_exact":
                    print(f"{player.name} is all-in!")
                    player.all_in = True
                    player.stake += player.stake_gap
                    self.pot += player.stake_gap
                    player.chips = 0
                    player.stake_gap = 0
                    return True
                if response == "fold":
                    player.fold = True
                    self.fold_list.append(player)
                    if len(self.fold_list) == (len(self.list_of_players_not_out) - 1):
                        for player in self.list_of_players_not_out:
                            if player not in self.fold_list:
                                self.fold_out = True
                                print(f"{player} wins!")
                                self.winners.append(player)
                                for player in self.winners:
                                    player.win = True
                                self.round_ended = True
                    return True
                if response == "call_exact":
                    player.stake += player.stake_gap
                    self.pot += player.stake_gap
                    player.chips -= player.stake_gap
                    player.stake_gap = 0
                    return True
                if response == "check":
                    player.stake_gap = 0
                    return True
                if response == "raise":
                    self.need_raise_info = True
                    while True:
                        bet = int(
                            ask_app(f"How much would {player.name} like to raise? ({player.chips} available)\n->",
                                    self))
                        if bet > player.chips or bet <= 0:
                            print("Invalid response")
                            continue
                        if bet == player.chips:
                            print(f"{player.name} is all-in!")
                            player.all_in = True
                        self.need_raise_info = False
                        player.stake += bet
                        self.pot += bet
                        player.chips -= bet
                        self.highest_stake = player.stake
                        self.ready_list.clear()
                        player.stake_gap = 0
                        return True
                if response == "call_and_raise":
                    self.need_raise_info = True
                    player.stake += player.stake_gap
                    self.pot += player.stake_gap
                    player.chips -= player.stake_gap
                    player.stake_gap = 0
                    while True:
                        try:
                            bet = int(
                                ask_app(f"How much would {player.name} like to raise? ({player.chips} available)\n->",
                                        self))
                        except ValueError:
                            continue
                        if bet > player.chips or bet <= 0:
                            print("Invalid response")
                            continue
                        if bet == player.chips:
                            print(f"{player.name} is all-in!")
                            player.all_in = True
                        self.need_raise_info = False
                        player.stake += bet
                        self.pot += bet
                        player.chips -= bet
                        self.highest_stake = player.stake
                        self.ready_list.clear()
                        return True
                if response == "call_and_all_in":
                    player.stake += player.stake_gap
                    self.pot += player.stake_gap
                    player.chips -= player.stake_gap
                    player.stake_gap = 0
                    player.stake += player.chips
                    self.pot += player.chips
                    player.stake_gap -= player.chips
                    player.chips = 0
                    print(f"{player.name} is all-in!")
                    player.all_in = True
                    self.highest_stake = player.stake
                    self.ready_list.clear()
                    return True
                if response == "all_in":
                    player.stake_gap = 0
                    player.stake += player.chips
                    self.pot += player.chips
                    player.chips = 0
                    print(f"{player.name} is all-in!")
                    player.all_in = True
                    self.highest_stake = player.stake
                    self.ready_list.clear()
                    return True
                print("Invalid Response")

        def ask_players(self):
            self.ready_list.clear()
            starting_index = self.list_of_players_not_out.index(self.first_actor)
            for player in self.list_of_players_not_out:
                player.ready = False
            while True:
                self.acting_player = self.list_of_players_not_out[starting_index]
                player_ready = self.answer(self.list_of_players_not_out[starting_index])
                starting_index += 1
                starting_index %= len(self.list_of_players_not_out)
                if player_ready:
                    self.ready_list.append("gogo")
                if len(self.ready_list) == len(self.list_of_players_not_out):
                    break

        def act_one(self):
            if self.small_blind_amount > self.small_blind.chips:
                self.small_blind.stake += self.small_blind.chips
                self.highest_stake = self.small_blind.chips
                self.pot += self.small_blind.chips
                self.small_blind.chips = 0
                print(f"{self.small_blind.name} is all-in!")
                self.small_blind.all_in = True
            else:
                self.small_blind.chips -= self.small_blind_amount
                self.small_blind.stake += self.small_blind_amount
                self.highest_stake = self.small_blind_amount
                self.pot += self.small_blind_amount
            if self.big_blind_amount > self.big_blind.chips:
                self.big_blind.stake += self.big_blind.chips
                self.highest_stake = self.big_blind.chips
                self.pot += self.big_blind.chips
                self.big_blind.chips = 0
                print(f"{self.big_blind} is all-in!")
                self.big_blind.all_in = True
            else:
                self.big_blind.chips -= self.big_blind_amount
                self.big_blind.stake += self.big_blind_amount
                self.highest_stake = self.big_blind_amount
                self.pot += self.big_blind_amount
            self.ask_players()

    class App(Tk):
        def __init__(self, *args, **kwargs):
            Tk.__init__(self, *args, **kwargs)
            self.game_object = object

            container = Frame(self)
            container.pack(side="top", fill="both", expand=True)
            container.grid_rowconfigure(0, weight=1)
            container.grid_columnconfigure(0, weight=1)

            self.frames = {}

            list_of_frames = [StartPage, GamePage]

            for F in list_of_frames:
                frame = F(container, self)
                self.frames[F] = frame
                frame.grid(row=0, column=0, sticky="nsew")

            self.fresh = True
            self.show_frame(StartPage)

        def show_frame(self, context):
            frame = self.frames[context]
            print("waiting")
            if not self.fresh:
                time.sleep(0.1)
                frame.update(game_info_q.get())
            self.fresh = False
            frame.tkraise()

    class StartPage(Frame):
        def __init__(self, parent, controller):
            Frame.__init__(self, parent)

            height = 500
            width = 800
            canvas = Canvas(self, height=height, width=width, bg="light green")
            canvas.pack()

            left_frame = Frame(canvas, bg='green', bd=5)
            left_frame.place(relx=0, rely=0, relwidth=0.5, relheight=1, anchor='nw')
            name_frame = Frame(left_frame, bg="light green", bd=5)
            name_frame.place(relx=0.5, rely=0.17, relwidth=0.9, relheight=0.7, anchor="n")
            self.entry_p0 = Entry(name_frame, font=("Courier", 12), bd=3)
            self.entry_p0.place(relwidth=0.5, relheight=0.2)
            self.entry_p1 = Entry(name_frame, font=("Courier", 12), bd=3)
            self.entry_p1.place(relx=0.5, rely=0, relwidth=0.5, relheight=0.2)
            self.entry_p2 = Entry(name_frame, font=("Courier", 12), bd=3)
            self.entry_p2.place(relx=0, rely=0.2, relwidth=0.5, relheight=0.2)
            self.entry_p3 = Entry(name_frame, font=("Courier", 12), bd=3)
            self.entry_p3.place(relx=0.5, rely=0.2, relwidth=0.5, relheight=0.2)
            self.entry_p4 = Entry(name_frame, font=("Courier", 12), bd=3)
            self.entry_p4.place(relx=0, rely=0.4, relwidth=0.5, relheight=0.2)
            self.entry_p5 = Entry(name_frame, font=("Courier", 12), bd=3)
            self.entry_p5.place(relx=0.5, rely=0.4, relwidth=0.5, relheight=0.2)
            self.entry_p6 = Entry(name_frame, font=("Courier", 12), bd=3)
            self.entry_p6.place(relx=0, rely=0.6, relwidth=0.5, relheight=0.2)
            self.entry_p7 = Entry(name_frame, font=("Courier", 12), bd=3)
            self.entry_p7.place(relx=0.5, rely=0.6, relwidth=0.5, relheight=0.2)
            self.entry_p8 = Entry(name_frame, font=("Courier", 12), bd=3)
            self.entry_p8.place(relx=0, rely=0.8, relwidth=0.5, relheight=0.2)
            self.entry_p9 = Entry(name_frame, font=("Courier", 12), bd=3)
            self.entry_p9.place(relx=0.5, rely=0.8, relwidth=0.5, relheight=0.2)
            enter_player_label = Label(left_frame, text="Player Names:", font=("Courier", 12), bd=3)
            enter_player_label.place(relx=0.25, rely=0.07, relwidth=0.5, relheight=0.05)
            # self.entry.bind("<Return>", lambda _: self.button_click(self.entry.get()))

            right_frame = Frame(canvas, bg='green', bd=5)
            right_frame.place(relx=1, rely=0, relwidth=0.5, relheight=1, anchor='ne')
            self.sc_label = Label(right_frame, text="Starting Chips:", font=("Courier", 12), bd=3)
            self.sc_label.place(relx=0.25, rely=0.1, relwidth=0.5, relheight=0.05)
            self.sc_entry = Entry(right_frame, font=("Courier"), bd=3)
            self.sc_entry.place(relx=0.5, rely=0.17, relwidth=0.5, relheight=0.07, anchor="n")

            self.sb_label = Label(right_frame, text="Small-Blind Chips:", font=("Courier", 12), bd=3)
            self.sb_label.place(relx=0.25, rely=0.33, relwidth=0.5, relheight=0.05)
            self.sb_entry = Entry(right_frame, font=("Courier"), bd=3)
            self.sb_entry.place(relx=0.5, rely=0.4, relwidth=0.5, relheight=0.07, anchor="n")

            self.bb_label = Label(right_frame, text="Big-Blind Chips:", font=("Courier", 12), bd=3)
            self.bb_label.place(relx=0.25, rely=0.56, relwidth=0.5, relheight=0.05)
            self.bb_entry = Entry(right_frame, font=("Courier"), bd=3)
            self.bb_entry.place(relx=0.5, rely=0.63, relwidth=0.5, relheight=0.07, anchor="n")
            self.bb_entry.bind("<Return>", lambda _: self.button_click(self.entry_p0.get(), self.entry_p1.get(),
                                                                       self.entry_p2.get(), self.entry_p3.get(),
                                                                       self.entry_p4.get(), self.entry_p5.get(),
                                                                       self.entry_p6.get(),
                                                                       self.entry_p7.get(), self.entry_p8.get(),
                                                                       self.entry_p9.get(), self.sc_entry.get(),
                                                                       self.sb_entry.get(), self.bb_entry.get(),
                                                                       controller))

            button = Button(right_frame, text="START", font=("Courier", 12),
                            command=lambda: self.button_click(self.entry_p0.get(), self.entry_p1.get(),
                                                              self.entry_p2.get(), self.entry_p3.get(),
                                                              self.entry_p4.get(), self.entry_p5.get(),
                                                              self.entry_p6.get(),
                                                              self.entry_p7.get(), self.entry_p8.get(),
                                                              self.entry_p9.get(), self.sc_entry.get(),
                                                              self.sb_entry.get(), self.bb_entry.get(), controller))
            button.place(relx=0.5, rely=0.9, relwidth=0.3, relheight=0.1, anchor="n")

        def button_click(self, entry0, entry1, entry2, entry3, entry4, entry5, entry6, entry7, entry8, entry9, entrysc,
                         entrysb, entrybb, controller):
            entry_list = [entry0, entry1, entry2, entry3, entry4, entry5, entry6, entry7, entry8, entry9, entrysc,
                          entrysb, entrybb]
            player_entry_list = [entry0, entry1, entry2, entry3, entry4, entry5, entry6, entry7, entry8, entry9]
            print(player_entry_list)
            player_entry_list = list(set(player_entry_list))
            for player in player_entry_list:
                if player == "":
                    player_entry_list.remove(player)
            print(player_entry_list)
            if len(player_entry_list) < 2:
                print("not enough players")
                return
            chip_entry_list = [entrysc, entrysb, entrybb]
            for chips in chip_entry_list:
                try:
                    chips = int(chips)
                except ValueError:
                    print("Value Error")
                    return
                if chips == "" or chips <= 0:
                    print("chip entry error")
                    return
            if not int(entrysc) > int(entrybb) > int(entrysb):
                print("chip entry error2 ")
                return
            setup = {
                "players": player_entry_list,
                "chips": chip_entry_list
            }
            response_q.put(setup)
            game_event.set()
            controller.show_frame(GamePage)

    class GamePage(Frame):
        def __init__(self, parent, controller):
            Frame.__init__(self, parent)

            self.restart = False
            self.responses = []
            self.list_of_button_r = []
            height = 500
            width = 800
            canvas = Canvas(self, height=height, width=width, bg="light green")
            canvas.pack()

            left_frame = Frame(canvas, bg='green', bd=5)
            left_frame.place(relx=0, rely=0, relwidth=0.5, relheight=1, anchor='nw')
            name_frame = Frame(left_frame, bg="light green", bd=5)
            name_frame.place(relx=0.5, rely=0, relwidth=1, relheight=1, anchor="n")

            self.frame_p0 = Frame(name_frame, bd=3, relief="groove")
            self.frame_p0.place(relwidth=0.5, relheight=0.2)
            self.name_label_p0 = Label(self.frame_p0, font=("Courier", 10), bd=3)
            self.name_label_p0.place(relx=0, rely=0, relheight=(1 / 3), relwidth=0.38)
            self.chips_label_p0 = Label(self.frame_p0, font=("Courier", 10), bd=3)
            self.chips_label_p0.place(relx=0, rely=(1 / 3), relheight=(1 / 3), relwidth=0.38)
            self.cards_frame_p0 = Frame(self.frame_p0, bd=3, relief="groove")
            self.cards_frame_p0.place(relx=0.38, relheight=1, relwidth=0.62)
            self.card1_p0 = Label(self.cards_frame_p0)
            self.card1_p0.place(relwidth=0.5, relheight=1)
            self.card2_p0 = Label(self.cards_frame_p0)
            self.card2_p0.place(relx=0.5, relwidth=0.5, relheight=1)
            self.stake_label_p0 = Label(self.frame_p0, bd=1, relief="groove")
            self.stake_label_p0.place(relx=0, rely=(2 / 3), relheight=(1 / 3), relwidth=0.38)

            self.frame_p1 = Frame(name_frame, bd=3, relief="groove")
            self.frame_p1.place(relx=0.5, rely=0, relwidth=0.5, relheight=0.2)
            self.name_label_p1 = Label(self.frame_p1, font=("Courier", 10), bd=3)
            self.name_label_p1.place(relx=0, rely=0, relheight=(1 / 3), relwidth=0.38)
            self.chips_label_p1 = Label(self.frame_p1, font=("Courier", 10), bd=3)
            self.chips_label_p1.place(relx=0, rely=(1 / 3), relheight=(1 / 3), relwidth=0.38)
            self.cards_frame_p1 = Frame(self.frame_p1, bd=3, relief="groove")
            self.cards_frame_p1.place(relx=0.38, relheight=1, relwidth=0.62)
            self.card1_p1 = Label(self.cards_frame_p1)
            self.card1_p1.place(relwidth=0.5, relheight=1)
            self.card2_p1 = Label(self.cards_frame_p1)
            self.card2_p1.place(relx=0.5, relwidth=0.5, relheight=1)
            self.stake_label_p1 = Label(self.frame_p1, bd=1, relief="groove")
            self.stake_label_p1.place(relx=0, rely=(2 / 3), relheight=(1 / 3), relwidth=0.38)

            self.frame_p2 = Frame(name_frame, bd=3, relief="groove")
            self.frame_p2.place(relx=0, rely=0.2, relwidth=0.5, relheight=0.2)
            self.name_label_p2 = Label(self.frame_p2, font=("Courier", 10), bd=3)
            self.name_label_p2.place(relx=0, rely=0, relheight=(1 / 3), relwidth=0.38)
            self.chips_label_p2 = Label(self.frame_p2, font=("Courier", 10), bd=3)
            self.chips_label_p2.place(relx=0, rely=(1 / 3), relheight=(1 / 3), relwidth=0.38)
            self.cards_frame_p2 = Frame(self.frame_p2, bd=3, relief="groove")
            self.cards_frame_p2.place(relx=0.38, relheight=1, relwidth=0.62)
            self.card1_p2 = Label(self.cards_frame_p2)
            self.card1_p2.place(relwidth=0.5, relheight=1)
            self.card2_p2 = Label(self.cards_frame_p2)
            self.card2_p2.place(relx=0.5, relwidth=0.5, relheight=1)
            self.stake_label_p2 = Label(self.frame_p2, bd=1, relief="groove")
            self.stake_label_p2.place(relx=0, rely=(2 / 3), relheight=(1 / 3), relwidth=0.38)

            self.frame_p3 = Frame(name_frame, bd=3, relief="groove")
            self.frame_p3.place(relx=0.5, rely=0.2, relwidth=0.5, relheight=0.2)
            self.name_label_p3 = Label(self.frame_p3, font=("Courier", 10), bd=3)
            self.name_label_p3.place(relx=0, rely=0, relheight=(1 / 3), relwidth=0.38)
            self.chips_label_p3 = Label(self.frame_p3, font=("Courier", 10), bd=3)
            self.chips_label_p3.place(relx=0, rely=(1 / 3), relheight=(1 / 3), relwidth=0.38)
            self.cards_frame_p3 = Frame(self.frame_p3, bd=3, relief="groove")
            self.cards_frame_p3.place(relx=0.38, relheight=1, relwidth=0.62)
            self.card1_p3 = Label(self.cards_frame_p3)
            self.card1_p3.place(relwidth=0.5, relheight=1)
            self.card2_p3 = Label(self.cards_frame_p3)
            self.card2_p3.place(relx=0.5, relwidth=0.5, relheight=1)
            self.stake_label_p3 = Label(self.frame_p3, bd=1, relief="groove")
            self.stake_label_p3.place(relx=0, rely=(2 / 3), relheight=(1 / 3), relwidth=0.38)

            self.frame_p4 = Frame(name_frame, bd=3, relief="groove")
            self.frame_p4.place(relx=0, rely=0.4, relwidth=0.5, relheight=0.2)
            self.name_label_p4 = Label(self.frame_p4, font=("Courier", 10), bd=3)
            self.name_label_p4.place(relx=0, rely=0, relheight=(1 / 3), relwidth=0.38)
            self.chips_label_p4 = Label(self.frame_p4, font=("Courier", 10), bd=3)
            self.chips_label_p4.place(relx=0, rely=(1 / 3), relheight=(1 / 3), relwidth=0.38)
            self.cards_frame_p4 = Frame(self.frame_p4, bd=3, relief="groove")
            self.cards_frame_p4.place(relx=0.38, relheight=1, relwidth=0.62)
            self.card1_p4 = Label(self.cards_frame_p4)
            self.card1_p4.place(relwidth=0.5, relheight=1)
            self.card2_p4 = Label(self.cards_frame_p4)
            self.card2_p4.place(relx=0.5, relwidth=0.5, relheight=1)
            self.stake_label_p4 = Label(self.frame_p4, bd=1, relief="groove")
            self.stake_label_p4.place(relx=0, rely=(2 / 3), relheight=(1 / 3), relwidth=0.38)

            self.frame_p5 = Frame(name_frame, bd=3, relief="groove")
            self.frame_p5.place(relx=0.5, rely=0.4, relwidth=0.5, relheight=0.2)
            self.name_label_p5 = Label(self.frame_p5, font=("Courier", 10), bd=3)
            self.name_label_p5.place(relx=0, rely=0, relheight=(1 / 3), relwidth=0.38)
            self.chips_label_p5 = Label(self.frame_p5, font=("Courier", 10), bd=3)
            self.chips_label_p5.place(relx=0, rely=(1 / 3), relheight=(1 / 3), relwidth=0.38)
            self.cards_frame_p5 = Frame(self.frame_p5, bd=3, relief="groove")
            self.cards_frame_p5.place(relx=0.38, relheight=1, relwidth=0.62)
            self.card1_p5 = Label(self.cards_frame_p5)
            self.card1_p5.place(relwidth=0.5, relheight=1)
            self.card2_p5 = Label(self.cards_frame_p5)
            self.card2_p5.place(relx=0.5, relwidth=0.5, relheight=1)
            self.stake_label_p5 = Label(self.frame_p5, bd=1, relief="groove")
            self.stake_label_p5.place(relx=0, rely=(2 / 3), relheight=(1 / 3), relwidth=0.38)

            self.frame_p6 = Frame(name_frame, bd=3, relief="groove")
            self.frame_p6.place(relx=0, rely=0.6, relwidth=0.5, relheight=0.2)
            self.name_label_p6 = Label(self.frame_p6, font=("Courier", 10), bd=3)
            self.name_label_p6.place(relx=0, rely=0, relheight=(1 / 3), relwidth=0.38)
            self.chips_label_p6 = Label(self.frame_p6, font=("Courier", 10), bd=3)
            self.chips_label_p6.place(relx=0, rely=(1 / 3), relheight=(1 / 3), relwidth=0.38)
            self.cards_frame_p6 = Frame(self.frame_p6, bd=3, relief="groove")
            self.cards_frame_p6.place(relx=0.38, relheight=1, relwidth=0.62)
            self.card1_p6 = Label(self.cards_frame_p6)
            self.card1_p6.place(relwidth=0.5, relheight=1)
            self.card2_p6 = Label(self.cards_frame_p6)
            self.card2_p6.place(relx=0.5, relwidth=0.5, relheight=1)
            self.stake_label_p6 = Label(self.frame_p6, bd=1, relief="groove")
            self.stake_label_p6.place(relx=0, rely=(2 / 3), relheight=(1 / 3), relwidth=0.38)

            self.frame_p7 = Frame(name_frame, bd=3, relief="groove")
            self.frame_p7.place(relx=0.5, rely=0.6, relwidth=0.5, relheight=0.2)
            self.name_label_p7 = Label(self.frame_p7, font=("Courier", 10), bd=3)
            self.name_label_p7.place(relx=0, rely=0, relheight=(1 / 3), relwidth=0.38)
            self.chips_label_p7 = Label(self.frame_p7, font=("Courier", 10), bd=3)
            self.chips_label_p7.place(relx=0, rely=(1 / 3), relheight=(1 / 3), relwidth=0.38)
            self.cards_frame_p7 = Frame(self.frame_p7, bd=3, relief="groove")
            self.cards_frame_p7.place(relx=0.38, relheight=1, relwidth=0.62)
            self.card1_p7 = Label(self.cards_frame_p7)
            self.card1_p7.place(relwidth=0.5, relheight=1)
            self.card2_p7 = Label(self.cards_frame_p7)
            self.card2_p7.place(relx=0.5, relwidth=0.5, relheight=1)
            self.stake_label_p7 = Label(self.frame_p7, bd=1, relief="groove")
            self.stake_label_p7.place(relx=0, rely=(2 / 3), relheight=(1 / 3), relwidth=0.38)

            self.frame_p8 = Frame(name_frame, bd=3, relief="groove")
            self.frame_p8.place(relx=0, rely=0.8, relwidth=0.5, relheight=0.2)
            self.name_label_p8 = Label(self.frame_p8, font=("Courier", 10), bd=3)
            self.name_label_p8.place(relx=0, rely=0, relheight=(1 / 3), relwidth=0.38)
            self.chips_label_p8 = Label(self.frame_p8, font=("Courier", 10), bd=3)
            self.chips_label_p8.place(relx=0, rely=(1 / 3), relheight=(1 / 3), relwidth=0.38)
            self.cards_frame_p8 = Frame(self.frame_p8, bd=3, relief="groove")
            self.cards_frame_p8.place(relx=0.38, relheight=1, relwidth=0.62)
            self.card1_p8 = Label(self.cards_frame_p8)
            self.card1_p8.place(relwidth=0.5, relheight=1)
            self.card2_p8 = Label(self.cards_frame_p8)
            self.card2_p8.place(relx=0.5, relwidth=0.5, relheight=1)
            self.stake_label_p8 = Label(self.frame_p8, bd=1, relief="groove")
            self.stake_label_p8.place(relx=0, rely=(2 / 3), relheight=(1 / 3), relwidth=0.38)

            self.frame_p9 = Frame(name_frame, bd=3, relief="groove")
            self.frame_p9.place(relx=0.5, rely=0.8, relwidth=0.5, relheight=0.2)
            self.name_label_p9 = Label(self.frame_p9, font=("Courier", 10), bd=3)
            self.name_label_p9.place(relx=0, rely=0, relheight=(1 / 3), relwidth=0.38)
            self.chips_label_p9 = Label(self.frame_p9, font=("Courier", 10), bd=3)
            self.chips_label_p9.place(relx=0, rely=(1 / 3), relheight=(1 / 3), relwidth=0.38)
            self.cards_frame_p9 = Frame(self.frame_p9, bd=3, relief="groove")
            self.cards_frame_p9.place(relx=0.38, relheight=1, relwidth=0.62)
            self.card1_p9 = Label(self.cards_frame_p9)
            self.card1_p9.place(relwidth=0.5, relheight=1)
            self.card2_p9 = Label(self.cards_frame_p9)
            self.card2_p9.place(relx=0.5, relwidth=0.5, relheight=1)
            self.stake_label_p9 = Label(self.frame_p9, bd=1, relief="groove")
            self.stake_label_p9.place(relx=0, rely=(2 / 3), relheight=(1 / 3), relwidth=0.38)

            # self.entry.bind("<Return>", lambda _: self.button_click(self.entry.get()))

            right_frame = Frame(canvas, bg='green', bd=5)
            right_frame.place(relx=1, rely=0, relwidth=0.5, relheight=1, anchor='ne')

            self.cc_frame = Frame(right_frame, bd=2, relief="raised")
            self.cc_frame.place(relx=0, rely=0, relwidth=1, relheight=0.2)

            self.cc_1 = Label(self.cc_frame, bg="green")
            self.cc_1.place(relwidth=(.50 / 3), relheight=1)
            card_d1 = ImageTk.PhotoImage(
                Image.open("cards\default0.png").resize((55, 85), Image.ANTIALIAS))
            self.cc_1.image = card_d1
            self.cc_1.configure(image=card_d1)

            self.cc_2 = Label(self.cc_frame, bg="green")
            self.cc_2.place(relx=(.50 / 3), relwidth=(.50 / 3), relheight=1)
            card_d2 = ImageTk.PhotoImage(
                Image.open("cards\default1.png").resize((55, 85), Image.ANTIALIAS))
            self.cc_2.image = card_d2
            self.cc_2.configure(image=card_d2)

            self.cc_3 = Label(self.cc_frame, bg="green")
            self.cc_3.place(relx=(.50 / 3) * 2, relwidth=(.50 / 3), relheight=1)
            card_d3 = ImageTk.PhotoImage(
                Image.open("cards\default1.png").resize((55, 85), Image.ANTIALIAS))
            self.cc_3.image = card_d3
            self.cc_3.configure(image=card_d3)

            self.cc_4 = Label(self.cc_frame, bg="green")
            self.cc_4.place(relx=(.50 / 3) * 3, relwidth=0.25, relheight=1)
            card_d4 = ImageTk.PhotoImage(
                Image.open("cards\default1.png").resize((55, 85), Image.ANTIALIAS))
            self.cc_4.image = card_d4
            self.cc_4.configure(image=card_d4)

            self.cc_5 = Label(self.cc_frame, bg="green")
            self.cc_5.place(relx=((.50 / 3) * 3) + 0.25, relwidth=0.25, relheight=1)
            card_d5 = ImageTk.PhotoImage(
                Image.open("cards\default1.png").resize((55, 85), Image.ANTIALIAS))
            self.cc_5.image = card_d5
            self.cc_5.configure(image=card_d5)

            self.pot_label = Label(right_frame, text="pot: ", font=("Courier", 12), bd=3)
            self.pot_label.place(relx=0, rely=0.2, relwidth=0.5, relheight=0.04)

            # self.dealer_label = Label(right_frame, text="dealer: ", font=("Courier", 12), bd=3)
            # self.dealer_label.place(relx=0, rely=0.28, relwidth=0.5, relheight=0.04)

            # self.sb_label = Label(right_frame, text="small-blind: ", font=("Courier", 12), bd=3)
            # self.sb_label.place(relx=0, rely=0.33, relwidth=0.5, relheight=0.04)

            # self.bb_label = Label(right_frame, text="big-blind: ", font=("Courier", 12), bd=3)
            # self.bb_label.place(relx=0, rely=0.38, relwidth=0.5, relheight=0.04)

            self.action_frame = Frame(right_frame, bd=2, relief="raised", bg="green")
            self.action_frame.place(rely=0.5, relwidth=1, relheight=0.5)
            self.action_cover_label = Label(self.action_frame, bg="light green")
            self.action_cover_label.place(relx=0, rely=0, relheight=1, relwidth=1)

            self.actor_label = Label(self.action_frame, text="Actor: ", font=("Courier", 12), bd=3)
            self.actor_label.place(relwidth=1, relheight=0.06)

            self.new_round_label = Label(self.action_frame, text="New Round?", font=("Courier", 9), bd=3)
            self.new_round_label.place(relx=0.8, rely=0.05, relheight=0.1, relwidth=0.2)
            self.button_y = Button(self.action_frame, text="Yes", command=lambda: self.action_input("yes"))
            self.button_y.place(relx=0.8, rely=0.15, relheight=0.1, relwidth=0.2)
            self.button_n = Button(self.action_frame, text="No", command=lambda: self.action_input("no"))
            self.button_n.place(relx=0.8, rely=0.25, relheight=0.1, relwidth=0.2)

            self.raise_entry = Entry(self.action_frame, font=("Courier", 9), bd=3)
            self.raise_entry.place(relx=0, rely=1, relheight=0.12, relwidth=0.22, anchor="sw")
            self.raise_button = Button(self.action_frame, text="RAISE", font=("Courier", 9), bd=3, command=lambda: self.action_input(self.raise_entry.get()))
            self.raise_button.place(relx=0.22, rely=1, relheight=0.12, relwidth=0.22, anchor="sw")

            self.winner_label = Label(self.action_frame, font=("Courier", 12), bd=3)
            self.winner_label.place(relx=0, rely=(1/3), relwidth=0.75, relheight=0.3)

        def update(self, game):
            self.new_round_label.lower(self.action_cover_label)
            self.button_y.lower(self.action_cover_label)
            self.button_n.lower(self.action_cover_label)
            self.raise_entry.lower(self.action_cover_label)
            self.raise_button.lower(self.action_cover_label)
            self.winner_label.lower(self.action_cover_label)
            if self.restart:
                card1 = ImageTk.PhotoImage(Image.open(str("cards\default0.png")).resize((55, 85), Image.ANTIALIAS))
                self.cc_1.image = card1
                self.cc_1.configure(image=card1)

                card1 = ImageTk.PhotoImage(Image.open(str("cards\default0.png")).resize((55, 85), Image.ANTIALIAS))
                self.cc_2.image = card1
                self.cc_2.configure(image=card1)

                card1 = ImageTk.PhotoImage(Image.open(str("cards\default0.png")).resize((55, 85), Image.ANTIALIAS))
                self.cc_3.image = card1
                self.cc_3.configure(image=card1)

                card1 = ImageTk.PhotoImage(Image.open(str("cards\default0.png")).resize((55, 85), Image.ANTIALIAS))
                self.cc_4.image = card1
                self.cc_4.configure(image=card1)

                card1 = ImageTk.PhotoImage(Image.open(str("cards\default0.png")).resize((55, 85), Image.ANTIALIAS))
                self.cc_5.image = card1
                self.cc_5.configure(image=card1)
                self.restart = False
            if game.round_ended:
                time.sleep(0.3)
                self.new_round_label.lift(self.action_cover_label)
                self.button_y.lift(self.action_cover_label)
                self.button_n.lift(self.action_cover_label)
                winners = []
                scores = []
                for player in game.list_of_players_not_out:
                    if player.win:
                        winners.append(player)
                        scores.append(player.score)
                print(f"gui thinks winners are: {winners}")
                print(f"and thinks scores are: {scores}")
                if scores == [[]]:
                    self.winner_label["text"] = "Winner: " + str(winners)
                else:
                    try:
                        for player in game.list_of_players_not_out:
                            if player.win:
                                if player.score == max(scores):
                                    self.winner_label["text"] = "Winner: " + str(winners) + "\n" + score_interpreter(player)
                    except IndexError:
                        pass
                self.winner_label.lift(self.action_cover_label)

                self.restart = True

                return
            if game.need_raise_info:
                self.raise_entry.lift(self.action_cover_label)
                self.raise_button.lift(self.action_cover_label)
            try:
                card1 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.cards[0]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.cc_1.image = card1
                self.cc_1.configure(image=card1)

                card1 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.cards[1]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.cc_2.image = card1
                self.cc_2.configure(image=card1)

                card1 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.cards[2]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.cc_3.image = card1
                self.cc_3.configure(image=card1)

                card1 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.cards[3]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.cc_4.image = card1
                self.cc_4.configure(image=card1)

                card1 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.cards[4]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.cc_5.image = card1
                self.cc_5.configure(image=card1)
            except IndexError:
                pass
            try:
                self.name_label_p0["text"] = game.list_of_players[0]
                self.name_label_p1["text"] = game.list_of_players[1]
                self.name_label_p2["text"] = game.list_of_players[2]
                self.name_label_p3["text"] = game.list_of_players[3]
                self.name_label_p4["text"] = game.list_of_players[4]
                self.name_label_p5["text"] = game.list_of_players[5]
                self.name_label_p6["text"] = game.list_of_players[6]
                self.name_label_p7["text"] = game.list_of_players[7]
                self.name_label_p8["text"] = game.list_of_players[8]
                self.name_label_p9["text"] = game.list_of_players[9]
            except IndexError:
                pass
            try:
                self.chips_label_p0["text"] = "Chips:\n" + str(game.list_of_players[0].chips)
                self.chips_label_p1["text"] = "Chips:\n" + str(game.list_of_players[1].chips)
                self.chips_label_p2["text"] = "Chips:\n" + str(game.list_of_players[2].chips)
                self.chips_label_p3["text"] = "Chips:\n" + str(game.list_of_players[3].chips)
                self.chips_label_p4["text"] = "Chips:\n" + str(game.list_of_players[4].chips)
                self.chips_label_p5["text"] = "Chips:\n" + str(game.list_of_players[5].chips)
                self.chips_label_p6["text"] = "Chips:\n" + str(game.list_of_players[6].chips)
                self.chips_label_p7["text"] = "Chips:\n" + str(game.list_of_players[7].chips)
                self.chips_label_p8["text"] = "Chips:\n" + str(game.list_of_players[8].chips)
                self.chips_label_p9["text"] = "Chips:\n" + str(game.list_of_players[9].chips)
            except IndexError:
                pass
            try:
                card1 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.list_of_players[0].cards[0]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.card1_p0.image = card1
                self.card1_p0.configure(image=card1)

                card1 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.list_of_players[1].cards[0]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.card1_p1.image = card1
                self.card1_p1.configure(image=card1)

                card1 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.list_of_players[2].cards[0]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.card1_p2.image = card1
                self.card1_p2.configure(image=card1)

                card1 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.list_of_players[3].cards[0]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.card1_p3.image = card1
                self.card1_p3.configure(image=card1)

                card1 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.list_of_players[4].cards[0]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.card1_p4.image = card1
                self.card1_p4.configure(image=card1)

                card1 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.list_of_players[5].cards[0]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.card1_p5.image = card1
                self.card1_p5.configure(image=card1)

                card1 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.list_of_players[6].cards[0]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.card1_p6.image = card1
                self.card1_p6.configure(image=card1)

                card1 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.list_of_players[7].cards[0]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.card1_p7.image = card1
                self.card1_p7.configure(image=card1)

                card1 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.list_of_players[8].cards[0]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.card1_p8.image = card1
                self.card1_p8.configure(image=card1)

                card1 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.list_of_players[9].cards[0]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.card1_p9.image = card1
                self.card1_p9.configure(image=card1)
            except IndexError:
                pass
            try:
                card2 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.list_of_players[0].cards[1]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.card2_p0.image = card2
                self.card2_p0.configure(image=card2)

                card2 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.list_of_players[1].cards[1]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.card2_p1.image = card2
                self.card2_p1.configure(image=card2)

                card2 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.list_of_players[2].cards[1]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.card2_p2.image = card2
                self.card2_p2.configure(image=card2)

                card2 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.list_of_players[3].cards[1]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.card2_p3.image = card2
                self.card2_p3.configure(image=card2)

                card2 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.list_of_players[4].cards[1]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.card2_p4.image = card2
                self.card2_p4.configure(image=card2)

                card2 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.list_of_players[5].cards[1]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.card2_p5.image = card2
                self.card2_p5.configure(image=card2)

                card2 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.list_of_players[6].cards[1]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.card2_p6.image = card2
                self.card2_p6.configure(image=card2)

                card2 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.list_of_players[7].cards[1]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.card2_p7.image = card2
                self.card2_p7.configure(image=card2)

                card2 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.list_of_players[8].cards[1]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.card2_p8.image = card2
                self.card2_p8.configure(image=card2)

                card2 = ImageTk.PhotoImage(
                    Image.open("cards\\" + str(game.list_of_players[9].cards[1]) + ".png").resize((55, 85), Image.ANTIALIAS))
                self.card2_p9.image = card2
                self.card2_p9.configure(image=card2)
            except IndexError:
                pass
            try:
                self.stake_label_p0["text"] = "Stake: " + str(game.list_of_players[0].stake)
                self.stake_label_p1["text"] = "Stake: " + str(game.list_of_players[1].stake)
                self.stake_label_p2["text"] = "Stake: " + str(game.list_of_players[2].stake)
                self.stake_label_p3["text"] = "Stake: " + str(game.list_of_players[3].stake)
                self.stake_label_p4["text"] = "Stake: " + str(game.list_of_players[4].stake)
                self.stake_label_p5["text"] = "Stake: " + str(game.list_of_players[5].stake)
                self.stake_label_p6["text"] = "Stake: " + str(game.list_of_players[6].stake)
                self.stake_label_p7["text"] = "Stake: " + str(game.list_of_players[7].stake)
                self.stake_label_p8["text"] = "Stake: " + str(game.list_of_players[8].stake)
                self.stake_label_p9["text"] = "Stake: " + str(game.list_of_players[9].stake)
            except IndexError:
                pass
            self.pot_label["text"] = "Pot: " + str(game.pot)
            if game.game_over:
                self.actor_label["text"] = "Winner!: " + str(game.winner.name)
                return
            print(f"round ended {game.round_ended}")

            self.actor_label["text"] = str(game.acting_player.name)

            variable = StringVar(self.action_frame)
            variable.initialize("ACTION")
            w = OptionMenu(self.action_frame, variable, *game.possible_responses)
            w.place(relx=0, rely=0.05, relheight=0.1, relwidth=0.3)
            button_go = Button(self.action_frame, text="GO", font=("Courier", 10), command=lambda: self.action_input(variable.get()))
            button_go.place(relx=1, rely=1, relheight=0.3, relwidth=0.3, anchor="se")

        def action_input(self, entry0):

            response_q.put(entry0)
            game_event.set()
            time.sleep(0.1)
            if not game_info_q.empty():
                self.update(game_info_q.get())

    def score_interpreter(player):
        list_of_hand_types = ["High Card", "One Pair", "Two Pair", "Three of a Kind", "Straight", "Flush",
                              "Full House",
                              "Four of a Kind", "Straight Flush", "Royal Flush"]
        list_of_values_to_interpret = ["Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten",
                                       "Jack",
                                       "Queen",
                                       "King", "Ace"]
        hand_type = list_of_hand_types[player.score[0]]
        mod1 = list_of_values_to_interpret[player.score[1]]
        mod2 = list_of_values_to_interpret[player.score[2]]
        mod3 = list_of_values_to_interpret[player.score[3]]
        if player.score[0] == 0:
            return hand_type + ": " + mod3
        if player.score[0] == 1:
            return hand_type + ": " + mod1 + "s"
        if player.score[0] == 2:
            return hand_type + ": " + mod1 + "s" + " and " + mod2 + "s"
        if player.score[0] == 3:
            return hand_type + ": " + mod1 + "s"
        if player.score[0] == 4:
            return hand_type + ": " + mod1 + " High"
        if player.score[0] == 5:
            return hand_type + ": " + mod1 + " High"
        if player.score[0] == 6:
            return hand_type + ": " + mod1 + "s" + " and " + mod2 + "s"
        if player.score[0] == 7:
            return hand_type + ": " + mod1 + "s"
        if player.score[0] == 8:
            return hand_type + ": " + mod1 + " High"
        if player.score[0] == 9:
            return hand_type

    def ask_app(question, game=""):
        print("asking...")
        print(question)
        answer = ""
        if game != "":
            game_info_q.put(game)
        game_event.wait()
        if not response_q.empty():
            answer = response_q.get()
        game_event.clear()

        return answer

    def update_gui(game1):
        print("updating gui...")
        print(game1)

    def play(game):
        game.deck.shuffle()
        game_info_q.put(game)
        update_gui(game)
        game.establish_player_attributes()
        game.deal_hole()
        game.print_round_info()
        game.act_one()
        game.print_round_info()
        if not game.round_ended:
            game.deal_flop()
            game.print_round_info()
        if not game.round_ended:
            game.ask_players()
            game.print_round_info()
        if not game.round_ended:
            game.deal_turn()
            game.print_round_info()
        if not game.round_ended:
            game.ask_players()
            game.print_round_info()
        if not game.round_ended:
            game.deal_river()
            game.print_round_info()
        if not game.round_ended:
            game.ask_players()
            game.print_round_info()
        if not game.round_ended:
            game.score_all()
            game.print_round_info()
        game.find_winners()
        game_info_q.put(game)

        game.print_round_info()
        game.round_ended = True
        print(game.winners, game.winner, [player for player in game.list_of_players_not_out if player.win])
        game.end_round()

    def run_app():
        app = App()
        app.mainloop()

    def run_game_data():
        game0 = Game()
        while True:
            play(game0)

    game_event = threading.Event()
    response_q = queue.Queue()
    game_info_q = queue.Queue()
    end_update = threading.Event()
    t1 = threading.Thread(target=run_app)
    t1.start()
    t2 = threading.Thread(target=run_game_data())
    t2.start()

if __name__ == "__main__":
    main()


# code to train world coord regression from RGB Image
# models are saved in checkpoints-wc/

import sys, os
from turtle import forward
import torch
import visdom
import argparse
import numpy as np
import torch.nn as nn
import torch.nn.init as init
import torch.nn.functional as F
import time
import torchvision.models as models
from tensorboardX import SummaryWriter

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

from torch.autograd import Variable
from torch.utils import data
from torchvision import utils
from tqdm import tqdm

from models import get_model
from loaders import get_loader
from utils import show_wc_tnsboard,  get_lr

def write_log_file(log_file_name,losses, epoch, lrate, phase):
    with open(log_file_name,'a') as f:
        f.write("\n{} LRate: {} Epoch: {} Loss: {} MSE: {}".format(phase, lrate, epoch, losses[0], losses[1]))

def train(args):

    # Setup Dataloader
    data_loader = get_loader('doc3dboundary')
    data_path = args.data_path
    t_loader = data_loader(data_path, is_transform=True, img_size=(args.img_rows, args.img_cols), augmentations=True)
    v_loader = data_loader(data_path, is_transform=True, split='val', img_size=(args.img_rows, args.img_cols))

    n_classes = t_loader.n_classes
    trainloader = data.DataLoader(t_loader, batch_size=args.batch_size, num_workers=8, shuffle=True)
    valloader = data.DataLoader(v_loader, batch_size=args.batch_size, num_workers=8)

    # Setup Model
    model = get_model(args.arch, n_classes,in_channels=3) #Get the U-Net architecture
    model = torch.nn.DataParallel(model, device_ids=range(torch.cuda.device_count()))
    model.cuda()

    # Activation
    activation=nn.Sigmoid()

    # Optimizer
    optimizer= torch.optim.Adam(model.parameters(),lr=args.l_rate, weight_decay=5e-4, amsgrad=True)

    # LR Scheduler, which can reduce the learning rate as time passing by
    sched=torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.5, patience=5, verbose=True)

    # Losses
    MSE = nn.MSELoss() #L2 Loss for measure the training loss and validation loss
    loss_fn = nn.BCELoss() # BCE Loss used throughout the whole training process, including L_C, L_D, L_T (Both in the first and second training phase)
    #gloss= grad_loss.Gradloss(window_size=5,padding=2) #The Gradient Loss used in L_C, i.e. deltaChead-deltaC

    epoch_start=0
    if args.resume is not None:
        if os.path.isfile(args.resume):# Loading model and optimizer from the checkpoint
            print("Loading model and optimizer from checkpoint '{}'".format(args.resume))
            checkpoint = torch.load(args.resume)
            model.load_state_dict(checkpoint['model_state'])
            #optimizer.load_state_dict(checkpoint['optimizer_state'])
            print("Loaded checkpoint '{}' (epoch {})"
                  .format(args.resume, checkpoint['epoch']))
            epoch_start=checkpoint['epoch']
        else:
            print("No checkpoint found at '{}'".format(args.resume))

    #Log file:
    if not os.path.exists(args.logdir):
        os.makedirs(args.logdir)
    experiment_name='boundary' #activation_dataset_lossparams_augmentations_trainstart
    log_file_name=os.path.join(args.logdir,experiment_name+'.txt')
    if os.path.isfile(log_file_name):
        log_file=open(log_file_name,'a')
    else:
        log_file=open(log_file_name,'w+')

    log_file.write('\n---------------  '+experiment_name+'  ---------------\n')
    log_file.close()

    # Setup tensorboard for visualization
    if args.tboard:
        # save logs in runs/<experiment_name>
        writer = SummaryWriter(comment=experiment_name)

    best_val_loss = 99999.0
    global_step=0
    print(get_lr(optimizer))

    for epoch in range(epoch_start,args.n_epoch):
        avg_loss=0.0
        avg_l1loss=0.0
        #avg_gloss=0.0
        train_mse=0.0
        model.train() # Tell the model we're training

        for i, (images, labels) in enumerate(trainloader):
            images = Variable(images.cuda())
            labels = Variable(labels.cuda())

            optimizer.zero_grad()
            outputs = model(images)
            pred=activation(outputs) #Activation Function
            #g_loss=gloss(pred, labels) # The Gradient Loss between the Ground Truth 3D representation and the pedicted one
            l1loss = loss_fn(pred, labels) # The BCE Loss between the above two
            loss=l1loss#i.e. the L_C loss, actually I uncomment this to make this consistent with the paper, originally the latter part is commented, which I don't know the reason now.
            avg_l1loss+=float(l1loss)
            #avg_gloss+=float(g_loss)
            avg_loss+=float(loss)
            train_mse+=float(MSE(pred, labels).item())

            loss.backward()
            optimizer.step()
            global_step+=1

            if (i+1) % 50 == 0:
                print("Epoch[%d/%d] Batch [%d/%d] Loss: %.4f" % (epoch+1,args.n_epoch,i+1, len(trainloader), avg_loss/50.0))
                avg_loss=0.0

            if args.tboard and  (i+1) % 20 == 0:
                #show_wc_tnsboard(global_step, writer,images,labels,pred, 8,'Train Inputs', 'Train Boundarys', 'Train Pred. Boundarys')
                writer.add_scalar('Boundary: BCE Loss/train', avg_l1loss/(i+1), global_step)
                #writer.add_scalar('Boundary: Grad Loss/train', avg_gloss/(i+1), global_step)

        train_mse=train_mse/len(trainloader)
        avg_l1loss=avg_l1loss/len(trainloader)
        #avg_gloss=avg_gloss/len(trainloader)
        print("Training BCE:%4f" %(avg_l1loss))
        print("Training MSE:'{}'".format(train_mse))
        train_losses=[avg_l1loss, train_mse]

        lrate=get_lr(optimizer)
        write_log_file(experiment_name, train_losses, epoch+1, lrate,'Train')

        model.eval() # Tell the model we're evaluating
        val_loss=0.0
        val_mse=0.0
        val_bg=0.0
        val_fg=0.0
        val_gloss=0.0
        val_dloss=0.0
        for i_val, (images_val, labels_val) in tqdm(enumerate(valloader)): #use progress bar
            with torch.no_grad():
                images_val = Variable(images_val.cuda())
                labels_val = Variable(labels_val.cuda())

                outputs = model(images_val)
                pred_val=activation(outputs)
                #g_loss=gloss(pred_val, labels_val).cpu()
                pred_val=pred_val.cpu()
                labels_val=labels_val.cpu()
                loss = loss_fn(pred_val, labels_val)
                val_loss+=float(loss)
                val_mse+=float(MSE(pred_val, labels_val))
                #val_gloss+=float(g_loss)

        if args.tboard:
            #show_wc_tnsboard(epoch+1, writer,images_val,labels_val,pred, 8,'Val Inputs', 'Val Boundarys', 'Val Pred. Boundarys')
            writer.add_scalar('Boundary: BCE Loss/val', val_loss, epoch+1)
            #writer.add_scalar('Boundary: Grad Loss/val', val_gloss, epoch+1)

        val_loss=val_loss/len(valloader)
        val_mse=val_mse/len(valloader)
        val_gloss=val_gloss/len(valloader)
        print("val loss at epoch {}:: {}".format(epoch+1,val_loss))
        print("val MSE: {}".format(val_mse))

        val_losses=[val_loss, val_mse]
        write_log_file(experiment_name, val_losses, epoch+1, lrate, 'Val')

        #reduce learning rate
        sched.step(val_loss)

        if val_loss < best_val_loss:
            best_val_loss=val_loss
            state = {'epoch': epoch+1,
                     'model_state': model.state_dict(),
                     'optimizer_state' : optimizer.state_dict(),}
            torch.save(state, args.logdir+"{}_{}_{}_{}_{}_best_model.pkl".format(args.arch, epoch+1,val_mse,train_mse,experiment_name))

        if (epoch+1) % 10 == 0:
            state = {'epoch': epoch+1,
                     'model_state': model.state_dict(),
                     'optimizer_state' : optimizer.state_dict(),}
            torch.save(state, args.logdir+"{}_{}_{}_{}_{}_model.pkl".format(args.arch, epoch+1,val_mse,train_mse,experiment_name))
        time.sleep(0.003)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Hyperparams')
    parser.add_argument('--arch', nargs='?', type=str, default='dnetccnl',
                        help='Architecture to use [\'dnetccnl, unetnc\']')
    parser.add_argument('--data_path', nargs='?', type=str, default='',
                        help='Data path to load data')
    parser.add_argument('--img_rows', nargs='?', type=int, default=256,
                        help='Height of the input image')
    parser.add_argument('--img_cols', nargs='?', type=int, default=256,
                        help='Width of the input image')
    parser.add_argument('--n_epoch', nargs='?', type=int, default=200,
                        help='# of the epochs')
    parser.add_argument('--batch_size', nargs='?', type=int, default=200,
                        help='Batch Size')
    parser.add_argument('--l_rate', nargs='?', type=float, default=1e-5,
                        help='Learning Rate')
    parser.add_argument('--resume', nargs='?', type=str, default=None,
                        help='Path to previous saved model to restart from')
    parser.add_argument('--logdir', nargs='?', type=str, default='./checkpoints-squeezeboundary/',
                        help='Path to store the loss logs')
    parser.add_argument('--tboard', dest='tboard', action='store_true',
                        help='Enable visualization(s) on tensorboard | False by default')
    parser.set_defaults(tboard=True)

    args = parser.parse_args()
    train(args)

# CUDA_VISIBLE_DEVICES=0,1,2 python trainboundary.py --arch squeezeunet --data_path /disk2/sinan/doc3d/ --batch_size 200 --tboard --resume /home/sinan/DewarpNet-master/checkpoints-squeezeboundary/squeezeunet_150_0.007575992671772838_0.006176567144506083_boundary_model.pkl


from flask import Flask, render_template

import sqlite3  # needed to make database connections and queries

# dunder name (double underscore)
app = Flask(__name__)

# route -list
@app.route("/") #trailing slash
def home():
    return render_template("home.html")

@app.route("/contact")
def contact():
    return render_template("contact.html")

@app.route("/about")
def about():
    return render_template("about.html")

@app.route("/all_plants")
def all_plants():
   conn = sqlite3.connect('plants.db')
   cur = conn.cursor()
   cur.execute("SELECT * FROM plant")
   results = cur.fetchall()
   print(results)
   return render_template("all_plants.html", results = results)

@app.route('/plant/<int:id>')
def plant(id):
    conn = sqlite3.connect("plants.db")
    cur = conn.cursor()
    cur.execute("SELECT * FROM plant WHERE id = ?",(id,))
    plant = cur.fetchone()
    cur.execute("SELECT intro FROM plant WHERE id = plant[4]",(id,))
    base = cur.fetchone()
    cur.execute("SELECT name FROM plant WHERE id IN(SELECT id FROM category WHERE id = ?)",(id,))
    category = cur.fetchone()
    return render_template ("all_plants.html", plant = plant, base = base, category = category)

#must be at bottom
if __name__ == "__main__": # run app from file directly
    app.run(debug= True) #remove debug at end


import argparse,ipfspinsteem.strings as s
from ipfspinsteem.ipfspinsteem2 import Steem,Parser,IPFS
import ipfshttpclient

parser = argparse.ArgumentParser(description='Extracts IPFS Hashes to Dtube/Dsound, creates an IPFS Object and pins it to an IPFS node.')
parser.add_argument('url', type=str, nargs='+',help='Dtube Video-Url. Example: account/permlink')
parser.add_argument('--api', dest='api', default='/ip4/127.0.0.1/tcp/5001/http',help='IPFS API IP. Default:/ip4/127.0.0.1/tcp/5001/http')
parser.add_argument('--exclude', dest='exclude', nargs='+',help='Exclude something. Example: videohash')
parser.add_argument('--object', dest='object',action='store_true',help='Will wrap all hashes to a single IPFS Object.')
parser.add_argument('--no-pin', dest='nopin',action='store_true',help='Will not pin anything to IPFS')
parser.add_argument('--quiet', dest='quiet',action='store_true',help='Will only print hash(es) and nothing else when successfully finnished.')
args=parser.parse_args()

def main():
	'''
	Connect to IPFS and Steem api.
	'''
	ipfs=IPFS(args.api)
	steem=Steem(steemd_nodes=None)
	'''
	Get user and permlinks from url argument.
	'''
	try:
		parser=Parser()
		info = parser.parseURL(urls=args.url)
	except ValueError:
		print("Invalid URL. Aborted")
		exit(0)
	'''
	Get IPFS hashes from Steem by content(user and permlink)
	'''
	try:
		hashes=steem.getHashesByContentList(info)
	except SyntaxError:
		print("SyntaxError. Probablly unavailable user and/or permlink. Aborted")
		exit(0)
	except KeyboardInterrupt:
		print("Interrupted by user")
	if hashes is None:
		print('No hashes found')
		exit(0)
	'''
	Remove invalid stuff
	'''
	opts={s.donotadd:args.exclude}
	hashes=Steem.removeInvalid(hashes,opts)
	'''
	Link all Hashes to a new IPFS Object or just add Hashes to list without creating object
	'''
	#print(ipfs.parseHash("QmbWPdc526RQxMVijVNQEyvz6s1Mh5hT3r4CZ4xhUh6xZk","QmbWPdc526RQxMVijVNQEyvz6s1Mh5hT3r4CZ4xhUh6xZk"))
	#objopts={s.donotadd:args.exclude}#Object creation options
	liste=[]
	for h in hashes:
		for e in h[s.permlinks]:
			for q in e:
				for p in q[s.links]:
					if args.quiet == False:
						print('extracted',h[s.user],'/',q[s.permlink],'/',p[s.Name],'/',p[s.Hash])
					if args.object == False:
						liste.append(p[s.Hash])
						#ipfs.pin(p[s.Hash])
						#print('pinned',p[s.Hash],'recursively')
	if args.object == True:
		try:
			obj=ipfs.createNewSingleObject(hashes),
		except KeyboardInterrupt:
			print('interrupted by user')
			exit(0)
		#obj=obj[0]
		liste.append(obj[0])
		if args.quiet == False:
			print('created object',obj[0])
	#obj=obj[0]

	#if args.quiet==False:

	'''
	Pin List "liste" to IPFS Node
	'''
	if args.nopin==False:
		try:
			ipfs.pin(liste)
			if args.quiet==False:
				for i in liste:
					print('pinned',i,'recursively')
			else:
				for i in liste:
					print(i)
		except ipfshttpclient.exceptions.DecodingError as e:
			print('pinning failed')
			print(e)
		except KeyboardInterrupt:
			print('Pinning Interrupted by user')
	elif args.object == True:
		if args.quiet== True:
			print(liste[0])


import io
import os
import pyaudio
import google.cloud.speech
import sys
import RPi.GPIO as GPIO
import time
import threading
import asyncio
import websockets
import json

# 초음파 센서 세팅
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
TRIG = 17
ECHO = 18
GPIO.setup(TRIG, GPIO.OUT)
GPIO.setup(ECHO, GPIO.IN)

# Audio recording parameters
RATE = 16000
CHUNK = int(RATE / 10)  # 100ms

uw = 0
#exit_flag = False  # 종료 여부를 확인하기 위한 플래그
exit_flag=threading.Event()
send_msg=""
serial_num=1111

class Stack:
    def __init__(self):
        self.items = []

    def is_empty(self):
        return len(self.items) == 0

    def push(self, item):
        self.items.append(item)

    def pop(self):
        if not self.is_empty():
            return self.items.pop()
        else:
            print("Stack is empty. Cannot pop.")

    def peek(self):
        if not self.is_empty():
            return self.items[-1]
        else:
            print("Stack is empty. Nothing to peek.")

    def size(self):
        return len(self.items)

    def clear(self):
        self.items = []

stack=Stack()

def stream_generator(stream):
    while True:
        data = stream.read(CHUNK)
        yield data

def send_and_receive_message(send_msg):
    uri = "ws://i9c103.p.ssafy.io:30002/"
    websocket=websockets.connect(uri)

    print("msg sending")
    websocket.send(json.dumps({"role":"handshake", "number":1111}))
    data = {"role": "gpt","message": send_msg, "number": 1111}
    websocket.send(json.dumps(data))

    # Receive and immediately print the response
    response = websocket.recv()
    print(f"Received: {response}")

def listen_print_loop(responses):
    send_msg=""
    stack.push("test string")
    num_chars_printed = 0
    for response in responses:
        #print(stack.pop())

        if not response.results:
            continue

        result = response.results[0]
        if not result.alternatives:
            continue

        transcript = result.alternatives[0].transcript

        overwrite_chars = ' ' * (num_chars_printed - len(transcript))

        if not result.is_final:
            stack.push(transcript + overwrite_chars)
            # stt와 sense모두 돌아가야함
            # sense가 가까워 지는경우 전역에 저장해 준뒤 보내줌
            # sense와의 연동
            # exit_flag true인 경우
            # string으로 보내주기
            # stack clear
            if exit_flag.is_set():
                send_msg=stack.peek()
                print(send_msg)
        else:
            print("send message is ",send_msg,end=" ")
            print()
            send_msg=""
            stack.clear()

def stt():
    global uw, exit_flag
    client = google.cloud.speech.SpeechClient()

    config = google.cloud.speech.RecognitionConfig(
        encoding=google.cloud.speech.RecognitionConfig.AudioEncoding.LINEAR16,
        sample_rate_hertz=RATE,
        language_code='ko-KR',
        enable_automatic_punctuation=True,
        enable_spoken_punctuation=True,
        model='latest_long',
    )

    streaming_config = google.cloud.speech.StreamingRecognitionConfig(
        config=config,
        interim_results=True,
    )

    p = pyaudio.PyAudio()

    # 어떻게 넣을지
    Speaker_diarization_config=google.cloud.speech.SpeakerDiarizationConfig(
        min_speaker_count=1,
        max_speaker_count=1,
    )

    stream = p.open(
        format=pyaudio.paInt16,
        channels=1,
        rate=RATE,
        input=True,
        frames_per_buffer=CHUNK,
    )

    audio_generator = stream_generator(stream)
    requests = (
        google.cloud.speech.StreamingRecognizeRequest(audio_content=content)
        for content in audio_generator
    )

    responses = client.streaming_recognize(streaming_config, requests)

    listen_print_loop(responses)

def sense():
    global uw, exit_flag
    while True:
        GPIO.output(17, False)
        time.sleep(0.5)

        GPIO.output(17, True)
        time.sleep(0.00001)
        GPIO.output(17, False)

        while GPIO.input(18) == 0:
            start = time.time()

        while GPIO.input(18) == 1:
            stop = time.time()

        time_interval = stop - start
        uw = time_interval * 17000
        uw = round(uw, 2)
        print(uw,end=" ")

        # 먼 경우
        if uw > 100:
            # thread가 존재 할때 종료 3. 멀어졌을때 종료하고 초기화
            print("remote")
            exit_flag.set()
        # 가까운 경우
        else:
            # thread가 미존재시 생성 2.스레드 생성해 입력 받기
            print("close")
            exit_flag.clear()

def main():

        global send_msg
        thread_stt = threading.Thread(target=stt)
        thread_sense = threading.Thread(target=sense)

        thread_stt.start()
        thread_sense.start()

        try:
            while True:
                '''
                if exit_flag.is_set():
                    thread_msg=threading.Thread(target=send_and_receive_message,args=(send_msg,))
                    thread_msg.start()
                    send_msg=""
                    thread_msg.join()'''
                time.sleep(1)

        except KeyboardInterrupt:
            GPIO.cleanup()
            thread_sense.join()
            thread_stt.join()

if __name__ == '__main__':
    main()


import torch
import torch.nn as nn
import torch.nn.functional as F
import logging
logger = logging.getLogger("model.py")

device = 'cuda' if torch.cuda.is_available() else 'cpu'
print(f'Using {device} device')

class QRCode_CNN(nn.Module):
    def __init__(self, act_func=F.relu, drop=0.0):
        super(QRCode_CNN, self).__init__()
        self.drop = drop
        logger.info("drop layer setting: {}".format(drop))
        self.drop_layer = nn.Dropout2d(p=self.drop)
        self.conv1 = nn.Conv2d(in_channels=1, out_channels=12, kernel_size=5)
        self.pool = nn.MaxPool2d(2, 2)  #
        self.conv2 = nn.Conv2d(in_channels=12, out_channels=24, kernel_size=5)
        # fc1: 5*5 是要根據前剛的網路計算出來的
        # fc1: 根據論文是使用 300 個 neurons.
        self.fc1 = nn.Linear(24 * (32-4-4) * (32-4-4), 1000)
        # fc1: 根據論文是使用 2 個 neurons，直接皆輸出.
        self.fc1_5 = nn.Linear(1000, 300)
        self.fc2 = nn.Linear(300, 2)
        self.act = act_func

    def forward(self, x):
        x = x.view((-1, 1, 32, 32))
        x = self.act(self.conv1(x))
        x = self.drop_layer(x)  # self.pool(x)
        x = self.act(self.conv2(x))
        x = self.drop_layer(x)  # self.pool(x)
        x = torch.flatten(x, start_dim=1)
        x = self.act(self.fc1(x))
        x = self.act(self.fc1_5(x))
        x = self.fc2(x)
        # !!! pytorch 做分類問題時不用自己套 softmax，
        # 他會在 nn.CrossEntropyLoss 預設套用 LogSoftmax+NLLLoss。
        #
        return x

if __name__ == "__main__":
    net = QRCode_CNN()
    mini_batch = torch.randn((64, 1, 32, 32))
    pred_y = net(mini_batch)
    print(pred_y)
    print(pred_y.shape)


import os
import csv
import Upload
import Defines
import ProcessImage
from flask import Flask, render_template, request

app = Flask(__name__)
app.template_folder = os.path.join(app.instance_path, 'template')

ProcessImage.InitProcessImage(app.instance_path)
Upload.InitUpload(app.instance_path)

@app.route('/')
def home_page():
    return render_template('index.html')

@app.route('/search', methods=['GET', 'POST'])
def search():
    if request.method == 'POST':
        search_term = request.form['search']

        results = []
        with open(ProcessImage.CSV_File, "r+", encoding="utf-8") as csv_file:
            csv_reader = csv.reader(csv_file, delimiter=Defines.csv_delimiter)
            for row in csv_reader:
                for token in row:
                    if search_term in token:
                        file = row[0]
                        summery_path = os.path.splitext(file)[0] + ".summ"
                        with open(summery_path, "r+", encoding="utf-8") as f:
                            summery = "".join( f.readlines() )
                        results.append((file, summery))
                        break

        return render_template('search.html', results=results)
    else:
        return render_template('index.html')

@app.route('/upload', methods=['GET', 'POST'])
def upload():
    if request.method == 'POST':

        if 'file' not in request.files:
            return render_template('upload.html', lngs=Defines.lngs, msg='No file selected')

        filename = Upload.Upload( request.files['file'] )

        if filename == '':
            return render_template('upload.html', lngs=Defines.lngs, msg='No file selected')

        extracted_text, summary, threshold = ProcessImage.ProcessImage(filename, request.form['lng'])

        render_text = '\n'
        for sentence, value in summary:
            # Format to be displayed in js on client
            render_text += '[`' + sentence + '`,' + str(value) + '],\n'

        return render_template('upload.html',
                                lngs=Defines.lngs,
                                msg='Successfully processed',
                                threshold=threshold,
                                extracted_text=render_text,
                                img_src=filename)

    elif request.method == 'GET':
        return render_template('upload.html', lngs=Defines.lngs)

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