简体   繁体   中英

What's the correct way to decrease a variable within a function?

Is there a way to make this work, or am I going to have to find a different way of logic? I wrote this really fast as an example of the problem I'm running into. Every time the guess function runs, I'd like to add a guess. The problem is that when I exit the function and then re-enter, the guess counter resets to 0. And I can't have the variable "guesses" outside of the defined function, which is what has me stumped.

What's the right way to do this?

def guess():
    x = 5
    guesses = 0
    while guesses < 5:
        guess = input("Guess: ")
        if guess == x:
            print("You win")
        else:
            print("try again")
            guesses = guesses + 1
            movement()

def movement():
    choice = input("left or guess")
    if choice == "left":
        movement()
    if choice == "guess":
        guess()

movement()

I'd like to be able to leave a function and re-enter without resetting the guesses variable.

A common way to deal with this is to encapsulate your information in the instance of a class. The instance will hold properties such as the number of guesses and any other state you want to maintain. The methods will create the behavior which includes manipulating these properties.

Here you can create a new instance, including the option of passing the initial number of guesses and the answer:

class Guess:
    def __init__(self, answer = 2, guesses = 5): # 2 and 5 are deafaults if nothing is passed in
        self.guesses = guesses
        self.answer = answer

    def guess(self):
        guess = input("Guess: ")
        if guess == self.answer:
            print("you win")
        else:
            self.guesses -= 1
            print(f"You have {self.guesses} left")
            self.movement()

    def movement(self):
        choice = input("left or guess? ")
        if choice == "left":
            self.movement()
        if choice == "guess":
            self.guess()


g = Guess(answer = 5, guesses = 2) # make a new game using the passed in values 
g.movement() # start game

I like OOP (Object Oriented Programming) so I would go with the other answer. That being said if you want, Python has something useful for this called a generator . Think of it as a function that remembers state.

def my_gen():
    x = 0
    while True:
        # Yield acts just like a normal return, the functions stops
        # after returning x.
        yield x
        # Next time the generator is called it will resume
        # right here, add it will remember all the values
        # it previously had (i.e. it remembers the last value for x.
        x += 1
# Note a generator is called differently then a normal function
# then a normal function
g = my_gen()
print(next(g)) # prints 0
print(next(g)) # prints 1
print(next(g)) # prints 2

Also to cover how a generator stops:

def my_gen2():
    x = 2
    while x > 0:
        yield x
        x -= 1
# Note that when a generator function
# has no more yields it will throw a
# StopIteration Exception
g = my_gen2()
print(next(g)) # prints 2
print(next(g)) # prints 1
print(next(g)) # This will cause an StopIteration Exception

# you can get around this either by:
g = my_gen2()
for x in g: # A for loop automatically stops on StopIteration
    print(x)

# Or catch the Exception
try:
    g = my_gen2()
    for _ in range(5): # Just calling next enough times for it to break
        print(next(g))
except StopIteration:
    print("can't call generator any more")

Your Code:

def guess():
    x = 5
    guesses = 0
    num_tries = 1
    while guesses < num_tries:
        guess = input("Guess: ")
        if guess == x:
            print("You win")
            yield 0
        else:
            guesses += 1
        if guesses == num_tries:
            yield 0 # Game over
        else:
            print("Try again")
            yield 1 # Game can continue


# Don't add unneeded recusion.
# Python has a limited stack. Don't consume it
# for something you should do in a loop.
def play():
    g = guess()
    while True:
        choice = input("left or guess: ")
        print(choice)
        if choice == "left":
            continue
        elif choice == "guess":
            try:
                if not next(g):
                    print("Game over")
                    break
            except StopIteration:
                print("Somehow called to many times")
                break
        else:
            print("Invalid Entry")
play()
def guess(guesses = 0,x = 5):
    choice = input("left or guess")
    guesses = guesses + 1
    if choice == "left":
        return guess(guesses=guesses)
    elif choice == "guess":
        guessint  = int(input("Guess(int): "))
        if guessint  == x:
            print("You win")
            print('number:', guesses)
            return guesses
        else:
            print("try again")
            return guess(guesses=guesses)
guess()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM