Y a-t-il un moyen de faire en sorte que cela fonctionne, ou vais-je devoir trouver une autre logique? J'ai écrit ceci très rapidement pour illustrer le problème que je rencontre. Chaque fois que la fonction de devinette s'exécute, j'aimerais ajouter une estimation. Le problème est que lorsque je quitte la fonction, puis que je rentre, le compteur de suppositions se réinitialise à 0. Et je ne peux pas avoir la variable "devine" en dehors de la fonction définie, ce qui m'a étonné.
Qu'est-ce qui la bonne façon de faire?
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()
Je voudrais pouvoir quitter une fonction et la ressaisir sans réinitialiser la variable de suppositions.
p >
3 Réponses :
J'aime la programmation orientée objet (POO), donc j'irais avec l'autre réponse.
Cela étant dit si vous le souhaitez, Python a quelque chose d'utile pour cela appelé un générateur . Pensez-y comme une fonction qui se souvient de l'état.
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()
Aussi pour expliquer comment un générateur s'arrête:
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")
Votre code:
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
Vous avez raison, l'autre réponse est plus simple. Mais merci de me montrer ça aussi! J'ai appris quelque chose de nouveau. Très nouveau dans ce domaine, donc c'est génial de voir à quel point vous êtes utiles :)
Une façon courante de gérer ce problème est d'encapsuler vos informations dans l'instance d'une classe. L'instance contiendra des propriétés telles que le nombre de suppositions et tout autre état que vous souhaitez conserver. Les méthodes créeront le comportement qui inclut la manipulation de ces propriétés.
Ici, vous pouvez créer une nouvelle instance, y compris la possibilité de transmettre le nombre initial de suppositions et la réponse:
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
J'allais faire un commentaire dans mon message mais le self.movement () semble être une récursion inutile et consomme juste la pile sans raison particulière.
Ouais, je suis d'accord avec ça @ Error-SyntacticalRemorse, je pensais plus à la question du maintien de l'état, mais cela pourrait certainement être remanié pour se débarrasser de l'appel récursif.
C'est exactement ce dont j'avais besoin. Merci!! J'ai commencé à coder il y a 2 jours et je suis maintenant époustouflé par l'utilité de cette communauté pour l'apprentissage. Wow. C'est très encourageant. Merci :)
Ça a l'air plutôt bien pendant deux jours @ChrisE! Bonne chance pour aller de l'avant.
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()
Le but est de quitter et de rentrer une fonction sans redéfinir la variable x. Combiner tout cela en une seule fonction «fonctionne», ici, mais le but était de trouver un moyen de se déplacer entre les fonctions. Si vous codez une séquence complexe d'événements, vous n'allez pas avoir toute l'histoire dans une seule fonction ...
Une solution simple mais "sale" est de déclarer les
suppositionsglobales. Une meilleure solution consiste à passersupposecomme paramètre à la fonction et à renvoyer sa nouvelle valeur.Une troisième solution consiste à créer un objet porteur d'état; par exemple. un seul jeu peut être encapsulé dans une classe
Game, qui sait comment accepter une supposition, suivre un mouvement ou se souvenir des suppositions. Vous allez créer un seul objet de cette classe, et l'objet sera implicitement transmis à toutes les méthodes en tant queself, sans que vous ayez à le jongler.Python a quelque chose pour cela appelé un générateur. Je peux vous donner un exemple dans une seconde.