import random
import logging
from guizero import App, Text, TextBox, PushButton, Picture, Combo, info

logger = logging.getLogger(__name__)
logger.setLevel(level=logging.DEBUG)

class Card:
    """
    The Card class represents a single playing card and is initialised by passing a suit and number.
    """
    def __init__(self, suit,  number):
        self._suit =   suit
        self._number = number
        card_order_dict = {"2":2, "3":3, "4":4, "5":5, "6":6, "7":7, "8":8, "9":9, "10":10,"J":11, "Q":12, "K":13, "A":14}
        self._value =  card_order_dict.get(number)
        image_dict = {"hearts":"❤", "clubs":"♣", "diamonds":"♦", "spades":"♠"}
        self._image = image_dict.get(suit)

    def __repr__(self):
        # return self._number + " of " + self._suit + " (" + str(self._value) + ")"
        return "[" + self._number + self._image + "]"

    @property
    def suit(self):
        """ Gets or sets the suit of the Card """
        return self._suit

    @suit.setter
    def suit(self, suit):
        if suit in ["hearts", "clubs", "diamonds", "spades"]:
            self._suit = suit.upper()
        else:
            logger.error("Tried to set an invalid suit (" + str(suit) + ") for " + repr(self) )

    @property
    def number(self):
        """ Gets or sets the number of the Card """
        return self._number

    @number.setter
    def number(self, number):
        if number in ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]:
            self._number = number
        else:
            logger.error("Tried to set an invalid number (" + str(number) + ") for " + repr(self))

    @property
    def value(self):
        """ Gets or sets the value of the Card """
        return self._value

    @value.setter
    def value(self, value):
        if value in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]:
            self._value = value
        else:
            logger.error("Tried to set an invalid value (" + str(value) + ") for " + repr(self))

class Deck:
    """
    The Deck represents a deck of playing cards in order.
    """
    def __init__(self):
        self._cards = []
        self.populate()

    def populate(self):
        suits = ["hearts", "clubs", "diamonds", "spades"]
        #numbers = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]
        numbers = [str(n) for n in range(2,11)] + ["J", "Q", "K", "A"]
        self._cards = [ Card(s, n) for s in suits for n in numbers ]
        logger.info("Deck created (" + repr(self) + ")")

    def __repr__(self):
        c = len(self._cards)
        return "Deck of " + str(c) + " cards"

    def shuffler(self):
        """ This method shuffles the deck"""
        logger.info("Deck shuffled")
        random.shuffle(self._cards)

    @property
    def cards(self):
        """ Gets or sets the cards of the Deck """
        return self._cards

    # unfisnished - unsure how to do this. Does it even make sense to make a setter for this?
    @cards.setter
    def cards(self, cards):
        if 1 == 1 :
            self._cards = cards
        else:
            # ~ print("That's not an allowed deck")
            logger.error("Tried to set an invalid deck (" + str(cards) + ") for " + repr(self))

    def draw(self):
        """ Draws a card from the Deck """
        return self._cards.pop()

    def cfinder(self, card):
        """ Looks if a Card exist in the Deck """
        f = False
        for c in self._cards:
            if repr(c) == repr(card):
                logger.info("Card found in deck (" + str(card) + ")")
                f = True
        if f == False:
            logger.info("Card not found in deck (" + str(card) + ")")
        return f

class Player:
    """
    The Player represents a player with a name that can hold cards in their hand.
    """
    def __init__(self, name):
        self._name =   name
        self.p_activity = True
        self._hand =   []
        self._chips =  0
        self._bet =    0

    def __repr__(self):
        return str(self._name)

    def drawCard(self, deck):
        c = deck.draw()
        self._hand.append(c)
        logger.info("A player drew a card (" + str(c) + ")")
        return self

    # unfinished - Need to discard a specfic card instead of just the first one.
    def discard(self):
        c = self._hand.pop()
        logger.info("A player discarded a card (" + str(c) + ")")
        return c

    def show_hand(self):
        print("Your hand: " + str(self._hand))

