I am trying to a make a simple game. I will supply of a dictionary of states and capitals and a list of states. Using loops and conditionals, I will ask the user if they want to learn some capitals and supply the list of states. The state gets removed from the list and the user should be prompted again if they want to play, repeatedly until the list is empty. With my code right now the loop piece works, if keeps asking if they want to play and as long as the user keeps saying yes my code works running till the list is empty and the loop. But when I try to add a layer for if the player says no and break the loop its not doing anything. Thanks in advance for help!!
states3 = ["NH", "MA", "MS", "SC", "HI"]
print("Let's test my geography skills!")
def state3(states3):
state_caps = {"NH": "Concord", "HI": "Honolulu", "SC":"Columbia", "MS": "Jackson", "MA":"Boston"}
play = input("Would you like to learn some capitals:")
while play == "Yes" or "yes":
if play == "Yes" or "yes":
print ("The states I know the captials of are:", states3)
yourstate = input("What state do you want to know the capital of: ")
print("The capital of", yourstate, "is", state_caps.get(yourstate, "That is not a vaild choice"), "!")
states3.remove(yourstate)
play = input("Would you like to learn some capitals:")
if len(states3) == 0:
print ("That's it! That's the end of geography skills")
break
state3(states3)
while play == "Yes" or play == "yes":
if play == "Yes" or play == "yes":
print ("The states I know the captials of..")
.....
....
elif play == "no" or "No":
break
Checking for yes/no is problematic. For example, "YES" is not covered in the above code, yet seems a reasonable response. To distinguish between the two choices, do we need to look at the entire word or only the first letter? (string "slicing")
Such reduces the set of applicable responses to the set: y, Y, n, N. Now, if we apply the string.lower() or string.upper() method*, we are down to two choices.
However, consider this even more closely. Is there really only one user-response that interests us? That the game should continue. Thus, any response other than 'yes' could be considered to mean stop looping!
Another question: once the while-condition has been satisfied and the loop starts to run, is it possible for the first if-condition to be anything other than True? Could the latter be removed then?
Instead of merely adding a "layer", let's review the entire game. How's this for a spec[ification]: repeatedly invite the user to choose a state, and then present its capital.
How do we define "repeatedly", or more precisely, how do we end the looping? There are two answers to that question: either all the states have been covered, and/or the user loses interest (the new "layer"). What happens if we use (both of) these to control the while-loop? (NB reversing the logical-statement) Loop if there are states to review and the user consents. Thus, can the last if-condition move 'up' into the while-condition...
Because you are evidently (enjoying) teaching yourself Python, I have left the writing of actual code to your learning experience, but herewith a few items which may increase your satisfaction:-
in the same way that the 'heading print()' is outside the loop, consider where the farewell should be located...
A list with contents is considered True, whereas an empty/emptied list is considered False. Very handy! Thus, you can ask if states3 (ie without the len()).
also consider the upper()/lower() 'trick' when accepting the state's abbreviation-input.
Related
I'm using a series of inputs and if statements to create a text game/ choose your own adventure where input decides what happens next within a function.
I was testing part of a function, and there should be a total of four strings that print with an input prompt, but after the first two it just moves onto the cell after the function. No error message. I'm using Jupyter Notebook with the latest version of Python. Any help appreciated in making the full function run. (Please ignore the goofy text, sorry for errors this is my first question)
start = input('Welcome to Witness Protection, enter HELP if you need help')
def helper():
if start == 'HELP':
answer= input('')
if answer == 'PICK':
answer= input('')
elif answer == 'WALK':
print('')
if answer == 'TRY':
answer= input('')
elif answer == 'WALK AWAY':
print('')
if answer == 'IN':
answer = input('')
elif answer == 'PUT':
print('')
if answer == 'ON':
answer = input('')
elif answer == 'BACK':
print('')
if start == 'HELP':
helper()
I have checked that I am using the right input, changed elifs to ifs nothing else came to mind that could be the issue any help appreciated
It looks like you want another input instead of a print after elif answer == 'WALK':. When you hit if answer == 'TRY' you haven't given them a chance to change the value of answer yet.
Also, you probably want a different kind of structure for your code. When you use if, only the code that is indented after the if and before the elif or else at the same level of indentation will get run. This means that if someone answers PICK, then none of the code below WALK will get run because the elif answer == 'WALK' section never gets entered. You may want to try a while loop with code that checks different variables to determine what to print at each loop (like what room they are in, what items they have, etc.), and then gets a new input from the user at the end of each loop.
Seems you have some mismatch with the nested if's.
you should indent the if's according to the flow of the questions, something like that:
def helper():
if start == 'HELP':
answer= input('Woah. As you are walking to the FBI office, you see a glistening penny on the floor. Something about it looks strange. What do you do? Enter PICK to pick it up or WALK to keep walking')
if answer == 'PICK':
answer= input('You reach down and grasp the penny, and try to pull it. It doesn’t move. Enter TRY to try again or WALK AWAY to walk away')
if answer == 'WALK AWAY':
print('You keep walking until you reach the FBI office. You make your way to the office of your agent, and sit down to wait for them.')
elif answer == 'TRY':
answer= input('The penny clicks out of place and slides along a track between the paving slabs. One of the slabs slides open. Enter IN to climb in or PUT to put the penny back where it was')
if answer == 'IN':
answer = input('A few metres down, you hit the floor, and see the opening above you close up. You find yourself in an ice cavern, surrounded by the bodies of slain ice dwarfs. Enter ON to walk on or BACK to back')
if answer == 'ON':
answer = input('You enter the realm of the evil wizard. He tells you he is thinking of giving up evil and asks you if you would like to join him in taking over the world and establishing a utopia. Enter YES for \'Of course I will join you, let’s do this!\' Enter THINK for \'That’s a big decision, I need some time to think about it\' Enter NO for \'Woah, sorry buddy, I’m just lost, I’m gonna have to bounce\'')
elif answer == 'BACK':
print('You scramble back to the surface and try to forget what just happened. You continue towards FBI HQ, and wait for your agent at their desk')
elif answer == 'PUT':
print('You move the penny back to where it was, and the slab slides back into place. You continue your walk towards the FBI offices, and wait for your agent in front of their desk')
elif answer == 'WALK':
print('You enter the building and make your way to the office of your agent, and sit down to wait for them.')
I thoroughly searched for an answer to my question but couldn't find anything that would explain my results. I truly hope that anyone of you can point me in the right direction.
At the moment I am trying to program a text-based adventure game using Python 3 in order to better understand the language.
While doing so I created a function that should ask the user for input and print a specific statement depending on the users input. In case the users input is invalid the function should then keep asking for input until it is valid.
Unfortunately the function only seems to keep asking for input, without ever executing the if/elif statements within the function. Due to no errors being shown I am currently at a loss as to why this is the case...
print("If You want to start the game, please enter 'start'." + "\n" +
"Otherwise please enter 'quit' in order to quit the game.")
startGame = True
def StartGame_int(answer):
if answer.lower() == "start":
startGame = False
return "Welcome to Vahlderia!"
elif answer.lower() == "quit":
startGame = False
return "Thank You for playing Vahlderia!" + "\n" + "You can now close
the window."
else:
return "Please enter either 'r' to start or 'q' to quit the game."
def StartGame():
answ = input("- ")
StartGame_int(answ)
while startGame == True:
StartGame()
You fell into the scoping trap: you are creating a new variable startGame inside the function that is discarded after you leave it. You would instead need to modify the global one:
def StartGame_int(answer):
global startGame # you need to specify that you want to modify the global var
# not create a same-named var in this scope
# rest of your code
This other SO questions might be of interest:
Python scoping rules
Asking the user for input until they give a valid response
Use of global keyword
and my all time favorite:
How to debug small programs (#1) so you enable yourself to debug your own code.
The last one will help you figure out why your texts that you return are not printed and why the if does not work on 'r' or 'q' and whatever other problems you stumble into. It will also show you that your if are indeed executed ;o)
Other great things to read for your text adventure to avoid other beginner traps:
How to copy or clone a list
How to parse a string to float or int
How to randomly select an item from a list
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.
I am trying to run a script which asks users for their favorite sports teams. This is what I have so far:
print("Who is your favorite sports team: Yankees, Knicks, or Jets?")
if input is "Yankees":
print("Good choice, go Yankees")
elif input is "Knicks":
print("Why...? They are terrible")
elif input is "Jets":
print("They are terrible too...")
else:
print("I have never heard of that team, try another team.")
Whenever I run this script, the last "else" function takes over before the user can input anything.
Also, none of the teams to choose from are defined. Help?
Input is a function that asks user for an answer.
You need to call it and assign the return value to some variable.
Then check that variable, not the input itself.
Note
you probably want raw_input() instead to get the string you want.
Just remember to strip the whitespace.
Your main problem is that you are using is to compare values. As it was discussed in the question here --> String comparison in Python: is vs. ==
You use == when comparing values and is when comparing identities.
You would want to change your code to look like this:
print("Who is your favorite sports team: Yankees, Knicks, or Jets?")
if input == "Yankees":
print("Good choice, go Yankees")
elif input == "Knicks":
print("Why...? They are terrible")
elif input == "Jets":
print("They are terrible too...")
else:
print("I have never heard of that team, try another team.")
However, you may want to consider putting your code into a while loop so that the user is asked the question until thy answer with an accepted answer.
You may also want to consider adding some human error tolerance, by forcing the compared value into lowercase letters. That way as long as the team name is spelled correctly, they comparison will be made accurately.
For example, see the code below:
while True: #This means that the loop will continue until a "break"
answer = input("Who is your favorite sports team: Yankees, Knicks, or Jets? ").lower()
#the .lower() is where the input is made lowercase
if answer == "yankees":
print("Good choice, go Yankees")
break
elif answer == "knicks":
print("Why...? They are terrible")
break
elif answer == "jets":
print("They are terrible too...")
break
else:
print("I have never heard of that team, try another team.")
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.