New to Python, can't find bug
Question: I am new to Python (3rd day) and I was just trying to creat a basic Rock,
Paper, Scissors. I am seeing a bug that I can't locate in the code and was
hoping somebody could help. Here is the output below with the code following:

    
    
    Welcome to Rock, Paper, Scissors!
    Player 1 name?b
    Player 2 name?s
    3
    2
    1
    GO!
    Rock, Paper or Scissors?rock
    b  threw  rock
    s  threw  rock
    Draw! Get Ready!.
    3
    2
    1
    GO!
    Rock, Paper or Scissors?rock
    b  threw  rock
    s  threw  scissors
    b  win.
    Rematch?no
    Goodbye.
    b  win.
    Rematch?
    

# After entering "no" for rematch, it is printing "b win." also asking
"Rematch?" again. Here is the code below:

    
    
    import time
    import random
    picks=["rock","paper","scissors"]
    answers=["yes","no"]
    rock="rock"
    paper="paper"
    scissors="scissors"
    yes="yes"
    no="no"
    invalid=""
    #############################################Defining Functions#########################################################
    def rename1():
        global name1
        while True:
            if name1 is invalid:
                name1 = input("Player 1 name?")
            if name1 is not invalid:
                break
    
    def rename2():
        global name2
        while True:
            if name2 is invalid:
                name2 = input("Player 2 name?")
            if name2 is not invalid:
                break
    
    def rematchinvalid():
        global rematch
        while True:
            if rematch not in answers:
                print("Invalid, try again..")
                rematch = input("Rematch?")
            if rematch in answers:
                break
    
    def Rethrow1():
        global P1
        while True:
            if P1 not in picks:
                 print("Invalid, try again..")
                 P1 = input("Rock, Paper, or Scissors?")
            if P1 in picks:
                break
    
    def start():
        print("3")
        time.sleep(1)
        print("2")
        time.sleep(1)
        print("1")
        time.sleep(1)
        print("GO!")
    
    def RPS():
        global P1
        global P2
        global rematch
        P1 = input("Rock, Paper or Scissors?")
        P2 = random.choice(picks)
        if P1 not in picks:
            Rethrow1()
        battle()
        winner()
    
    def battle():
        print(name1," threw ",P1)
        print(name2," threw ",P2)
    
    def winner():
        global rematch
        if P1 == P2:
            print("Draw! Get Ready!.")
            start()
            RPS()
        if P1 == rock and P2 == scissors:
                print(name1," win.")
        if P1 == rock and P2 == paper:
                print(name2," win.")
        if P1 == scissors and P2 == rock:
                print(name2," win.")
        if P1 == scissors and P2 == paper:
                print(name1," win.")
        if P1 == paper and P2 == rock:
                print(name1," win.")
        if P1 == paper and P2 == scissors:
                print(name2," win.")
        rematch = input("Rematch?")
        if rematch not in answers:
            rematchinvalid()
        replay()
    
    def replay():
        if rematch == yes:
            start()
            RPS()
        if rematch == no:
            print("Goodbye.")
    ################################################Game Start##############################################################
    print("Welcome to Rock, Paper, Scissors!")
    name1 = input("Player 1 name?")
    if name1 is invalid:
        rename1()
    name2 = input("Player 2 name?")
    if name2 is invalid:
        rename2()
    start()
    RPS()
    

Also, if you have any recommendations on how to clean up the code, that would
be appreciated!

Thanks


Answer: Take a look at your function `winner`:

    
    
    def winner():
        global rematch
        if P1 == P2:
            print("Draw! Get Ready!.")
            start()
            RPS()
        if P1 == rock and P2 == scissors:
                print(name1," win.")
        if P1 == rock and P2 == paper:
                print(name2," win.")
        if P1 == scissors and P2 == rock:
                print(name2," win.")
        if P1 == scissors and P2 == paper:
                print(name1," win.")
        if P1 == paper and P2 == rock:
                print(name1," win.")
        if P1 == paper and P2 == scissors:
                print(name2," win.")
        rematch = input("Rematch?")
        if rematch not in answers:
            rematchinvalid()
        replay()
    

When there is a tie, you print _Draw! Get Ready!._ , call `start()`, call
`RPS()`, then what? Then, instead of exiting the function, you let the control
flowed right into the code below, which displayed the winner name one more
time, then asked for rematch one more time before exiting the function. I
leave it up to you to fix it.

As for recommendation: please do not use global variables.

# Update

Here is some suggestion to eliminate global variables: pass information into
functions and return information from function. For example, here is a way to
eliminate the global variable `rematch`. This variable is first used in
`winner()` and then passed to `replay()`. Also, `rematchinvalid()` get the
user's input into this variable and pass it back to `winner`, so the
information flow for rematch is:

    
    
    rematchinvalid <==> winner ==> replay
    

With that in mind, we can fix `rematchinvalid()` as such:

    
    
    def rematchinvalid(rematch):
        # Remove the global statement here
        while True:
            if rematch not in answers:
                print("Invalid, try again..")
                rematch = input("Rematch?")
            if rematch in answers:
                break
        return rematch  # Return rematch to the caller
    

As for `winner()`, we will receive information from `rematchinvalid()` and
pass it on to `replay()`:

    
    
    def winner():
        # Remove global statement
        if P1 == P2:
            print("Draw! Get Ready!.")
            start()
            RPS()
            return  # Fix for your problem
        if P1 == rock and P2 == scissors:
                print(name1," win.")
        if P1 == rock and P2 == paper:
                print(name2," win.")
        if P1 == scissors and P2 == rock:
                print(name2," win.")
        if P1 == scissors and P2 == paper:
                print(name1," win.")
        if P1 == paper and P2 == rock:
                print(name1," win.")
        if P1 == paper and P2 == scissors:
                print(name2," win.")
        rematch = input("Rematch?")
        if rematch not in answers:
            rematch = rematchinvalid(rematch)  # Get the valid rematch
        replay(rematch)  # Pass rematch to replay
    

Finally, for replay, we can accept `rematch` as a parameter:

    
    
    def replay(rematch):
        if rematch == yes:
            start()
            RPS()
        if rematch == no:
            print("Goodbye.")
    

That should take care of `rematch`. You can apply this method to eliminate
other variables as well.