class Game:
    """
    The Game represent the card game
    """
    def __init__(self, name):
        self.name = name
        self.g_state    = 0
        self.g_pool     = 0
        self.g_priority = 0
        self.g_round    = 0
        self.g_players  = []
        self.g_board    = []
        self.g_discard  = []
        self.g_deck     = []
        # self.p_slot1    = []
        # self.p_slot2    = []
        # self.p_slot3    = []
        # self.p_slot4    = []
        # self.p_slot5    = []
        # self.p_slot6    = []
        # self.app = App(title="Poker Game 2021", width=600, height=400, layout="grid")
        self.g_play_state = "Starting Game"
        self.main()

    def game_window(self):
        """ This makes the game window """

        player = self.g_players[self.g_priority]

        def gui_setup():
            game_state.value = "Gui Loaded"
            self.g_play_state = "Gui Setup Finished"

        def update_player():
            player = self.g_players[self.g_priority]

        def quit_game():
            exit()

        def play_game():
            play_game.disable()
            update_gui()
            gameloop()

        def update_game():
            logger.info("Updating Game") #remove later

        def get_player_names():
            return self.g_players

        def get_player1_info():
            info("Player 1 Info", "Info Stuff...")

        def get_player2_info():
            info("Player 2 Info", "Info Stuff...")

        def update_game_state():
            update_gui()
            show_game_info()
            update_game_info()

        def end_round():
            player = self.g_players[self.g_priority]
            bhp = self.find_winner(self.g_players)
            pc = len(bhp)
            # ~ bhv = self.best_hand(player)

            game_info_18.visible = True

            if pc == 1:
                game_result1.value = "[" + bhp[0]._name + "] won the pot (" + str(self.g_pool) + ")"
                bhp[0]._chips = bhp[0]._chips + self.g_pool
                self.g_pool = 0
                # self.player_cleanup(bhp[0])

            if len(bhp) == 2:
                game_result1.value = "[" + bhp[0]._name + "] splits the pot (" + str(self.g_pool) + ") with [" + bhp[1]._name + "]"
                bhp[0]._chips = bhp[0]._chips + self.g_pool/2
                bhp[1]._chips = bhp[1]._chips + self.g_pool/2
                self.g_pool = 0

            show_winning_hand(self.best_hand(player))

            for player in self.g_players:
                self.player_cleanup(player)

        def show_winning_hand(best_hand_value):
            if best_hand_value == 0:
                logger.error("Error: No winning hand was found.")
            if 1 <= best_hand_value < 2:
                game_result2.value = "Winning hand: High card"
            if 2 <= best_hand_value < 3:
                game_result2.value = "Winning hand: Pair"
            if 3 <= best_hand_value < 4:
                game_result2.value = "Winning hand: Two pair"
            if 4 <= best_hand_value < 5:
                game_result2.value = "Winning hand: Three of a kind"
            if 5 <= best_hand_value < 6:
                game_result2.value = "Winning hand: Straight"
            if 6 <= best_hand_value < 7:
                game_result2.value = "Winning hand: Flush"
            if 7 <= best_hand_value < 8:
                game_result2.value = "Winning hand: Full House"
            if 8 <= best_hand_value < 9:
                game_result2.value = "Winning hand: Four of a kind"
            if 9 <= best_hand_value < 10:
                game_result2.value = "Winning hand: Straight Flush"
            if 10 <= best_hand_value:
                game_result2.value = "Winning hand: Royal Straight Flush"

        def disable_g_buttons():
            call_bet.disable()
            raise_bet.disable()
            fold_bet.disable()

        def enable_g_buttons():
            call_bet.enable()
            raise_bet.enable()
            fold_bet.enable()

        def raise_bet():
            if int(input_bet.value) < 1:
                return
            raise_bet.disable()
            max_bet = player._chips
            if int(input_bet.value) > max_bet:
                self.bet(player, int(max_bet))
            else:
                self.bet(player, int(input_bet.value))
            input_bet.clear()
            game_signal == 1
            # ~ print("Raise")

            # ~ update_game_info()
            if 1 <= self.g_state <= 3:
                self.g_state += 1
                gameloop()
            elif self.g_state == 4:
                self.g_state += 1
                gameloop()
                disable_g_buttons()
                end_round()
                new_game.enable()

            if self.g_priority == 0:
                self.g_priority += 1
                self.computer_turn()

        def call_bet():
            call_bet.disable()
            self.call(player)
            game_signal == 1

            if 1 <= self.g_state <= 3:
                self.g_state += 1
                gameloop()
            elif self.g_state == 4:
                self.g_state += 1
                gameloop()
                disable_g_buttons()
                end_round()
                new_game.enable()

            if self.g_priority == 0:
                self.g_priority += 1
                self.computer_turn()

        def fold_bet():
            fold_bet.disable()
            # ~ print("Fold")
            self.fold(player)
            new_game.enable()

        def new_game():
            new_game.disable()
            purge_game_results()
            self.g_state == 1
            game_info_18.visible = False
            self.new_round()
            update_gui()
            gameloop()

        def purge_game_results():
            game_result1.value = ""
            game_result2.value = ""

        def update_gui():
            raise_bet.visible   = True
            call_bet.visible    = True
            fold_bet.visible    = True
            raise_bet.enable()
            call_bet.enable()
            fold_bet.enable()

        def show_g_buttons():
            raise_bet.visible   = True
            call_bet.visible    = True
            fold_bet.visible    = True

        def hide_g_buttons():
            raise_bet.visible   = False
            call_bet.visible    = False
            fold_bet.visible    = False

        def show_game_result():
            game_result1.visible = True
            game_result2.visible = True

        def hide_game_result():
            game_result1.visible = False
            game_result2.visible = False

        def show_h_cards():
            game_info_18.visible = True

        def hide_h_cards():
            game_info_18.visible = False

        def display_game_area():
            print("Displaying game area")

        def show_game_info():
            game_info_1.visible  = True
            game_info_2.visible  = True
            game_info_3.visible  = True
            game_info_4.visible  = True
            game_info_5.visible  = True
            game_info_6.visible  = True
            game_info_7.visible  = True
            game_info_8.visible  = True
            game_info_9.visible  = True
            game_info_10.visible = True
            game_info_11.visible = True
            game_info_12.visible = True
            game_info_13.visible = True
            game_info_14.visible = True
            game_info_15.visible = True
            game_info_16.visible = True
            game_info_17.visible = True
            # ~ game_info_18.visible = True
            game_info_19.visible = True
            game_info_20.visible = True

        def hide_game_info():
            game_info_1.visible  = False
            game_info_2.visible  = False
            game_info_3.visible  = False
            game_info_4.visible  = False
            game_info_5.visible  = False
            game_info_6.visible  = False
            game_info_7.visible  = False
            game_info_8.visible  = False
            game_info_9.visible  = False
            game_info_10.visible = False
            game_info_11.visible = False
            game_info_12.visible = False
            game_info_13.visible = False
            game_info_14.visible = False
            game_info_15.visible = False
            game_info_16.visible = False
            game_info_17.visible = False
            # ~ game_info_18.visible = False
            game_info_19.visible = False
            game_info_20.visible = False

        def update_game_info():
            game_info_5.value   = str(self.g_players[0]._chips)
            game_info_10.value  = str(self.g_players[1]._chips)
            game_info_12.value  = str(self.high_bet())
            game_info_14.value  = str(self.g_pool)
            game_info_16.value  = str(self.g_players[0]._hand)
            game_info_18.value  = str(self.g_players[1]._hand)
            game_info_20.value  = str(self.g_board)

        def gameloop():
            # ~ print("Game state: "+ str(self.g_state))
            if self.g_state == 1:
                game_state.value = "Starting Round 1"
                self.blinds()
                game_state.value = "Placing Blinds"
                self.deal1()
                game_state.value = "Dealing Hand Cards"
                if player._chips < 25:
                    raise_bet.disable()
                else:
                    raise_bet.enable()
            if self.g_state == 2:
                game_state.value = "The flop (3 Cards)"
                logger.info("Game state :" + str(self.g_state))
                self.deal2()
                if player._chips < 1:
                    raise_bet.disable()
                else:
                    raise_bet.enable()
            if self.g_state == 3:
                game_state.value = "The Turn (1 card)"
                logger.info("Game state :" + str(self.g_state))
                self.deal3()
                if player._chips < 1:
                    raise_bet.disable()
                else:
                    raise_bet.enable()
            if self.g_state == 4:
                game_state.value = "The River (1 card)"
                logger.info("Game state :" + str(self.g_state))
                self.deal4()
                if player._chips < 1:
                    raise_bet.disable()
                else:
                    raise_bet.enable()
            if self.g_state == 5:
                game_state.value = "End of Round"
                logger.info("Game state :" + str(self.g_state))
                logger.info("Round over")

            update_game_state()
            update_game_info()

        # ~ def player_turn():
            # ~ """ player betting round """
            # ~ player = self.g_players[self.g_priority]
            # ~ update_game_state()

            # ~ print("Player Turn Test:" + str(self.g_state))

        app = App(title="Poker Game 2021", width=1200, height=800, layout="grid")

        game_options        = Text(app, text="Game Options", grid=[1,1], size=14, font="Times New Roman", color="black", align="left")
        play_game           = PushButton(app, command=play_game, text="Play Game", grid=[1,2], align="left")
        new_game            = PushButton(app, command=new_game, text="New Game", grid=[1,3], align="left", visible=True, enabled=False)
        exit_game           = PushButton(app, command=quit_game, text="Quit Game", grid=[1,4], align="left")
        # ~ poker_pic           = Picture(app, image="Suit Icons.gif", grid=[2,1], align="left")
        player_description  = Text(app, text="Players:", grid=[1,5], size=14, font="Times New Roman", color="black", align="left")
        player1             = PushButton(app, command=get_player1_info, text="Player 1", grid=[1,6], align="left")
        player2             = PushButton(app, command=get_player2_info, text="Player 2", grid=[1,7], align="left")
        Gui_options         = Text(app, text="Gui Options:", grid=[1,8], size=14, font="Times New Roman", color="black", align="left")
        update              = PushButton(app, command=update_game_state, text="Update", grid=[1,9], align="left")
        # ~ column_seperator    = Text(app, text="|   ", grid=[2,1], size=14, font="Times New Roman", color="black", align="left")
        # ~ column_seperator2   = Text(app, text="|   ", grid=[2,2], size=14, font="Times New Roman", color="black", align="left")
        # ~ column_seperator2   = Text(app, text="|   ", grid=[2,3], size=14, font="Times New Roman", color="black", align="left")
        # ~ column_seperator2   = Text(app, text="|   ", grid=[2,4], size=14, font="Times New Roman", color="black", align="left")
        game_state          = Text(app, text="Active", grid=[7,2], size=14, font="Times New Roman", color="black", align="left", visible=False)
        input_bet           = TextBox(app, grid=[2,1])
        raise_bet           = PushButton(app, command=raise_bet, text="Bet", grid=[3,1], align="left", visible=False, enabled=False)
        call_bet            = PushButton(app, command=call_bet, text="Call", grid=[4,1], align="left", visible=False, enabled=False)
        fold_bet            = PushButton(app, command=fold_bet, text="Fold", grid=[5,1], align="left", visible=False, enabled=False)

        show_g_buttons      = PushButton(app, command=show_g_buttons, text="Show Game Buttons", grid=[1,9], align="left")
        hide_g_buttons      = PushButton(app, command=hide_g_buttons, text="Hide Game Buttons", grid=[1,10], align="left")
        show_gi             = PushButton(app, command=show_game_info, text="Show Game Info", grid=[1,11], align="left")
        hide_gi             = PushButton(app, command=hide_game_info, text="Hide Game Info", grid=[1,12], align="left")
        show_game_result    = PushButton(app, command=show_game_result, text="Show Game Results", grid=[1,13], align="left")
        hide_game_result    = PushButton(app, command=hide_game_result, text="Hide Game Results", grid=[1,14], align="left")
        show_h_cards        = PushButton(app, command=show_h_cards, text="Show Hand Cards", grid=[1,15], align="left")
        hide_h_cards        = PushButton(app, command=hide_h_cards, text="Hide Hand Cards", grid=[1,16], align="left")
        game_state_title    = Text(app, text="Game State:", grid=[1,20], size=14, font="Times New Roman", color="black", align="left")
        game_state          = Text(app, text="", grid=[1,21], size=14, font="Times New Roman", color="black", align="left")

        game_info_1         = Text(app, text="P1:", grid=[8,2], size=14, font="Times New Roman", color="black", align="left", visible=False)
        game_info_2         = Text(app, text=self.g_players[0]._name, grid=[9,2], size=14, font="Times New Roman", color="black", align="left", visible=False)
        game_info_3         = Text(app, text="     ", grid=[10,2], size=14, font="Times New Roman", color="black", align="left", visible=False)
        game_info_4         = Text(app, text="Chips: $", grid=[11,2], size=14, font="Times New Roman", color="black", align="right", visible=False)
        game_info_5         = Text(app, text=str(self.g_players[0]._chips), grid=[12,2], size=14, font="Times New Roman", color="black", align="left", visible=False)
        game_info_6         = Text(app, text="P2:", grid=[8,3], size=14, font="Times New Roman", color="black", align="left", visible=False)
        game_info_7         = Text(app, text=self.g_players[1]._name, grid=[9,3], size=14, font="Times New Roman", color="black", align="left", visible=False)
        game_info_8         = Text(app, text="     ", grid=[10,3], size=14, font="Times New Roman", color="black", align="left", visible=False)
        game_info_9         = Text(app, text="Chips: $", grid=[11,3], size=14, font="Times New Roman", color="black", align="right", visible=False)
        game_info_10        = Text(app, text=str(self.g_players[1]._chips), grid=[12,3], size=14, font="Times New Roman", color="black", align="left", visible=False)
        game_info_11        = Text(app, text="Highest bet: $", grid=[8,4], size=14, font="Times New Roman", color="black", align="left", visible=False)
        game_info_12        = Text(app, text=str(self.high_bet()), grid=[9,4], size=14, font="Times New Roman", color="black", align="left", visible=False)
        game_info_13        = Text(app, text="Pot: $", grid=[11,4], size=14, font="Times New Roman", color="black", align="right", visible=False)
        game_info_14        = Text(app, text=str(self.g_pool), grid=[12,4], size=14, font="Times New Roman", color="black", align="left", visible=False)
        game_info_15        = Text(app, text="Player 1 Hand cards:", grid=[8,5], size=14, font="Times New Roman", color="black", align="left", visible=False)
        game_info_16        = Text(app, text="", grid=[9,5], size=14, font="Times New Roman", color="black", align="left", visible=False)
        game_info_17        = Text(app, text="Player 2 Hand cards:", grid=[8,6], size=14, font="Times New Roman", color="black", align="left", visible=False)
        game_info_18        = Text(app, text="", grid=[9,6], size=14, font="Times New Roman", color="black", align="left", visible=False)
        game_info_19        = Text(app, text="Table cards:", grid=[8,7], size=14, font="Times New Roman", color="black", align="left", visible=False)
        game_info_20        = Text(app, text="", grid=[9,7], size=14, font="Times New Roman", color="black", align="left", visible=False)

        game_signal         = 0
        game_result1        = Text(app, text="", grid=[9,22], size=14, font="Times New Roman", color="black", align="left")
        game_result2        = Text(app, text="", grid=[9,23], size=14, font="Times New Roman", color="black", align="left")

        gui_setup()
        app.display()

    def show_game_state(self):
        """ This show the game state using text """
        print("""
        +------------------------+------------------------+
        | P1: """ + self.g_players[0]._name +
            """               | P2: """ + self.g_players[1]._name +
                """    |
        +------------------------+------------------------+
        | Chips: $""" + str(self.g_players[0]._chips) +
            """           | Chips: $""" +
                str(self.g_players[1]._chips) + """            |
        +------------------------+------------------------+
        | Pot: $""" + str(self.g_pool) +
            """ | Current bet: $""" + str(self.g_players[0]._bet) +
                """ | Highest bet: $""" + str(self.high_bet()) + """
        +------------------------+------------------------+
        | Cards in hand: """ + str(self.g_players[0]._hand) + """
        +------------------------+------------------------+
        | Cards on board: """ + str(self.g_board) + """
        +------------------------+------------------------+
        """)

    def show_hand_cards(self):
        """ This reveal/show the players cards and table cards using text """
        print("""
        +------------------------+------------------------+
        | Hand cards (""" + str(self.g_players[0]._name) + """): """ + str(self.g_players[0]._hand) + """
        +------------------------+------------------------+
        | Hand cards (""" + str(self.g_players[1]._name) + """): """ + str(self.g_players[1]._hand) + """
        +------------------------+------------------------+
        | Table cards: """ + str(self.g_board) + """
        +------------------------+------------------------+
        """)

    def main(self):
        """ sets up the main menu """

        def start_game():
            main_menu.destroy()
            self.setup()

        def quit_game():
            exit()

        main_menu = App(title="Poker Game Menu", width=150, height=250)

        # ~ poker_pic       = Picture(main_menu, image="Suit Icons.gif", align="top")
        window_title    = Text(main_menu, text="Game Menu", size=13, font="Times New Roman", color="black", align="top")
        start_game      = PushButton(main_menu, command=start_game, text="Start Game", align="top")
        exit_game       = PushButton(main_menu, command=quit_game, text="Quit Game", align="top")

        main_menu.display()

        # gp = input("Do you want to play (y/n)? ")

        # if gp == "y":
        #     print("Starting game")
        #     self.setup()
        # if gp == "n":
        #     print("Closing game")
        #     exit()

    def setup(self):
        """ sets up a game vs a computer player """
        self.g_state = 0
        self.g_round = 0
        del self.g_players[:]
        del self.g_board[:]

        # p_name = input("What is your name?")
        self.g_players.append(Player("Player 1"))
        self.g_players.append(Player("Computer player"))

        for player in self.g_players:
            player._chips = 1000
            logger.info(str(player._name) + "'s chips: " + str(player._chips))
            logger.info(player._name + " joined the game")

        self.g_state += 1
        logger.info("Game state :" + str(self.g_state))
        self.g_round += 1
        logger.info("Round 1")

        self.game_window()
        # self.gameloop()

    def new_round(self):
        """ sets up a new round """
        self.g_state = 0
        self.g_pool = 0
        del self.g_board[:]
        for player in self.g_players:
            del player._hand[:]
            player._bet = 0

        self.g_state += 1
        logger.info("Game state :" + str(self.g_state))
        self.g_round += 1
        logger.info("Round " + str(self.g_round))

        # ~ self.gameloop()

    def blinds(self):
        """ adds blinds(forced bets) """
        c1 = self.g_players[0]._chips
        b1 = self.g_players[0]._bet
        c2 = self.g_players[1]._chips
        b2 = self.g_players[1]._bet

        if self.g_priority == 0:
            c1 -= 25
            b1 += 25
            c2 -= 50
            b2 += 50
        if self.g_priority == 1:
            c1 -= 50
            b1 += 50
            c2 -= 25
            b2 += 25

        # this section should be removed (or redone) at some point.
        self.g_players[0]._chips = c1
        self.g_players[0]._bet = b1
        self.g_players[1]._chips = c2
        self.g_players[1]._bet = b2

        self.g_pool = 75

    def deal1(self):
        """ create a deck, shuffle it, and deal 2 cards to each player """
        self.g_deck =  Deck()
        self.g_deck.shuffler()

        for player in self.g_players:
            player.drawCard(self.g_deck)
            player.drawCard(self.g_deck)

    def deal2(self):
        """ Flop - three community cards are flipped face up on the table """
        self.g_board.append(self.g_deck._cards.pop())
        self.g_board.append(self.g_deck._cards.pop())
        self.g_board.append(self.g_deck._cards.pop())
        # self.show_table()

        # ~ self.player_turn()

    def deal3(self):
        """ Turn - fourth community card is flipped face up on the table """
        self.g_board.append(self.g_deck._cards.pop())
        # self.show_table()

        # ~ self.player_turn()

    def deal4(self):
        """ River - fifth community card is flipped face up on the table """
        self.g_board.append(self.g_deck._cards.pop())
        # self.show_table()

        # ~ self.player_turn()

    # ~ def player_turn(self):
        # ~ """ player betting round """
        # ~ player = self.g_players[self.g_priority]
        # ~ self.show_game_state()
        # ~ # self.show_high_bet()
        # ~ # self.show_bet(player)
        # ~ if player._chips < 50:
            # ~ gp = input("You can now fold (f), call/check (c) or quit game (q)")
        # ~ else:
            # ~ gp = input("You can now fold (f), call/check (c), raise (r) or quit game (q)")
        # ~ if gp == "f":
            # ~ self.fold(player)
        # ~ elif gp == "c":
            # ~ self.call(player)
        # ~ elif gp == "r":
            # ~ hb = self.high_bet()
            # ~ cb = player._bet
            # ~ pc = hb - cb
            # ~ print("You call " + str(pc))
            # ~ while True:
                # ~ try:
                    # ~ bet = int(input("how much do you want to bet?"))
                    # ~ break
                # ~ except:
                    # ~ print("Please give a number")
            # ~ if isinstance(bet, int):
                # ~ self.bet(player, int(bet))
        # ~ elif gp == "q":
            # ~ exit()

        # ~ if gp in ["f", "c", "r", "f"]:
            # ~ if self.g_priority == 0:
                # ~ self.g_priority += 1
                # ~ self.computer_turn()
        # ~ else:
            # ~ self.player_turn()

    def computer_turn(self):
        """ first computer betting round """
        # unfinished
        player = self.g_players[self.g_priority]
        self.call(player)

        logger.info("Computer player betted, called or raised")
        self.g_priority -= 1

    # ~ def gameloop(self):
        # ~ self.blinds()
        # ~ self.deal1()
        # ~ self.player_turn()
        # ~ if self.g_state == 1:
            # ~ self.g_state += 1
            # ~ logger.info("Game state :" + str(self.g_state))
            # ~ self.deal2()
        # ~ if self.g_state == 2:
            # ~ self.g_state += 1
            # ~ logger.info("Game state :" + str(self.g_state))
            # ~ self.deal3()
        # ~ if self.g_state == 3:
            # ~ self.g_state += 1
            # ~ logger.info("Game state :" + str(self.g_state))
            # ~ self.deal4()
        # ~ if self.g_state == 4:
            # ~ self.g_state += 1
            # ~ logger.info("Game state :" + str(self.g_state))
            # ~ self.end_round()
            # ~ logger.info("Round over")
            # ~ gp = input("You can now quit (q) or Press enter to continue")
            # ~ if gp == "q":
                # ~ exit()
            # ~ else:
                # ~ self.new_round()

    def end_round(self):
        # print("End of Round Players: ")
        # print(self.g_players)

        self.show_hand_cards()

        bhp = self.find_winner(self.g_players)
        pc = len(bhp)

        if pc == 1:
            print("[" + bhp[0]._name + "] won the pot (" + str(self.g_pool) + ")")
            bhp[0]._chips = bhp[0]._chips + self.g_pool
            self.g_pool = 0
            # self.player_cleanup(bhp[0])

        if len(bhp) == 2:
            print("[" + bhp[0]._name + "] splits the pot (" + str(self.g_pool) + ") with [" + bhp[1]._name + "]")
            bhp[0]._chips = bhp[0]._chips + self.g_pool/2
            bhp[1]._chips = bhp[1]._chips + self.g_pool/2
            self.g_pool = 0

        for player in self.g_players:
            self.player_cleanup(player)

        logger.info("End of Round")

    def find_winner(self, players):
        winners = []
        best_hand_value = 0
        for player in players:
            a = self.best_hand(player)
            if a > best_hand_value:
                if best_hand_value != 0:
                    del winners[0]
                best_hand_value = a
                winners.append(player)
            elif self.best_hand(player) == best_hand_value:
                winners.append(player)
        # ~ self.show_winning_hand(best_hand_value)
        return winners

    def show_winning_hand(self, best_hand_value):
        if best_hand_value == 0:
            logger.error("Error: No winning hand was found.")
        if 1 <= best_hand_value < 2:
            print("Winning hand: High card")
        if 2 <= best_hand_value < 3:
            print("Winning hand: Pair")
        if 3 <= best_hand_value < 4:
            print("Winning hand: Two pair")
        if 4 <= best_hand_value < 5:
            print("Winning hand: Three of a kind")
        if 5 <= best_hand_value < 6:
            print("Winning hand: Straight")
        if 6 <= best_hand_value < 7:
            print("Winning hand: Flush")
        if 7 <= best_hand_value < 8:
            print("Winning hand: Full House")
        if 8 <= best_hand_value < 9:
            print("Winning hand: Four of a kind")
        if 9 <= best_hand_value < 10:
            print("Winning hand: Straight Flush")
        if 10 <= best_hand_value:
            print("Winning hand: Royal Straight Flush")

    def best_hand(self, player):
        egh = self.make_end_hand(player)
        rv = 0

        if self.r_flush(egh) != 0:
            rv = self.r_flush(egh)
        elif self.s_flush(egh) != 0:
            rv = self.s_flush(egh)
        elif self.kind4(egh) != 0:
            rv = self.kind4(egh)
        elif self.full_house(egh) != 0:
            rv = self.full_house(egh)
        elif self.flush(egh) != 0:
            rv = self.flush(egh)
        elif self.straight(egh) != 0:
            rv = self.straight(egh)
        elif self.kind3(egh) != 0:
            rv = self.kind3(egh)
        elif self.two_pair(egh) != 0:
            rv = self.two_pair(egh)
        elif self.pair(egh) != 0:
            rv = self.pair(egh)
        elif self.high_card(egh) != 0:
            rv = self.high_card(egh)

        return rv

    def score_hand(self, cards):
        egh = cards
        rv = 0

        if self.r_flush(egh) != 0:
            print("Royal Straight Flush")
            rv = self.r_flush(egh)
        elif self.s_flush(egh) != 0:
            print("Straight Flush")
            rv = self.s_flush(egh)
        elif self.kind4(egh) != 0:
            print("4 of a kind")
            rv = self.kind4(egh)
        elif self.full_house(egh) != 0:
            print("Full House")
            rv = self.full_house(egh)
        elif self.flush(egh) != 0:
            print("Flush")
            rv = self.flush(egh)
        elif self.straight(egh) != 0:
            print("Straight")
            rv = self.straight(egh)
        elif self.kind3(egh) != 0:
            print("3 of a kind")
            rv = self.kind3(egh)
        elif self.two_pair(egh) != 0:
            print("Two pair")
            rv = self.two_pair(egh)
        elif self.pair(egh) != 0:
            print("Pair")
            rv = self.pair(egh)
        elif self.high_card(egh) != 0:
            print("High card")
            rv = self.high_card(egh)

        return rv

    def make_end_hand(self, player):
        eh = []
        for card in player._hand:
            eh.append(card)
        for card in self.g_board[:]:
            eh.append(card)
        eh.sort(key=lambda x: x._value, reverse=False)
        # print(str(player._name) + "'s end hand: ")
        # print(eh)
        return eh

    def player_cleanup(self, player):
        player._bet       = 0
        player._hand      = []   # not sure if this actually empty the hand. I should test this.
        # player.p_activity = False #  not sure if this should be implemented here or not.

    def show_table(self):
        print("Cards on table: " + str(self.g_board))

    def show_pool(self):
        print("Current pool: " + str(self.g_pool))

    def show_high_bet(self):
        print("Highest bet: " + str(self.high_bet()))

    def show_bet(self, player):
        print("Your current bet: " + str(player._bet))

    def high_bet(self):
        b = 0
        for player in self.g_players:
            if b < player._bet:
                b = player._bet
        return b

    def call(self, player):
        hb = self.high_bet()
        cb = player._bet
        pc = hb - cb

        if cb < hb:
            player._chips -= pc
            player._bet   += pc
            self.g_pool   += pc

        logger.info("Player called/checked")

    def fold(self, player):
        self.player_cleanup(player)
        logger.info("Player folded")

    def bet(self, player, bet):
        hb = self.high_bet()
        cb = player._bet
        pc = hb - cb

        if cb < hb:
            player._chips -= pc
            player._bet   += pc
            self.g_pool   += pc

        player._chips -= bet
        player._bet   += bet
        self.g_pool   += bet

        logger.info("Player raised")

    # def card_value_finder(self, value):
    #     p_hand = self.g_board + self.g_players[0]._hand
    #     for card in p_hand:
    #         if card._value == value:
    #             return True
    #     return False

    def r_flush(self, hand):
        c1 = hand
        f1 = False
        h_suit = 0
        c_suit = 0
        d_suit = 0
        s_suit = 0
        c1.sort(key=lambda x: x._value, reverse=False)
        v1 = 0
        s1 = 0
        rv = 0
        t1 = []
        t2 = []

        for card in c1:
            if card._suit == "hearts":
                h_suit += 1
            if card._suit == "clubs":
                c_suit += 1
            if card._suit == "diamonds":
                d_suit += 1
            if card._suit == "spades":
                s_suit += 1

        if h_suit > 4:
            f1 = True
            for card in c1:
                if card._suit == "hearts":
                    t1.append(card)
        elif c_suit > 4:
            f1 = True
            for card in c1:
                if card._suit == "clubs":
                    t1.append(card)
        elif d_suit > 4:
            f1 = True
            for card in c1:
                if card._suit == "diamonds":
                    t1.append(card)
        elif s_suit > 4:
            f1 = True
            for card in c1:
                if card._suit == "spades":
                    t1.append(card)

        if f1:
            for card in t1:
                if card._value > 9:
                    t2.append(card)

            v1 = c1[0]._value

            for card in t2:
                if card._value == v1:
                    s1 += 1
                    if s1 == 5:
                        rv = 10
                        return rv
                    v1 = card._value + 1
                else:
                    v1 = card._value + 1
                    s1 = 1

        return 0

    def s_flush(self, hand):
        c1 = hand
        c1.sort(key=lambda x: x._value, reverse=False)
        t1 = []
        f1 = False
        h_suit = 0
        c_suit = 0
        d_suit = 0
        s_suit = 0
        v1 = 0
        s1 = 1
        hv1 = 0
        rv = 0

        for card in c1:
            if card._suit == "hearts":
                h_suit += 1
            if card._suit == "clubs":
                c_suit += 1
            if card._suit == "diamonds":
                d_suit += 1
            if card._suit == "spades":
                s_suit += 1

        if h_suit > 4:
            f1 = True
            for card in c1:
                if card._suit == "hearts":
                    t1.append(card)
        elif c_suit > 4:
            f1 = True
            for card in c1:
                if card._suit == "clubs":
                    t1.append(card)
        elif d_suit > 4:
            f1 = True
            for card in c1:
                if card._suit == "diamonds":
                    t1.append(card)
        elif s_suit > 4:
            f1 = True
            for card in c1:
                if card._suit == "spades":
                    t1.append(card)

        if f1:
            v1 = t1[0]._value + 1
            for card in t1:
                if card._value == v1:
                    s1 += 1
                    if s1 > 4:
                        hv1 = card._value
                    v1 = card._value + 1
                else:
                    v1 = card._value + 1
                    s1 = 1

        if hv1 != 0:
            rv = 9 + hv1/100
            return rv
        else:
            return 0

    def kind4(self, hand):
        c1 = hand
        c1.sort(key=lambda x: x._value, reverse=True)
        v1 = c1[0]._value
        k1 = 0
        hv1 = 0
        hv2 = 0
        rv = 0

        for card in c1:
            if card._value == v1:
                k1 += 1
                if k1 > 3:
                    hv1 = card._value
            else:
                v1 = card._value
                k1 = 1

        if hv1 != 0:
            for card in c1:
                if card._value != hv1:
                    if card._value > hv2:
                        hv2 = card._value
            rv = 8 + hv1/100 + hv2/10000
            return rv
        else:
            return 0

    def full_house(self, hand):
        c1  = hand
        c1.sort(key=lambda x: x._value, reverse=True)
        v1  = c1[0]._value
        h1  = 0
        hv1 = 0
        hv2 = 0
        rv  = 0

        for card in c1:
            if card._value == v1:
                h1 += 1
                if h1 == 3:
                    if hv1 < card._value:
                        hv1 = card._value
            else:
                v1 = card._value
                h1 = 1

        if hv1 != 0:
            v1 = c1[0]._value
            h1 = 0
            for card in c1:
                if card.value != hv1:
                    if card._value == v1:
                        h1 += 1
                        if h1 == 2:
                            if hv2 < card._value:
                                hv2 = card._value
                    else:
                        v1 = card._value
                        h1 = 1
        if hv2 != 0:
            rv = 7 + hv1/100 + hv2/10000
            return rv
        else:
            return 0

    def flush(self, hand):
        c1 = hand
        c1.sort(key=lambda x: x._value, reverse=True)
        h_suit = 0
        c_suit = 0
        d_suit = 0
        s_suit = 0
        f1 = 0
        hv1 = 0
        hv2 = 0
        hv3 = 0
        hv4 = 0
        hv5 = 0
        rv = 0

        for card in c1:
            if card._suit == "hearts":
                h_suit += 1
            if card._suit == "clubs":
                c_suit += 1
            if card._suit == "diamonds":
                d_suit += 1
            if card._suit == "spades":
                s_suit += 1

        if h_suit > 4:
            for card in c1:
                if card._suit == "hearts":
                    f1 += 1
                    if f1 == 1:
                        hv1 = card._value
                    if f1 == 2:
                        hv2 = card._value
                    if f1 == 3:
                        hv3 = card._value
                    if f1 == 4:
                        hv4 = card._value
                    if f1 == 5:
                        hv5 = card._value
            rv = 6 + hv1/100 + hv2/10000 + hv3/1000000 + hv4/100000000 + hv5/10000000000
            return rv
        elif c_suit > 4:
            for card in c1:
                if card._suit == "clubs":
                    f1 += 1
                    if f1 == 1:
                        hv1 = card._value
                    if f1 == 2:
                        hv2 = card._value
                    if f1 == 3:
                        hv3 = card._value
                    if f1 == 4:
                        hv4 = card._value
                    if f1 == 5:
                        hv5 = card._value
            rv = 6 + hv1/100 + hv2/10000 + hv3/1000000 + hv4/100000000 + hv5/10000000000
            return rv
        elif d_suit > 4:
            for card in c1:
                if card._suit == "diamonds":
                    f1 += 1
                    if f1 == 1:
                        hv1 = card._value
                    if f1 == 2:
                        hv2 = card._value
                    if f1 == 3:
                        hv3 = card._value
                    if f1 == 4:
                        hv4 = card._value
                    if f1 == 5:
                        hv5 = card._value
            rv = 6 + hv1/100 + hv2/10000 + hv3/1000000 + hv4/100000000 + hv5/10000000000
            return rv
        elif s_suit > 4:
            for card in c1:
                if card._suit == "spades":
                    f1 += 1
                    if f1 == 1:
                        hv1 = card._value
                    if f1 == 2:
                        hv2 = card._value
                    if f1 == 3:
                        hv3 = card._value
                    if f1 == 4:
                        hv4 = card._value
                    if f1 == 5:
                        hv5 = card._value
            rv = 6 + hv1/100 + hv2/10000 + hv3/1000000 + hv4/100000000 + hv5/10000000000
            return rv
        else:
            return 0

    def straight(self, hand):
        c1 = hand
        c1.sort(key=lambda x: x._value, reverse=False)
        v1 = c1[0]._value
        s1 = 0
        hv1 = 0
        rv = 0

        for card in c1:
            if card._value == v1:
                s1 += 1
                if s1 > 4:
                    hv1 = card._value
                v1 = card._value + 1
            else:
                v1 = card._value + 1
                s1 = 1

        if c1[-1]._value == 14:
            if s1 < 5:
                s1 = 1
                v1 = 2
                for card in c1:
                    if card._value == v1:
                        s1 += 1
                        if s1 > 4:
                            if hv1 < card._value:
                                hv1 = card._value
                        v1 = card._value +1
        if hv1 != 0:
            rv = 5 + hv1/100
            return rv
        else:
            return 0

    def kind3(self, hand):
        c1 = hand
        c1.sort(key=lambda x: x._value, reverse=True)
        v1 = c1[0]._value
        k1 = 0
        hv1 = 0
        hv2 = 0
        hv3 = 0
        rv = 0

        for card in c1:
            if card._value == v1:
                k1 += 1
                if k1 == 3:
                    hv1 = card._value
            else:
                v1 = card._value
                k1 = 1

        if hv1 != 0:
            for card in c1:
                if card._value != hv1:
                    if hv2 == 0:
                        hv2 = card._value
                    elif hv3 == 0:
                        hv3 = card._value
            rv = 4 + hv1/100 + hv2/10000 + hv3/1000000
            return rv
        else:
            return rv

    def two_pair(self, hand):
        c1 = hand
        c1.sort(key=lambda x: x._value, reverse=True)
        v1 = c1[0]._value
        p1 = 0
        hv1 = 0
        hv2 = 0
        hv3 = 0
        rv = 0

        for card in c1:
            if card._value == v1:
                p1 += 1
                if p1 == 2:
                    if hv1 == 0:
                        hv1 = card._value
                    elif hv2 == 0:
                        hv2 = card._value
                    p1 = 0
            else:
                v1 = card._value
                p1 = 1

        if hv2 != 0:
            for card in c1:
                if card._value != hv1:
                    if card._value != hv2:
                        if hv3 < card._value:
                            hv3 = card._value
            rv = 3 + hv1/100 + hv2/10000 + hv3/1000000
            return rv
        else:
            return 0

    def pair(self, hand):
        c1 = hand
        c1.sort(key=lambda x: x._value, reverse=True)
        v1 = c1[0]._value
        p1 = 0
        hv1 = 0
        hv2 = 0
        hv3 = 0
        hv4 = 0
        rv = 0

        for card in c1:
            if card._value == v1:
                p1 += 1
                if p1 == 2:
                    hv1 = card._value
            else:
                v1 = card._value
                p1 = 1

        if hv1 != 0:
            for card in c1:
                if card._value != hv1:
                    if hv2 == 0:
                        hv2 = card._value
                    elif hv3 == 0:
                        hv3 = card._value
                    elif hv4 == 0:
                        hv4 = card._value
            rv = 2 + hv1/100 + hv2/10000 + hv3/1000000 + hv4/100000000
            return rv
        else:
            return 0

    def high_card(self, hand):
        c1 = hand
        c1.sort(key=lambda x: x._value, reverse=True)
        hv1 = c1[0]._value
        hv2 = c1[1]._value
        hv3 = c1[2]._value
        hv4 = c1[3]._value
        hv5 = c1[4]._value
        rv = 1 + hv1/100 + hv2/10000 + hv3/1000000 + hv4/100000000 + hv5/10000000000
        return rv

