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.
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've been trying to work on practice modules in the python crash course book. I'm working on while loops and input functions. I tried running the below code in the terminal but only the second line of code prints.
What rental car would you like?
The full code is below:
while True:
car = input("What rental car would you like?")
print(f'Let me see if I can find you a {car.title()}.')
car += input('Subaru')
break
while True:
table = input("How many people are in your party?")
table = int(table)
if table > 8:
print('My apologies, you will have to wait for a table.')
else:
print('Your table is ready!')
break
I tried breaking the loops apart to get the rest to print in the terminal but I'm not sure where I'm messing up. I don't get any errors, it just only prints one line of code out of the entire thing.
It is waiting for your input. After you write something and hit enter it will proceed.
I did not quite understand the first while loop, but for the second one the problem is with the indentation of the break statement
I'm making a coin flip game that asks the user "Heads or Tails", and after the user chooses one of the two, it will respond back saying either "correct" or "wrong". When I run my code, it works perfectly fine if I keep repeating either heads or tails. But if I switch it up like something like heads, heads, tails . It won't ask me the question "Heads or Tails" anymore. And what's weird is sometimes after switching it up it will ask but then eventually it stops. This is my code:
import random
coin=["CORRECT!", "WRONG!"]
hot=raw_input("Heads or Tails? \n")
while hot == "heads":
if hot=="heads":
for i in range(1):
print random.choice(coin)
hot=raw_input("Heads or Tails? \n")
while hot =="tails":
if hot=="tails":
for i in range(1):
print random.choice(coin)
hot=raw_input("Heads or Tails? \n")
And then this right here is the problem I'm talking about when I run it
Heads or Tails?
heads
CORRECT!
Heads or Tails?
tails
CORRECT!
Heads or Tails?
tails
WRONG!
Heads or Tails?
heads
After that last heads I put it doesn't say correct or wrong, and sometimes it doesn't show it even earlier when I run it.
You can try implementing the same using:
hot = raw_input('Heads or Tails?\n')
while hot != 'quit':
if hot == random.choice(['heads', 'tails']):
print 'Correct!'
hot = raw_input('Heads or Tails?\n')
else:
print 'Wrong!'
hot = raw_input('Heads or Tails?\n')
This allows the user to continue flipping the coin until the user enters 'quit'.
It isn't strange that your program stops after you stop responding "tails". This is because of basic control flow. You've used five types of control flow in your program.
First, unless told otherwise, control will flow from one statement to the next. So import random happens first, then the assignment of coin, and so on.
Second, you've used function calls such as raw_input() and random.choice(). These run other subprograms, which we don't need to consider very deeply here since all of them return to your main program.
Third came two while loop constructs. These contain some section of code they repeat as long as their condition is satisfied; crucially, they therefore end when it is not. So the first loop actually ends when you respond something other than "heads".
Fourth, you have an if statement within each loop. This runs its contents if a condition is satisfied, just like while, but doesn't repeat. Since the condition you used is exactly the same as the surrounding while, these checks are redundant; we wouldn't be executing this part of the program if the condition wasn't met.
Fifth you used a for statement; these make loops, like while, but process every entry of some iterable. In this case, that served no purpose because there is only one entry in range(1) and you never actually used it. Like the if, it is redundant.
Having deciphered these, we see the control flow moves from "heads" loop to "tails" loop then simply ends, having run out of program. To keep the program running we must have a loop that does not end, for instance:
while True:
if hot=="heads":
for i in range(1):
print random.choice(coin)
hot=raw_input("Heads or Tails? \n")
if hot=="tails":
for i in range(1):
print random.choice(coin)
hot=raw_input("Heads or Tails? \n")
This loop exhibits another issue, namely that nothing checks that the answer entered was either heads or tails. It will therefore get stuck running nothing if we give another answer. You can solve this by ensuring we ask for a guess in every iteration, and for some extra flair, even respond to invalid guesses using else:
while True:
hot=raw_input("Heads or Tails? \n")
if hot=="heads":
for i in range(1):
print random.choice(coin)
elif hot=="tails":
for i in range(1):
print random.choice(coin)
else:
print "I don't know what side of a coin that is."
Note that I moved the raw_input call outside of the conditional sections. Since it was equal for all branches, it doesn't need duplication. I also used elif and else to tie together the conditional sections, ensuring only one of them will run for any iteration (each time through the loop). And about duplication, your two conditionals perform the exact same operation! You've taken a shortcut and not actually calculated which side the coin landed on - only used its odds of success. Let's fix that too.
sides = ("heads", "tails")
while True:
hot = raw_input("Heads or Tails? \n")
if hot in sides:
toss = random.choice(sides)
if hot == toss:
print "Correct"
else:
print "Incorrect"
else:
print "I don't know what side of a coin that is."
Note that there are two if statements on different levels this time, each with their own else. These are independent, aside from the fact that the inner one only runs if the outer condition was true. All sorts of control flow statements (ending in :) can be nested this way.
The second rule for If-Statements here, which has me confused states that:
If this else should never run because it doesn't make sense, then you must use a die function in the else that prints out an error message and dies, just like we did in the last exercise. This will find many errors.
Here's the code from the last exercise:
def dead(why):
print why, "Good job!"
exit(0)
def start():
print "You are in a dark room."
print "There is a door to your right and left."
print "Which one do you take?"
choice = raw_input("> ")
if choice == ‘left’:
bear_room()
else:
dead(‘You stumble around the room until you starve.’)
Is it essentially saying that you must successfully terminate the program if a condition is not met?
Yes, the idea is:
import sys
def die(msg):
print msg
sys.exit(1)
if condition:
# do stuff
else:
die('This cannot happen!')
You could also use an assert instead, or raise an exception, or anything else that would fail catastrophically. This helps you validate at runtime that the clause you didn't expect to execute, really didn't run.
IMHO you shouldn't get too hung up on how this die is done, exactly. The important point the referred text tries to make is that when you're sure some condition is true, you might as well assert it forcefully so that you can catch runtime bugs.
The guide is trying to show you that you can see the choice that a user gives when it's something that you don't check for in your if statement. If your else looks like:
else:
dead(choice)
You will be able to see what the user input that you didn't expect.
The problem is that the syntax only allows for "Left", when the prompt allows entry of anything. In other words, if I enter "Bob", I will starve. I should be trapping for anything that isn't appropriate and "die"ing at that point (or helping the user make an appropriate decision).
This is an attempt at teaching error handling and die. You would rewrite it such that you allow accurate entry or die (no exit). If you don't choose left, there is no other choice even though the prompt states there are two choices.
If you truly expect only 'left' to be added, a better way of checking for unexpeted input would be
if choice != ‘left’:
dead(‘You stumble around the room until you starve.’)
bear_room()
That way you still validate that the input is what you expected, but it saves indentation and space for the main logic.
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.