This question already has answers here:
How to repeat a section of the program until the input is correct?
(3 answers)
Closed 5 years ago.
I am trying to learn Python. I just made a simple rock, paper, scissors game for practice. I am having a small problem.
When each player choose the same item, the game ends in a tie.
When the player makes a mistake and has to choose again, the variable is empty. Notice that Player 1 says "none".
This is the method. The problem occurs in the else branch.
def play1():
player1_choice = input("Player 1 - Go: ")
if (check(player1_choice)):
return player1_choice
else:
print(error_msg)
play1() # Something is wrong here.
What did I do wrong? How can I fix it? Thanks
Don't use recursion if you don't have to. Try this:
def play1():
while True:
player1_choice = input("Player 1 - Go: ")
if (check(player1_choice)):
return player1_choice
else:
print(error_msg)
This is a classic while loop application; you want to loop until you get a reasonable answer (while the known answer is unacceptable), returning that answer to the calling program.
Use a for loop when you know as you enter the loop how many times you have to repeat it.
Recursion is proper when you have a job in which you can:
do something simple;
reduce the remaining task to something smaller, closer to a trivial "completed" state;
pass that smaller task to the same function for further processing.
In this application, getting a wrong answer from the user doesn't put you any closer to a solution (a valid answer) than when you started. The task isn't any simpler now. Further processing is the same, but you get that just as well with an iteration loop.
Related
I am making a small text-based game in Python. It involves many inputs and so to avoid bugs, there are a few things I have to check every time an input exists. Naturally, to speed up the process I wanted to put the code into a def in order to simplify the writing process. When I put the code in the def, it red underlines the continue and break commands (meaning they are incorrect), and if you run the code using the def name, a Traceback occurs. I have tried putting the def section at the beginning of the program, after the while True: (The program is supposed to run infinitely until a certain action is taken that breaks the loop) I have also made sure to try putting it under any variables referenced and in the loop so that no part of it is not defined and so that everything would work if I were to just put the code in there.
Here is the code I am trying to put into a def.
def input_bugs():
if letter_one.lower() == "done" and total_count == 0:
print("You have to play at least one game!")
continue
elif letter_one.lower() == "done":
break
elif len(letter_one) > 1:
print("Sorry, you gotta pick a single letter, no more. Otherwise, type 'done' to end the game and see your stats.")
continue
Here is the Traceback I get every time I try to run it.
line 20
continue
^^^^^^^^
SyntaxError: 'continue' not properly in loop
At this point, I don't even care if I have to write it out every time, I can just copy and paste. I am simply curious as to why it doesn't work so that I know in the future. In case you could not tell, I am pretty new to programming so I want to learn from any mistake I make. Also sorry if I referred to some things in the wrong way. Hopefully, you understood what I meant.
I would like to know why this code does not work; it should exit at the "GAME OVER" point, but it continues to my next defined function.
I have tried other variations on exit() such as: sys.exit(), quit() and SystemExit.
run_attack = input("What do you do: Run/Attack\n")
run = ['run', 'Run', 'RUN']
attack = ['attack', 'Attack', 'ATTACK']
run_attack = 1
while run_attack < 10:
if run_attack == ("run") or ("Run") or ("RUN"):
print ("You turn to run from the wolf but he quickly pounces
you...")
time.sleep(2)
print("You are quickly ripped apart and just about get to see
yourself be eaten.")
print("GAME OVER")
break
exit() #This is where the game should exit, yet after input it
continues to the next function
elif run_attack == ("attack") or ("Attack") or ("ATTACK"):
print("You brace yourself for a bite and have no time to reach"
"for any kind of weapon form your backpack.")
time.sleep("2")
input("You clock the dog hard, twice on the muzzle.")
print("The dog recoils in pain and retreats back to the woods.")
print("You quickly start running as you assume there will be a den in the woods.")
break
else:
input("Type Run or Attack...")
You have several problems in your code; why did you write this much without testing it?
First, you read the user's input, immediately replace is with 1, and then try to test it (incorrectly) as if it were still a string. Your posted code has several syntax errors, so I have some trouble reproducing the problem. However, the immediately obvious problem is here:
break
exit() # This is where ...
You can't get to the exit statement, as you break from the loop just before you can get there.
I strongly recommend that you back up to a few lines and use incremental programming: write a few lines at a time, debug those, and don't continue until they do what you want.
Also look up how to test a variable against various values. Your if statement is incorrect. Instead, try the list inclusion you're trying to set up:
if run_attack in run:
...
elif run_attack in attack:
...
I took the liberty of rewriting your whole program to show you a few things wrong with it and a few tricks. I've done it without the loop, since you never use it anyway... you can add the while loop later once you've mastered it, but you should really go back to basics on some things here:
run_attack = input("What do you do: Run/Attack\n")
if run_attack.lower() == "run":
print("""some
stuff
with
multiple
lines and GAME OVER""")
exit()
elif run_attack in ("attack", "Attack", "ATTACK"):
print("""some
stuff
with
multiple
lines""")
else:
input("Type Run or Attack...")
Some notes:
Using """ for strings enables you to write multiple lines without multiple print statements
Using str.lower() on strings makes everything easy to compare because you only have to compare it to the lowercase version of each string. However for attack you can notice I used a different inclusion test, without multiple conditions. Either way works here.
Like the other answer here (and many comments), you should use only exit() to leave the program entirely, or only break to exit the loop and continue to other code that's beneath the entire loop.
When you rewrite your loop, with a condition like while number_of_turns < 10 don't forget to add 1 to the number of turns on each loop, otherwise that condition is always True and you'll have an infinite loop...
I'm actually quite surprised this code had any resemblance to the behavior you expected from it, my suggestion is to go back over to the basics of python, learn loops, string methods, basic commands. The rest is already said in the other answer here (which is better than mine, frankly) just wanted to add some ideas.
This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed 6 years ago.
Question1 = input("We will start off simple, what is your name?")
if len(Question1) > 0 and Question1.isalpha(): #checks if the user input contains characters and is in the alphabet, not numbers.
Question2 = input("Ah! Lovely name, %s. Not surprised you get all the women, or is it men?" % Question1)
if Question2.lower() in m: #checks if the user input is in the variable m
print ("So, your name is %s and you enjoy the pleasure of %s! I bet you didnt see that coming." % (Question1, Question2))
elif Question2.lower() in w: # checks if the user input is in the variable w
print ("So, your name is %s and you enjoy the pleasure of %s! I bet you didnt see that coming." % (Question1, Question2))
else: #if neither of the statements are true (incorrect answer)
print ("Come on! You're helpless. I asked you a simple question with 2 very destinctive answers. Restart!")
else:
print ("Come on, enter your accurate information before proceeding! Restart me!") #if the first question is entered wrong (not a name)
Question3 = input("Now I know your name and what gender attracts you. One more question and I will know everything about you... Shall we continue?")
In order to get the right answer, I will first tell you what happens when I run it:
There are several scenarios but I will walk you through 2. When I run the program I am first asked what my name is, I can enter anything here that is alphabetic, then it asks me if I like men or woman, weird I know but it's a project I am working on, if I were to say 'men' or 'women' the program runs perfectly, but if I were to enter say... 'dogs' it would follow the else statement print ("Come on! You're helpless. I asked you a simple question with 2 very destinctive answers. Restart!") but then it continues the code and goes to the last line shown above "Now I know your name and what gender attract you...... blah blah". What I am trying to do is have it restart the script if you were to enter anything other than 'men' or 'women'.
I was told that a while statement would work, but I would need an explanation as to why and how... I'm new to Python in a sense.
That's what loops are for.
while True:
# your input and all that here
if answer == "man" or answer == "woman":
# do what you want if the answer is correct
break # this is important, as it breaks the infinite `while True` loop
else:
# do whatever you want to do here :)
continue
If you want the script to repeat indefinitely, you can simply wrap everything in a while loop like so:
while True:
# Do yo your logic here.
# Break out when a condition is met.
If you want to be more savvy with it you can use a method and have the method call itself over and over until it's done.
def ask_questions():
# Do your logic here
if INPUT_NOT_VALID:
ask_questions()
else:
# Continue on.
Also, search on this site for you text because I've seen about five or six questions all involving this programming scenario which means it has to be a common problem from a programming class (one I'm assuming you are in). If that's the case discuss with classmates and try to stimulate each other to find the solution instead of just posting online for an answer.
I have a piece of coding that is most basically a quiz. I had error handling so that if someone pressed a letter or anything other than a number, it would carry on with the quiz instead of letting the person attempt another question. (For example, if question 5 was 2+3 and they entered t, then it would carry on and not give them a different question for question 5).
I tried to update the coding, so it would loop:
def random_question():#defines function to get random question
count = 0#equates count to 0
for number in range (0,10):#makes the code generate the question 10 times
try:#the code makes it so the computer tries one thing and is the beggining
questionList = [random_sum,random_subtraction,random_times]#puts functions in a list to be called on
randomQuestion = random.choice(questionList)#calls on the list to generate the random questions
randomQuestion()#calls on variable
except ValueError:#if there is a value error or a type error it will notice it and try to stop it
print ("Please enter a number")#prints out the statement if there is a type error or a value error
else:
break
random_question()#calls on the function random_question
However, it comes up with a syntax error, and highlights the 'except' part next to the ValueError.
Any help as to why this is would be much appreciated.
Your except statement should have the same indention as your try statement. In your sample code it is indented an extra tab which would cause that error.
Python takes indention seriously and it is often the culprit. I'm unclear if your def line is a place holder or if this code is part of it, but if this code is part of the function definition you have other indention issues to worry about.
I'd suggest going through it carefully and making sure everything is lined up properly. The basic rule of thumb is, if something is part of something else, it is indented under it.
def something():
step 1
step 2
if (condition):
the true thing
else:
the false thing
while (something):
repeat something
this is not part of the function anymore
1.I'm using break to break out of a loop, but I don't know how to make the program keep going no matter what unless this happens. Just typing in while: is invalid (or so the progam tells me) and I want the game to keep going even if the user types in an emptry string.
2.Is there a way to not have to re-type a bit of code every time I need it? I have a bunch of responses for the program to spit out that I'll have to use many times:
if action[0]=='go':
print("You're supposed to go to David!")
elif action[0]=='look':
print("You can't see that")
elif action[0]=='take':
print("You don't see the point in taking that.")
else:
print("I don't recognise that command")
Where action is a list from the player's input. Or do I just have to type it out again each time?
I don't know how to define a function that does the above, and I'm not even sure that's what I'm supposed to do.
3.Some story descriptions I'm using are a very long stings and I don’t want players to have to scroll sideways too much. But I want to just define them as variables to save myself some typing. Is there a way around this. Or do I just have to type it out every time with
print(“““a string here”””)
4.If the string starts with 'look' and has 'floor' or 'mess' or 'rubbish' in it, I want it to print a certain output. This is what I currently have:
if action[0]=='look':
if 'floor' in action or 'rubbish' in action or 'trash' or 'mess' in action:
print('onec')
elif 'screen' in action or 'computer' in action or 'monitor' in action:
print('oned')
elif 'around' in action or 'room' in action or 'apartment' in action:
print('onee')
elif 'david' in action or 'tyler' in action or 'boy' in action or 'brat' in action or 'youth' in action:
print('onef')
break
else:
print("You can't see that")
It prints 'onec' for any input beginning with 'look'.
The while statement requires a condition.
You can call the same instructions over and over using a function.
"String literals can span multiple lines in several ways"
Use strategically-placed print statements to show the value of action, e.g. after if action[0]=='look'
Lastly, please don't add any more items to this question. Rather ask a new question. This site has somewhat specific rules on that sort of thing.
To make an infinite While loop, use while True:.
You could use a dict to store common action strings and their responses.
Just register the string first, then when the input come, change it:
command = "nothing"
command = input("Enter command: ")
while command:
Or just simply:
while True:
Yes, think about it by yourself.. Okay, why not put it in list responses?
If it is really long, put it in a file. Read it when you need it using open(). More on File Processing
This will help you shorten your code, making it easier to read, and makes it more efficient.
while requires a condition that it has to evaluate. If you want it to loop forever, just give it a condition that always evaluates to True, such as 4>3. It would be best for everyone if you just used while True:, which is the clearest option.
For this specific case, I would recommend using a dict() and its .get() method. Something like this:
action_dict = {'go':"You're supposed to go to David!",
'look':"You can't see that",
'take':"You don't see the point in taking that."
}
print(action_dict.get(action[0], "I don't recognise that command")
would replicate what you have going on right now.
See the link provided by cjrh here: http://docs.python.org/3.3/tutorial/introduction.html#strings
Our mind-reading powers are a bit off in October, we'll need some more information other than "it does not work" to help you with that.