g1 = Game("Poker")


MODULES = ['main', 'widget']

DEPS =  [
    (['any'],
     [
        ('app', 'Supervisor console', 'supervisorctl'),
   		('plugin', 'services'),
     ])
]

NAME = 'Supervisor'
PLATFORMS = ['any']
DESCRIPTION = 'Control processes under supervisord'
VERSION = '1'
GENERATION = 1
AUTHOR = 'Ajenti team'
HOMEPAGE = 'http://ajenti.org'


import arcle
import gymnasium as gym
import time

env = gym.make('ARCLE/RawARCEnv-v0',render_mode='ansi')

obs, info = env.reset()

for _ in range(1000):

    action = env.action_space.sample()

    obs,reward,term,trunc,info = env.step(action)

    if term or trunc:
        obs, info = env.reset()

    time.sleep(0.3)

env.close()


import random
import sys

import pygame
import pygame_gui

def load_image(path):
    image = pygame.image.load(path)
    return image

def write_exp_and_record(number):
    text = font.render(f"Ваши очки: {number}", True, (0, 0, 255))
    text_x = 10
    text_y = 10
    screen.blit(text, (text_x, text_y))
    text = font.render(f"Рекорд: {record}", True, (0, 0, 255))
    text_x = 600
    text_y = 10
    screen.blit(text, (text_x, text_y))

