I'm coding a text adventure in python.
In general: I want people to be able to make mistakes for putting in the wrong answers. If they not write a valid answer like "1" or "2" they should get send back with a loop until they put in a viable answer without breaking the whole code and to start all over again.
As mentioned in the title: I have a problem with consecutive if-query-loops (with elif else etc.) I do found a nice while-function for just one query. (here on stack overflow. THX for that so far)
But trying to implement it for consecutive if-querys leading to the next one is not working.
The first if-query works fine, but after going to the second one, when writing gibberish for example, instead of looping back to the second question I get send to the first(!) one again...
I tried to put "else: -continue..." to every(!) if-query, even with multiple "while True:" after each query.. but that resulting in infinty loops...
I'm a beginner with python, but heard that maybe switch / case -functions might be working?
Still, is there maybe a more efficient way?
Thanks a lot for your time and effort! :-)
while True:
question1 = input("question1")
if question1 =="1":
print("Wrong")
break
elif question1 == "2":
print("Right, go on!!")
question2 = input("question2")
if question2 == "1":
print("Wrong")
break
elif question2 == "2":
print("Right, go on!!")
question3 = input("question3")
if question3 == "1":
print("wrong")
break
elif question3 == "2":
print("Right, go on!!")
quit()
else:
print("Use a valid answer!")
continue
Here's an idea of how I'd structure your program and what things you should look at and learn to properly implement what you want to do.
I'd recommend you use a state machine and putting all your logic into a dictionary (which later you could read from a json file, so you can create different adventures without having to modify the code at all)
The logic of your adventure is:
You are in question 1 and you have 3 possible answers:
1 -> Correct: Go to next question
2 -> Incorrect: Go back to first question
Anything else -> Repeat current question
Then you can mount each question with a nested dictionary structure, like this:
states = {
1: {
"Question": "The text of question 1",
"Answers": {
"1": 2, # Answer "1" will go to state 2
"2": 1, # Answer "2" will go to state 1
"Default": 1 # Anything else will stay in state 1
}
},
2: {
"Question": "The text of question 2",
"Answers": {
"2": 3, # Answer "2" will go to state 3
"1": 1, # Answer "1" will go to state 1
"Default": 2 # Anything else will stay in state 2
}
}
}
You can add more options to your dictionary, maybe you want the user to allow more answer for each question, and you can then put to which state each answer goes (maybe you don't want sequential questions, but more a graph with complex paths)
Now your main code will have a variable state that you can initialize to 1
state = 1
You can then access the information of this state by doing
states[state]
For example the question of the current state is
states[state]["Question"]
And the answers dictionary are in
states[state]["Answers"]
So if the user inputs an answer answer, you can get the appropriate response doing
states[state]["Answers"][answer]
This might look a bit complicated now for you, but try understanding dictionaries and how to structure your question and answers in them and you will see that your code then simplifies a lot, you just need to print the Question for the current state, read the answer and update the state according to the dictionary.
so you want something like
state = 1
while True:
# print current question
print(states[state]["Question"])
# ask the user an answer
answer = input("What is your answer? ")
# check if answer exist for the current state
if answer in states[state]["Answers"].keys():
# if it exist go to the state pointed by that answer
state = states[state]["Answers"][answer]
else:
# if it doesn't exist, go to the state pointed by default
state = states[state]["Answers"]["Default"]
You maybe want a final state that gives you a victory, so you can get a special state that when reached will print "You won" and exit the game
Try to understand the logic of this program and you will find that a combination of state machines and dictionaries will make your code very flexible and very easy to understand.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I found a problem which I cannot solve on my own and when I did my research - answers are not unanimous.
Consider the following python code:
rooms = {1: 'Foyer', 2: 'Conference Room'}
room = input('Enter the room number: ')
if not room in rooms:
print('Room does not exist.')
else:
print("The room name is " + rooms[room])
The program fails to find the rooms, but when we convert room variable into int (like below) program works fine.
rooms = {1: 'Foyer', 2: 'Conference Room'}
room = int(input('Enter the room number: '))
if not room in rooms:
print('Room does not exist.')
else:
print("The room name is " + rooms[room])
A lot of people says the problem is invalid syntax, but in my opinion it's more like mistmatched data type. I don't get any errors in that code. My question is why do most people think this is invalid syntax. What do you think?
You're correct and the ones who told you it was a syntax error, it isn't. It is exactly the "mismatched data type" since the keys on the variable "rooms" are integers, but the user input or the variable "room" is specifically not an integer or a number. In other words, the user input returns a string and the "rooms" variable keys are integers which create a mismatched data type when matched together by an if statement and can probably cause confusion. To prevent this, make sure to see if both values that you're gonna be comparing are the same data types.
I agree with wondercricket...no error handling. rather than converting to int in the original input, if you move it further down, you could use it to handle the usecase of a string (invalid) input...
rooms = {1: 'Foyer', 2: 'Conference Room'}
room = input('Enter the room number: ')
try:
if int(room) in rooms:
print("The room name is " + rooms[int(room)])
else:
print("could not find a room based on the number you entered...please try again")
except:
print('Please enter the room number as a number')
I have a list of tuples, holding information about people (one for each tuple, with things like (name, age, etc.)). I want to check the list to see whether any names match a user input. My problem is if I use a for loop I then get multiple lines returning false, rather than just one. I also cannot then ask the user to try again, until success. My current code is:
last_name = input("Please input person's last name")
for person in personList:
if person[0] == last_name.capitalize():
print("success")
else:
print("fail")
This will print out "fail" for each player, rather than just once, and will not prompt a user to try again. I know a while loop would enable multiple attempts but I can't see how to link the while with the for, and still output a "fail" only once.
As I'm trying to learn more about tuples, please don't suggest using objects. I know it would make a lot more sense but it doesn't help me understand tuples.
You need two modifications: a way to stop the loop if you find a match, and a way to print 'fail' only if you found no matches in the entire list.
You can get the first modification by adding a break in the if statement, and you can get the second one by adding an else clause to the for loop, which means "run this code if the loop ran to its full completion".
for person in personList:
if person[0] == last_name.capitalize():
print("success")
break
else:
print("fail")
You could simplify checking if user input value is in personList to one line like so and then check whether input matched at least once and if it did print 'success' and break loop, else print 'fail' and ask user again.
personList = [('Abc', 'Cba'), ('Xyz', 'Zyx')]
while True:
last_name = input("Please input person's last name: ").capitalize()
if any(last_name == i[0] for i in personList):
print("success")
break
else:
print("fail")
Output:
Please input person's last name: random
fail
Please input person's last name: xyz
success
So first of all lets understand whats happening.
For each person in the tuple you ask if his name is X.
So accordingly each person will answer you: "No", until you get to the right person, and only that person will say: "Yes", and even further, unless he is the last one it will go on until the very end.
In conclusion, you're asking every single tuple to say whether it matches the user input, or not.
But there is also an easy way of fixing this. So what can we do instead?
We will just collect every answer, and then check whether our input exists in the collection.
Lets write down in code:
total_collection = []
for person in personList:
if person[0] == last_name.capitalize():
total_collection.append("1")
else:
total_collection.append("0")
if "1" in total_collection:
print("Success!")
else:
print("Fail...")
In this code, the string "1" represents a match, and the string "0" represents no-match.
Also, this way you can say at which index the match/es was/were located.
Yes I know that there is already a post covering this, but when I read it, it didn't help so please don't mark this as a duplicate.
I want to write a program that asks the user if they want advice and if they input "No" or "no" I want it to repeat the question and if they input "Yes" or "yes" I want it to print the advice. I want it to include a while loop
I have tried to write it myself but I can't get it to work correctly.
Anyone know?
Code from the comment for 3.4 -
def doQuestion(question, advice):
reply = ("no")
while reply == "no":
print (question)
reply = input("Do you need some advice? ").lower()
if (reply == "yes"):
print ("Always listen to your IT teachers")
doQuestion("Do you want some advice?","Always listen to your IT teachers")
The following will keep on checking up on the user to see whether or not they need advice regarding a question:
def doTheyNeedAdvice(advice):
while raw_input("Do you need advice? ").lower() == "no":
pass
print (advice)
print "How old am I?"
doTheyNeedAdvice("I am old enough")
Am trying to create a quiz program in Python where the questions are stored in one txt file with the answers in another. The questions are set out in the text file as follows:
Which one of these is a percussion instrument?
A. Trumpet
B. Euphonium
C. Viola
D. Glockenspiel
The program pulls the questions out in random order and keeps score of the number of right answers.
I know how to open files, read from them and display the contents of the file on the screen, I even know now how to randomise the info in the file. However, as there are multiple lines involved AND another file to get the answer from, I have no idea where to start.
I would really appreciate any help you could offer me.
Feel free to ask questions if you need to clarify anything.
EDIT:
Ok, I have decided to change my idea a little, which might make it easier. Using a CSV file might be the better option. Here is what I have so far.
def Trivia():
score=0
myFile = open("farming.csv","r") # opens the CSV file and stores it in the array myFile
players = myFile.readlines() # reads the lines of the CSV file into the variable players
questionno=1
while questionno < 6:
for p in players:
data = p.split(",") #splits each cell of the CSV file into its parts
questions = data[0]
answera = data[1]
answerb = data[2]
answerc = data[3]
CorrectAnswer = data[4]
print("Question #",questionno)
print(questions) #prints the question and the 3 answers
time.sleep(0.5)
print(answera)
time.sleep(0.5)
print(answerb)
time.sleep(0.5)
print(answerc)
time.sleep(0.5)
answer = input("Answer? ") #asks the user for their answer
time.sleep(1)
print(".")
time.sleep(1)
print(".")
time.sleep(1)
print(".")
if answer == CorrectAnswer: #checks if the answer is correct and prints approptiate responses
print("That is the correct answer")
score=score+1
time.sleep(1)
else:
print("That is not the correct answer")
time.sleep(1)
print("Your current score is", score)
print("")
questionno = questionno+1
myFile.close()
My problem now is that I don't know how to get to the next question in the quiz. Using this format it keeps asking the same question. Any idea?
Thanks.
This question is two-fold: what to save, and how to save. Let's answer "how" first.
Seems like what you need is serialization, which is a fancy way of saying "saving data in a particular format". I would learn about pickle or json. This will allow you to save and load objects, so you could for instance save a class that represents a question.
And about what you save and not how you save it, I guess each answer should be saved along with a number of a question, then you can link between them - sort of like foreign keys in a DB.
Good luck!
I am not exactly 100 percent sure as yet I haven't run the program myself to check. But I think it could be the "While" module. It says while questionno is under six, do that question, and so when you add 1 to questionno it is still under 6 running the program over again. Change it too this
If questionno == 1:
.....
.....
.....
for next question in the quiz you'll need to just start it with
If questionno == 2:
.....
.....
.....
now write the 2nd quiz
I apologize for my earlier questions as they were vague and difficult to answer. I am still fairly new to programming and am still learning the ins and outs of it all. So please bear with me. Now to the background information. I am using python 3.3.0. I have it loaded onto the Eclipse IDE and that is what I am using to write the code and test it in.
Now to the question: I am trying to learn how to create and use dictionaries. As such my assignment is to create a price matching code that through user interface will not only be able to search through a dictionary for the items (which are the keys and the locations and prices which are the values associated with the keys.) So far I have created a user interface that will run through well enough without any errors however (at least within the IDE) When I run through and input all of the prompts the empty dictionary is not updated and as such I cannot then make a call into the dictionary for the earlier input.
I have the code I have written so far below, and would like if someone could tell me if I am doing things correctly. And if there are any better ways of going about this. I am still learning so more detailed explanations around code jargon would be useful.
print("let's Price match")
decition = input("Are you adding to the price match list?")
if decition == "yes":
pricematchlist = {"Snapple":["Tops",99]}
location = input("Now tell me where you shopped")
item = input("Now what was the item")
price = input("Now how much was the item")
int(price)
pricematchlist[item]=location,price
print(pricematchlist)
else:
pricematchlist = {"Snapple":["Tops",99]}
reply = input("Ok so you want to search up a previous price?")
if reply == "yes":
search = input("What was the item?")
pricematchlist.item(search)
These are a few minor changes. For dictionaries: you are using them correctly.
print("let's Price match")
pricemathlist = {"Snapple":["Tops", 99]} # assign it here
decition = input("Are you adding to the price match list?").lower() #"Yes"-->"yes"
if decition == "yes":
# pricematchlist = {"Snapple":["Tops",99]}
# If this whole code block is called repeatedly, you don't want to reassign it
location = input("Now tell me where you shopped")
item = input("Now what was the item")
price = int(input("Now how much was the item"))
# int(price) does nothing with reassigning price
pricematchlist[item]=location,price
print(pricematchlist)
else:
reply = input("Ok so you want to search up a previous price?").lower()
if reply == "yes":
search = input("What was the item?")
print pricematchlist[search] # easier way of accessing a value