def draw_rects():
    for i2 in range(4):
        x = 0
        y = 155 + (120 * i2)
        rect = pygame.Rect(x, y, 1000, 70)
        pygame.draw.rect(screen, (195, 213, 229), rect)

def do_gameover(details):
    global running, clock, fps, playing

    def write_info():
        global exp

        texts = [font.render("Игра окончена", True, (0, 0, 255)), font.render(details, True, (0, 0, 255)),
                 font.render(f"Результат: {exp}", True, (0, 0, 255))]
        text_x = 300
        text_y = 250
        text_rect = pygame.Rect(text_x - 10, text_y - 10, 430, 145)
        frame_rect = pygame.Rect(text_x - 15, text_y - 15, 435, 150)
        pygame.draw.rect(screen, (200, 200, 200), text_rect)
        pygame.draw.rect(screen, (180, 180, 180), frame_rect, 10)
        screen.blit(texts[0], (text_x, text_y))
        text_y += 40
        screen.blit(texts[1], (text_x, text_y))
        text_y += 40
        screen.blit(texts[2], (text_x, text_y))

    manager2 = pygame_gui.UIManager((1000, 600))
    play_rect2 = pygame.Rect((400, 400), (200, 50))
    play2 = pygame_gui.elements.UIButton(
        relative_rect=play_rect2,
        manager=manager2,
        text="Начать заново",
    )
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
                exit()
            if event.type == pygame.USEREVENT:
                if event.user_type == pygame_gui.UI_BUTTON_PRESSED:
                    if event.ui_element == play2:
                        running = False
            manager2.process_events(event)

        draw_rects()
        enemies.draw(screen)
        doctors.draw(screen)
        smiles.draw(screen)
        vaccines.draw(screen)
        write_exp_and_record(exp)
        write_info()
        manager2.draw_ui(screen)
        manager2.update(time_delta=time_delta)
        clock.tick(fps)
        pygame.display.flip()

class Doctor(pygame.sprite.Sprite):

    def __init__(self, *group):
        super().__init__(*group)
        self.image = load_image("data/doctor500.png")
        self.rect = self.image.get_rect()
        self.rect.x = 100
        self.rect.y = 150
        self.move_rate = 120

    def update(self, *args):
        if args and args[0].type == pygame.MOUSEBUTTONDOWN and \
                self.rect.collidepoint(args[0].pos):
            vac = Vaccine(y=self.rect.centery)
            vaccines.add(vac)
        elif args and args[0].type == pygame.KEYDOWN:
            # print(args[0].key)
            # if args[0].key == 275:
            #    self.rect.x += 150
            # if args[0].key == 276:
            #    self.rect.x -= 150
            if args[0].key == 274 and self.rect.y + self.move_rate <= 600:
                self.rect.y += self.move_rate
            if args[0].key == 273 and self.rect.y - self.move_rate >= 145:
                self.rect.y -= self.move_rate
            if args[0].key == 32:
                vac = Vaccine(y=self.rect.centery)
                vaccines.add(vac)

class Vaccine(pygame.sprite.Sprite):

    def __init__(self, *group, y):
        super().__init__(*group)
        self.image = load_image("data/shpritz.png")
        self.rect = self.image.get_rect()
        self.rect.x = 150
        self.rect.centery = y - 2

    def update(self, *args):
        self.rect.x += 5
        if self.rect.x > 950:
            self.kill()

class Smile(pygame.sprite.Sprite):

    def __init__(self, *group, n):
        super().__init__(*group)
        self.image = load_image(f"data/смайл{random.choice([1, 2, 3])}.png")
        self.rect = self.image.get_rect()
        self.rect.centerx = 50
        self.rect.y = 160 + (120 * n)
        self.hp = 2

    def update(self, *args):
        hits = pygame.sprite.spritecollide(self, enemies, False)
        if hits:
            y = hits[0].rect.y
            self.hp -= 1
            if self.hp == 0:
                for hit in hits:
                    hit.kill()
                self.kill()
            if self.hp == 1:
                self.image = load_image("data/больной смайлик.png")
                for en in enemies:
                    if en.rect.y == y:
                        en.kill()

class Enemy(pygame.sprite.Sprite):

    def __init__(self, *group):
        super().__init__(*group)
        self.image = load_image("data/virus1.png")
        self.images = [load_image("data/virus3.png"), load_image("data/virus5.png")]
        self.rect = self.image.get_rect()
        self.rect.x = 800 + random.randint(-150, 150)
        self.rect.y = 150 + (120 * random.randint(0, 3))
        self.hp = 3

    def update(self, *args):
        global exp
        self.rect.x -= 2
        hits = pygame.sprite.spritecollide(self, vaccines, False)
        if hits:
            for hit in hits:
                hit.kill()
                self.hp -= damage
                if self.hp == 2:
                    self.image = self.images[0]
                if self.hp == 1:
                    self.image = self.images[1]
        if self.rect.x < 20:
            do_gameover("Вирус пробрался!")
        if self.rect.x < doc.rect.x + doc.rect.width - 30 and self.rect.y == doc.rect.y:
            if exp > record:
                with open("data/record.txt", "w") as r_file:
                    r_file.write(f"{exp}")
            do_gameover("Доктор заразился!")
        if self.hp <= 0:
            exp += 1
            self.kill()

while True:
    pygame.init()
    font = pygame.font.Font("data/Phosphate.ttc", 40)
    size = width, height = 1000, 600
    screen = pygame.display.set_mode(size)
    pygame.display.set_caption('Игра "Вакцинация"')
    doctors = pygame.sprite.Group()
    enemies = pygame.sprite.Group()
    vaccines = pygame.sprite.Group()
    smiles = pygame.sprite.Group()
    damage = 1
    num_of_enemies = 1
    manager = pygame_gui.UIManager((1000, 600))
    fon = pygame.image.load("/Users/alexeyilyin/Downloads/oblozhka 3.png")
    with open("data/record.txt", "r") as record_file:
        record = int(record_file.read())
    doc = Doctor()
    doctors.add(doc)
    for i in range(10):
        enemy = Enemy()
        enemies.add(enemy)
    for i in range(4):
        smile = Smile(n=i)
        smiles.add(smile)
    exp = 0
    fps = 60
    clock = pygame.time.Clock()
    running = True
    fr_c = 0
    enemy_rate = 250
    playing = False
    block = False
    play_rect = pygame.Rect((420, 525), (100, 50))
    play = pygame_gui.elements.UIButton(
        relative_rect=play_rect,
        manager=manager,
        text="Играть",
    )
    while running:
        screen.fill((255, 255, 255))
        time_delta = clock.tick(60) / 1000.0
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit()
            if event.type == pygame.USEREVENT:
                if event.user_type == pygame_gui.UI_BUTTON_PRESSED:
                    if event.ui_element == play:
                        playing = True
            if playing:
                doctors.update(event)
            if not playing:
                manager.process_events(event)
        if not playing:
            screen.blit(fon, (0, -117))
            manager.draw_ui(screen)
            manager.update(time_delta=time_delta)
        if playing:
            enemies.update()
            vaccines.update()
            smiles.update()
            draw_rects()
            enemies.draw(screen)
            doctors.draw(screen)
            smiles.draw(screen)
            write_exp_and_record(exp)
            vaccines.draw(screen)
        clock.tick(fps)
        pygame.display.flip()
        if playing:
            if fr_c % enemy_rate == 0:
                if num_of_enemies < 3:
                    num_of_enemies += 0.1
                if enemy_rate > 50:
                    enemy_rate -= 10
                for i in range(int(num_of_enemies)):
                    if len(enemies) < 10:
                        en = Enemy()
                        enemies.add(en)
            fr_c += 1
        if not smiles:
            do_gameover("Вирус победил!")

    if exp > record:
        with open("data/record.txt", "w") as r_file:
            r_file.write(f"{exp}")


from django.urls import path, include
from . import views
from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)

urlpatterns = [
  path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
  path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
  path('projects', views.get_projects, name='api_get_projects'),
  path('projects/<int:id>', views.get_project, name='api_get_project'),
  path('projects/<int:id>/vote', views.vote_project, name='api_vote_project')
]


import sys
sys.setrecursionlimit(10 ** 6)

def search(v, wei):
    for i in graph[v]:
        a, b = i
        if distance[a] == -1:
            distance[a] = wei + b
            search(a, wei + b)

n = int(sys.stdin.readline())
graph = [[] for _ in range(n + 1)]

for _ in range(n):
    temp = list(map(int, sys.stdin.readline().split()))
    index = 1

    while temp[index] != -1:
        graph[temp[0]].append((temp[index], temp[index + 1]))
        index += 2

## 1에서 가장 먼 거리에 있는 노르들 구한다.
distance = [-1] * (n + 1)
distance[1] = 0
search(1, 0)

## 1에서 구한 노드와 가장 먼 거리에 있는 노드를 구한다.
start = distance.index(max(distance))
distance = [-1] * (n + 1)
distance[start] = 0
search(start, 0)

print(max(distance))

백준-트리의지름2.py


def solve(H, W, R, C):
    if H < R or W < C:
        return 0
    if H == 1 and W == 1:
        return 0

    if R == 1 or R == H:
        if 1 < C and C < W:
            res =  3
        else:
            res =  2
    else:
        if 1 < C and C < W:
            res =  4
        else:
            res =  3
    if H == 1 or W == 1:
        res -= 1
    return res

if __name__ == "__main__":
    H, W = map(int, input().split())
    R, C = map(int, input().split())
    print(solve(H, W, R, C))


#!/usr/bin/env python3

from setuptools import find_packages, setup

with open('requirements.txt') as requirements:
    requirements = requirements.read().splitlines()

with open('README.md') as readme:
    long_description = readme.read()

if __name__ == '__main__':
    setup(name='wikiphilosophy',
          version='0.3.3',
          description='See how every wikipedia article leads to Philosophy',
          author='Adhityaa Chandrasekar',
          author_email='c.adhityaa@gmail.com',
          maintainer='Adhityaa Chandrasekar',
          maintainer_email='c.adhityaa@gmail.com',
          platforms='any',
          packages=find_packages(),
          install_requires=requirements,
          license='AGPL-3.0',
          long_description=long_description,
          entry_points={'console_scripts': ['wikiphilosophy = wikiphilosophy:main']},
          classifiers=[
              'Development Status :: 4 - Beta',

              'Environment :: Console',
              'Environment :: MacOS X',
              'Environment :: Win32 (MS Windows)',
              'Environment :: X11 Applications :: Gnome',

              'Intended Audience :: Developers',

              'License :: OSI Approved :: GNU Affero General Public License '
              'v3 or later (AGPLv3+)',

              'Operating System :: OS Independent',

              'Programming Language :: Python :: Implementation :: CPython',
              'Programming Language :: Python :: 3.4',
              'Programming Language :: Python :: 3.5',
              'Programming Language :: Python :: 3 :: Only'])


import flask
import requests

app = flask.Flask(__name__)
app.config["DEBUG"] = True

@app.route("/test", methods=["POST"])
def test():
    return 'Ciao'

@app.route('/')
def home():
    r = requests.post('http://127.0.0.1:5000/test')
    return ""

app.run()


import numpy.typing as npt
from sdg_clf import modelling, base, evaluation

def get_final_predictions_sdg_clf(texts: list[str], model_weights: list[str], threshold: float = 0.5) -> npt.NDArray:
    model_types = modelling.get_model_types(model_weights)
    # the number of models in the ensemble
    n_models = len(model_types)
    predictions = []

    # create predictions if any are missing
    for i in range(n_models):
        # load the model
        transformer = base.get_transformer(model_types[i], model_weights[i])
        predictions.append(transformer.predict_multiple_samples_no_threshold(texts))

    # combine predictions
    predictions = evaluation.combine_multiple_predictions(predictions)
    # threshold predictions
    predictions = evaluation.threshold_multiple_predictions(predictions, threshold)
    # predict with strategy any
    predictions = evaluation.predict_multiple_strategy_any(predictions)
    # convert to numpy array
    predictions = predictions.numpy().astype(int)

    return predictions


import cv2
from imageutils import image_with_gray_arg
from imageutils import Color
from contourutils import get_contours

image, image_gray = image_with_gray_arg()
contours = get_contours(image_gray, cv2.RETR_EXTERNAL)
for contour in contours:
    perimeter = cv2.arcLength(contour, True)
    approx = cv2.approxPolyDP(contour, 0.01 * perimeter, True)
    if len(approx) == 4: # If there are 4 vertices approximated, then its a rect
        cv2.drawContours(image, [contour], -1, Color.GREEN.value, 2)
        x, y, w, h = cv2.boundingRect(approx)
        cv2.putText(
            image, "Rectangle", (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5,
            Color.GREEN.value, 2)
cv2.imshow("Rectangles", image)
cv2.waitKey(0)


#!/usr/bin/python

"""
Script for generating the plots of dneff vs. N
"""
import os

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

from scipy.ndimage import gaussian_filter
from scipy.interpolate import interp2d, interp1d
from utils import remove_nans
from scipy.interpolate import RectBivariateSpline
from matplotlib.lines import Line2D
from skimage.measure import find_contours

OMEGA_CDM_H2 = 0.1198
SI_BOUND = 457.281  # 0.1 cm^2 / g
NEFF_CMB_BOUND = (2.92, 0.36)
NEFF_BBN_BOUND = (2.85, 0.28)

FILE_NAMES = [
    "bm_lec1=1_lec2=0_xi_inf=1e-2",
    "bm_lec1=0.1_lec2=1_xi_inf=1e-2",
    "bm_lec1=0.1_lec2=1_xi_inf=5e-2",
    "bm_lec1=1e-3_lec2=1_xi_inf=1e-2",
]

DATA_FILES = [
    os.path.join(
        os.path.dirname(os.path.abspath(__file__)),
        "..",
        "..",
        "rundata",
        fn + ".csv",
    )
    for fn in FILE_NAMES
]

def find_cont(xs, ys, zs, level=SI_BOUND):
    contour = find_contours(zs, level)[0]

    jjs, iis = contour.T

    new_ys = np.interp(jjs, np.arange(len(ys)), ys)
    new_xs = np.interp(iis, np.arange(len(xs)), xs)

    return new_xs, new_ys

if __name__ == "__main__":

    # Load the benchmark data and extract needed quantities
    # data = pd.read_csv("../../rundata/bm_lec1=0.1_lec2=1.0.csv")
    # data = pd.read_csv("../../rundata/bm_lec1=1.0_lec2=0.0.csv")
    # data = pd.read_csv("../../rundata/bm_lec1=0.1_lec2=1.0_xi_inf=5e-2.csv")
    data = pd.read_csv("../../rundata/bm_lec1=0.1_lec2=1.0_xi_inf=1e-1.csv")

    data.sort_values(by=["LAM", "N"], inplace=True)

    ns = np.unique(np.array(data["N"]))
    lams = np.unique(np.array(data["LAM"]))

    NS = np.linspace(np.min(ns), 20, 500)
    LAMS = np.logspace(np.log10(np.min(lams)), np.log10(np.max(lams)), 500)

    n_array = np.array(data["N"]).reshape((len(lams), len(ns)))
    lam_array = np.array(data["LAM"]).reshape((len(lams), len(ns)))

    # Relic densities
    rde_array = np.array(data["RD_ETA"]).reshape((len(lams), len(ns)))
    rdd_array = np.array(data["RD_DEL"]).reshape((len(lams), len(ns)))
    remove_nans(rde_array)
    remove_nans(rdd_array)

    # Dneff
    dneff_cmb_array = np.array(data["DNEFF_CMB"]).reshape((len(lams), len(ns)))
    dneff_bbn_array = np.array(data["DNEFF_BBN"]).reshape((len(lams), len(ns)))
    remove_nans(dneff_cmb_array)
    remove_nans(dneff_bbn_array)

    # Generate the eta RD contour
    eta_rd_cont = find_cont(ns, lams, rde_array, level=OMEGA_CDM_H2)

    # Generate interpolation of delta neff at cmb and bbn
    dneff_cmb_interp = RectBivariateSpline(ns, np.log10(lams), dneff_cmb_array)
    dneff_bbn_interp = RectBivariateSpline(ns, np.log10(lams), dneff_bbn_array)

    # Evaluate on contour
    dneff_cmb = [
        dneff_cmb_interp(x, y)[0][0]
        for x, y in zip(eta_rd_cont[0], np.log10(eta_rd_cont[1]))
    ]
    dneff_bbn = [
        dneff_bbn_interp(x, y)[0][0]
        for x, y in zip(eta_rd_cont[0], np.log10(eta_rd_cont[1]))
    ]

    plt.plot(
        eta_rd_cont[0],
        np.abs(dneff_cmb),
        label=r"$\Delta N^{\mathrm{CMB}}_{\mathrm{eff}}$",
    )
    plt.plot(
        eta_rd_cont[0],
        np.abs(dneff_bbn),
        label=r"$\Delta N^{\mathrm{BBN}}_{\mathrm{eff}}$",
    )
    plt.legend()
    plt.yscale("log")
    plt.xlim([5, 30])
    plt.ylim([1e-4, 1e-1])
    plt.savefig(
        "/home/logan/Research/DarkSun/cpp/analysis/figures/dneff_xi_inf=1e-1.pdf"
    )


import os
import pickle

from dotenv import load_dotenv
from google.auth.transport.requests import Request
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build

SCOPES = ['https://mail.google.com/']

def gmail_authenticate(credentials):
    creds = None
    if os.path.exists("token.pickle"):
        with open("token.pickle", "rb") as token:
            creds = pickle.load(token)
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                credentials, SCOPES)
            creds = flow.run_local_server(port=0)
        with open("token.pickle", "wb") as token:
            pickle.dump(creds, token)
    return build('gmail', 'v1', credentials=creds)

def search_messages(service, query):
    result = service.users().messages().list(userId='me', q=query).execute()
    messages = []
    if 'messages' in result:
        messages.extend(result['messages'])
    while 'nextPageToken' in result:
        page_token = result['nextPageToken']
        result = service.users().messages().list(
            userId='me',
            q=query,
            pageToken=page_token,
        ).execute()
        if 'messages' in result:
            messages.extend(result['messages'])
    return messages

def read_message(service, message):
    msg = service.users().messages().get(
        userId='me',
        id=message['id'],
        format='full',
    ).execute()
    return msg['internalDate'], msg['snippet']

def get_verification_code(credentials):
    load_dotenv()
    service = gmail_authenticate(credentials)
    messages = search_messages(service, 'Подтверждение учетных данных Ozon')
    newest_code = {}
    for message in messages:
        timestamp, snippet = read_message(service, message)
        if not newest_code or timestamp >= newest_code['timestamp']:
            newest_code['timestamp'] = timestamp
            newest_code['code'] = snippet[112:118]
    return newest_code['code']


from functools import wraps

from .consts import ERROR_TYPE, EXCEPTION_TYPE, FUNC_TYPE, IGNORE_TYPE
from .types import Error

def ignore(func):
    func._type = IGNORE_TYPE
    return func

def functional(func):
    @wraps(func)
    def runner(self, *args, **kwargs):
        if not self._magic:
            return func(self, *args, **kwargs)

        if self.error:
            return self
        if self.exception:
            return self

        try:
            resp = func(self, self.data, *args, **kwargs)
            if isinstance(resp, Error):
                self.error = resp
            else:
                self.data = resp
        except Exception as exc:
            self.exception = exc

        return self

    runner._type = FUNC_TYPE
    return runner

def error(func):
    @wraps(func)
    def wrapper(self, *args, **kwargs):
        if not self._magic:
            resp = func(self, *args, **kwargs)
            if isinstance(resp, Error):
                self.error = resp.data
                return self.error

        if not self.error:
            return self

        resp = func(self, self.error, self.data, *args, **kwargs)
        if isinstance(resp, Error):
            self.error = resp.data
            return self

        if resp is not None:
            self.data = resp

        self.error = None
        return self

    wrapper._type = ERROR_TYPE
    return wrapper

def exception(exc_cls):
    def decorator(func):
        @wraps(func)
        def wrapper(self, *args, **kwargs):
            if not self._magic:
                resp = func(self, *args, **kwargs)
                if isinstance(resp, Error):
                    self.error = resp.data
                    return self.error
            if not self.exception:
                return self
            if not isinstance(self.exception, exc_cls):
                return self

            resp = func(self, self.exception, self.data, *args, **kwargs)
            if isinstance(resp, Exception):
                self.exception = resp
                return self

            if isinstance(resp, Error):
                self.error = resp.data
            elif resp is not None:
                self.data = resp

            self.exception = None
            return self

        wrapper._type = EXCEPTION_TYPE
        return wrapper

    return decorator


import tkinter as tk
import ttkbootstrap as ttk

class App(ttk.Window):
    def __init__(self, title, size):

        #main setup
        super().__init__(themename="darkly")
        self.title(title) #or just straight in the top funtion
        self.geometry(f"{size[0]}x{size[1]}")

        #widgets
        self.menu = Menu(self)
        self.main = Main(self)

        #run
        self.mainloop()

class Menu(ttk.Frame):
    def __init__(self, master):
        super().__init__(master)

        self.place(x=0, y=0, relwidth=0.3, relheight=1)

        self.create_widgets()

    def create_widgets(self):
        menu_button1 = ttk.Button(self, text="Button 1")
        menu_button2 = ttk.Button(self, text="Button 2")
        menu_button3 = ttk.Button(self, text="Button 3")

        menu_slider1 = ttk.Scale(self, orient="vertical")
        menu_slider2 = ttk.Scale(self, orient="vertical")

        toggle_frame= ttk.Frame(self)
        menu_toggle1 = ttk.Checkbutton(toggle_frame, text="check 1")
        menu_toggle2 = ttk.Checkbutton(toggle_frame, text="check 2")

        entry = ttk.Entry(self)

        #create the grid
        self.columnconfigure((0,1,2), weight=1, uniform="a")
        self.rowconfigure((0,1,2,3,4,5), weight=1, uniform="a")

        #place the widgets
        menu_button1.grid(row=0, column=0, sticky="nsew", columnspan=2)
        menu_button2.grid(row=0, column=2, sticky="nsew")
        menu_button3.grid(row=1, column=0, columnspan=3, sticky="nsew")

        menu_slider1.grid(row=2, column=0, rowspan=2, sticky="nsew", pady=20)
        menu_slider2.grid(row=2, column=2, rowspan=2, sticky="nsew", pady=20)

        #toggle layout
        toggle_frame.grid(row=4, column=0, columnspan=3, sticky="nsew")
        menu_toggle1.pack(side="left", expand=True)
        menu_toggle2.pack(side="left", expand=True)

        #entry layout
        entry.grid(row=5, column=0, columnspan=3, sticky="new", padx=10)

class Main(ttk.Frame):
    def __init__(self, master):
        super().__init__(master)
        self.place(relx=0.3, y=0, relwidth=0.7, relheight=1)
        Entry(self, "entry 1","button 1","green")
        Entry(self, "entry 2","button 2","blue")
        Entry(self, "entry 3","button 3","red")

class Entry(ttk.Frame):
    def __init__(self, master, label_text, button_text, label_background):
        super().__init__(master)

        label = ttk.Label(self, text=label_text, background=label_background)
        button = ttk.Button(self, text=button_text)

        label.pack(expand=True, fill="both")
        button.pack(expand=True, fill="both")

        self.pack(side="left", expand=True, fill="both", padx=20, pady=20)

App("Class based app", (600,400))


from time import sleep
print('-=-'*15, '\n         ANÁLISE DE DADOS DO GRUPO\n', '-=-'*15)
c = mulher20 = nhomem = mais18 = 0
while True:
  c +=1
  print(f'Pessoa {c}:')
  idade = int(input('Idade: '))
  sexo = str(input('Sexo [F/M]: ')).lower()
  if idade >=18:
    mais18 += 1
  if sexo == 'm':
    nhomem += 1
  if sexo == 'f' and idade < 20:
    mulher20 += 1
  opcao = str(input('\nQuer continuar [S/N]?: ')).lower()
  if opcao == 'n':
    print('Você escolheu SAIR ')
    sleep(0.8)
    print('Saindo...')
    sleep(1.2)
    break
  if opcao == 's':
    print('Você escolheu continuar...\n')
    sleep(0.8)
print('-=-'*15)
print(f'\nAo todo: \n* {mais18} pessoa/s com mais de 18 anos foram cadastrados\n* {nhomem} homem/s foram cadastrados \n* {mulher20} mulher/es com menos de 20 anos foi cadastrada')
print('\n!!!FIM!!!\n')


import threading
import ipywidgets as ipw
import pandas as pd
import bqplot as bq
import time

class Plot(bq.Figure):
    subseayellow = "#f8ed9b"
    subseagreen = "#00a0b0"
    subseapink = "#f3776f"
    subseablue = "#012b5d"
    subseagreydark = "#c0c1ba"
    colors = [subseablue, subseapink, subseagreen, subseayellow, subseagreydark]

    def __init__(self, timedeltafunction, datafunction, grid_area, live=True, title="", ylabel=""):
        """Plotter class

        Parameters
        ----------
        timedeltafunction : callable
            should return pandas.Timedelta
        datafunction : callable
            should return [{"s":pandas.Series, "labels":["label"]}, ...]
        grid_area : str
            name in css grid
        """
        self.timedeltafunction = timedeltafunction
        self.datafunction = datafunction
        self.live = live

        self.scales = self.get_scales()
        self.axx, self.axy = self.get_axes(ylabel=ylabel)
        self.marks = self.get_marks()
        margin = 30
        super().__init__(
            marks=self.marks,
            title=title,
            axes=[self.axx, self.axy],
            legend_style={"fill": "white"},
            legend_location="bottom-left",
            animation_duration=700,
            legend_text={"font-size": 16},
            fig_margin={
                "top": margin + 5,
                "bottom": margin - 5,
                "left": margin + 30,
                "right": margin,
            },
        )
        self.layout = ipw.Layout(grid_area=grid_area, width="auto", height="auto")
        self.start()

    def update_loop(self):
        while self.live:
            time.sleep(1)
            self.redraw()

    def start(self):
        self.live = True
        thread = threading.Thread(target=self.update_loop)
        thread.start()

    def stop(self):
        self.live = False

    def get_scales(self):
        return {"x": bq.DateScale(), "y": bq.LinearScale()}

    @staticmethod
    def get_axes_limits(lower, upper):
        diff = upper - lower
        _min = lower - diff * 0.3
        _max = upper + diff * 0.1
        return _min, _max

    def redraw(self):
        margin = pd.Timedelta('30s')
        data = self.datafunction()
        end = pd.Timestamp.now()
        start = end - self.timedeltafunction()
        maxs = []
        mins = []
        for d, mark in zip(data, self.marks):
            if len(d["s"]) > 0:
                array = d["s"][start-margin:end+margin]
                x = array.index
                y = array.values
                mark.x = x
                mark.y = y
                maxs.append(max(y))
                mins.append(min(y))
        y_limits = self.get_axes_limits(min(mins), max(maxs))
        self.scales["x"].min = start
        self.scales["x"].max = end
        self.scales["y"].min = y_limits[0]
        self.scales["y"].max = y_limits[1]

    def get_marks(self):
        marks = []
        data = self.datafunction()
        for d, c in zip(data, self.colors):
            marks.append(
                bq.Lines(
                    x=[],
                    y=[],
                    icon="line-chart",
                    scales=self.scales,
                    stroke_width=2,
                    fill='bottom',
                    fill_opacities=[0.2],
                    colors=[c],
                    labels=d["labels"],
                    display_legend=True,
                )
            )
        return marks

    def get_axes(self, ylabel):
        font_size = 15
        axx = bq.Axis(
            scale=self.scales["x"],
            grid_lines="solid",
            tick_format="%H:%M:%S",
            tick_style={"font-size": font_size},
        )
        axy = bq.Axis(
            scale=self.scales["y"],
            grid_lines="solid",
            orientation="vertical",
            label=ylabel,
            label_offset="40px",
            tick_style={"font-size": font_size},
        )
        return axx, axy

class UI(ipw.GridBox):
    def __init__(self, timedeltafunction, datafunction):
        super().__init__()
        self.live = True

        self.toggle_button = ipw.Button(
            description="Pause",
            button_style="success",
            tooltip="Press to toggle live update",
            layout=ipw.Layout(
                grid_area="toggle", width="100px", margin="9px 0px 0px 0px"
            ),
        )
        self.toggle_button.on_click(self.toggle)

        self.plot = Plot(
            timedeltafunction, datafunction, 'plot'
        )

        self.children = [
            self.toggle_button,
            self.plot,
        ]

        self.layout = ipw.Layout(
            width="100%",
            height="93vh",
            grid_template_rows="50px 500px",
            grid_template_columns="auto 900px auto",
            grid_template_areas="""
                ". toggle ."
                ". plot ."
                """,
        )

    def toggle(self, *args):
        if self.live:
            self.plot.stop()
            self.live = False
            self.toggle_button.description = "Start"
        elif not self.live:
            self.plot.start()
            self.live = True
            self.toggle_button.description = "Pause"


# -*- coding: utf-8 -*-
"""
Created on Wed Jun 10 03:10:04 2020

@author: mvrcc
Sample code:
    We will calculate the P(A|B) being:
        A: Probability of win after a win streak of 4 (for example)
        B: Probability of a win streak of 4 (for example)

        P(A|B) = P(AꓵB) / P(B)

        P(B) = (# of times with a win streak of 4) / (# of Game)
        P(AꓵB) = (@ of wins after a win streak of 4) / (# of Game)
The number of consecutive wins to obtain the probability is a parameter
entered in the program
Other calculations, following the same structure, can be entered, like
the probability of lose conditioned to a lost streak, for instance.
"""

import pandas as pd

"""
Function to compute the conditional probability
"""

def computeProb(counterWon, counterWS, counterGame):
    pb = counterWS / counterGame
    paib = counterWon / counterGame
    if pb == 0:
        pab = 0
    else:
        pab = paib / pb

    return pab

# Main Module
# Import data
df = pd.read_csv("modifiedWinStreaks - good.csv")

teamNumberS = pd.Series([])
teamNameS = pd.Series([])
counterWonS = pd.Series([])
counterWSS = pd.Series([])
pabS = pd.Series([])

no_integer = True
while no_integer:
    try:
        wsValue = int(
            input("Enter the # of consecutive wins to be used as minimum Win Streak ")
        )
        no_integer = False
    except:
        print("Enter an integer value")

# determine who won Game
teamNumber = df["Team Number"]
teamName = df["Team Name"]
winStreak = df["Numeric Win Streak"]

# Initialize counters for next team
team = -1
counterWS = 0
counterWon = 0
counterGame = 0
j = 0
for i in range(len(df)):
    if teamNumber[i] != team:
        if team != -1:
            # Calculate probabilities
            pab = computeProb(counterWon, counterWS, counterGame)
            # Stores figures for this team
            teamNumberS[j] = team
            teamNameS[j] = teamName[i - 1]
            counterWonS[j] = counterWon
            counterWSS[j] = counterWS
            pabS[j] = pab
            j += 1
            # Initialize counters for next team
            counterWS = 0
            counterWon = 0
            counterGame = 0
        team = teamNumber[i]
    if winStreak[i] >= wsValue:
        counterWS += 1
        if winStreak[i] > wsValue:
            counterWon += 1
    counterGame += 1

# Stores figures for last team
pab = computeProb(counterWon, counterWS, counterGame)
teamNumberS[j] = team
teamNameS[j] = teamName[i - 1]
counterWonS[j] = counterWon
counterWSS[j] = counterWS
pabS[j] = pab

# Creates the table with statistics per team
dft = pd.DataFrame(
    {
        "Team Number": teamNumberS,
        "Team Name": teamNameS,
        "#Wins WS": counterWonS,
        "#Win Streak": counterWSS,
        "Probability": pabS,
    }
)

print(dft)
dft.to_csv("big10Probability.csv")
print("done")


class Solution:
  def minSwap(self, A: List[int], B: List[int]) -> int:
    keepAt = [math.inf] * len(A)
    swapAt = [math.inf] * len(A)
    keepAt[0] = 0
    swapAt[0] = 1

    for i in range(1, len(A)):
      if A[i] > A[i - 1] and B[i] > B[i - 1]:
        keepAt[i] = keepAt[i - 1]
        swapAt[i] = swapAt[i - 1] + 1
      if A[i] > B[i - 1] and B[i] > A[i - 1]:
        keepAt[i] = min(keepAt[i], swapAt[i - 1])
        swapAt[i] = min(swapAt[i], keepAt[i - 1] + 1)

    return min(keepAt[-1], swapAt[-1])

Leetcode/0801. Minimum Swaps To Make Sequences Increasing/0801.py