validating correct answer with loops in python - python

Sorry for the non descriptive question I had no idea how to word it.
I'm trying to write a program (GUI) where I ask the users questions and then in return they answer and see if they are correct however when I enter the correct answer it's still showing as being incorrect.
My code looks something like this.
prompt for question 1
txtQuestion = Text(Point(5,8), "Question 1")
txtQuestion.setTextColor("red")
txtQuestion.setSize(16)
txtQuestion.setStyle("bold")
txtQuestion.draw(win)
txtAnswer = Text(Point(1.5,4), "Answer 1: ")
txtAnswer.setTextColor(color_rgb(255,127,80))
txtAnswer.setSize(14)
txtAnswer.setStyle("bold")
txtAnswer.draw(win)
txtAnswer2 = Text(Point(1.5,3), "Answer 2: ")
txtAnswer2.setTextColor(color_rgb(255,127,80))
txtAnswer2.setSize(14)
txtAnswer2.setStyle("bold")
txtAnswer2.draw(win)
txtAnswer3 = Text(Point(1.5,2), "Answer 3: ")
txtAnswer3.setTextColor(color_rgb(255,127,80))
txtAnswer3.setSize(14)
txtAnswer3.setStyle("bold")
txtAnswer3.draw(win)
txtAnswer4 = Text(Point(1.5,1), "Answer 4: ")
txtAnswer4.setTextColor(color_rgb(255,127,80))
txtAnswer4.setSize(14)
txtAnswer4.setStyle("bold")
txtAnswer4.draw(win)
txtEnterAn = Text(Point(8,3), "Enter your answer below: ")
txtEnterAn.setTextColor("black")
txtEnterAn.draw(win)
entAnswer = Entry(Point(8,2), 3)
entAnswer.draw(win)
Answer1 = entAnswer.getText()
win.getMouse()
#loop for answer
if Answer1 == "A":
txtCorrect = Text(Point(5,9), "Correct!")
txtCorrect.setTextColor("black")
txtCorrect.draw(win)
else:
txtCorrect = Text(Point(5,9), "Inorrect!")
txtCorrect.setTextColor("black")
txtCorrect.draw(win)
Now I'm not sure why every time I enter "A" it still shows as incorrect I know in another program I had to float the entAnswer variable but I figured this time I wouldn't have to since it's a string.
I must be overlooking the situation but I can't lay my finger down on it, any help would be appreciated, thanks!
p.s. I didn't put it in with the code but I do have the variables up top initialized such as Answer1 = " " and so forth

The problem here seems to be that you're misunderstanding how GUIs work. It's not like the sequential print/read code that most programming instruction starts with. The GUI widgets only create themselves, draw to the screen and wait for events.
This line:
Answer1 = entAnswer.getText()
will end up setting Answer1 to an empty string, because at that point, the user hasn't entered anything in the text box. Instead, you have to create a callback function that will be called by the GUI when the user hits a button to score the answer. Then in that function you will be able to read the user's answer and mark it correct or incorrect.
I recommend going through your GUI library's tutorial again to get a feel for the event-driven style of GUI programming.

I'd recommend that you abstract that user interface detail away from the problem of showing questions, obtaining answers, and determining correctness. You can sort all of that out with nothing more than a command line, text based user interface. Once you have that, then you can proceed with the user interface design with confidence, knowing that the logic behind the questionnaire is sound.
This idea goes by several names: layering, MVC, etc. I'd recommend it for this problem, because it'll help you learn the idea for those more difficult problems to come where it'll be indispensable.

i don't see a reason the logic would fail, but are you sure you are pressing "A" and not "a" .

I can't say anything about this particular problem, but I would do a
print "'" + answer + "'"
print answer.__class__
I have encountered wrapper classes (in OTHER situations) which behave like strings
but are not actually strings. Furthermore spaces and newlines can be added everywhere :)

Related

I just started programming and am having problem with both of these while loops

I've just starting a programming course and im making an adventure game.
I've gotten up to this "path" where the user must choose between the market or the blacksmith.
If they choose either they have two choices and if they dont say either choice I want to re-ask and go through the loop again. currently if I type everything in first try it works but if I fail to provide a valid answer it prompts to re-enter then doesn't go through the loop again.
How do I write this to take my:
else:
print ("Choice must be (Sword / Platemail)...")
answer = input ("").lower().strip()
and
else:
print ("Choice must be (Bread / Cabbage)...")
answer = input("").lower().strip()
return to the top of the loop with the "answer" in order to have the if and elif statments do what they need to do?
Any help recommendations would be amazing please keep in mind im brand new to programming.
Picture of code in question
The pattern is like this:
while True:
answer = input("Choice?").lower().strip()
if answer in ('sword','platemail'):
break
print("Choice must be Sword or Platemail")
For cleaner code, you might want to put this into a function, where you pass the possible answers and return the validated one.

Problem with restarting function over again

I started to learn coding with python couple days ago. I dont have any previous coding experience so im a total beginner. Im watching youtube tutorials and every time i learn something new, i try to play with those learnt things. Now i tried to make kind of a guess game and im having a problem with it. (jokingly first question is asking "are you idiot" lol).
I tried to make it so that you have 3 lives per question (there will be multiple questions which are just copies of this code with different questions and answers) Once you run out of lives, it asks if you want to start over and if answered yes, it starts from the question number 1. The problem is if you answer "yes", it starts over but it does not give the lives back and even if you answer correctly, it says game over. However if you answer correctly the first time without restarting, it works just fine and continues to the next question.
What am i missing here? Thanks for the answers!
def question1():
secret_word = "yes"
guess = ""
guess_count = 0
guess_limit = 3
out_of_guesses = False
game_over_question = ""
while guess != secret_word and not out_of_guesses:
if guess_count < guess_limit:
guess = input("Are you idiot?: ").lower()
if guess == secret_word:
print("correct! Next question:")
else:
guess_count += 1
if guess_count <= 2:
print("Try again")
else:
out_of_guesses = True
if out_of_guesses:
while game_over_question not in ("yes", "no"):
answer = input("Game over, want to start over?: ")
if answer == "yes":
question1()
elif answer == "no":
exit()
else:
print("Its yes or no.")
question1()
To understand this, you best use a debugger. To use a debugger, you need an IDE that has one, e.g. PyCharm. The screenshots in this question are from PyCharm. Other IDEs (like Visual Studio Code) will differ in usability but the concept will be the same.
Some background on using a debugger
When debugging, you set breakpoints, typically by clicking on the left of the line of code, e.g. like so:
With breakpoints enabled, you use the Bug icon instead of the Play icon.
The flow of execution will stop whenever the code hits a line with a breakpoint. You can then choose how to go on using these icons:
Step over this line of code
Step into this line (if there's a method call)
Step into (my code)
Step out (run the function until the end)
Run to cursor
Debugging your code
In your case, let's set a breakpoint on line 24. In this case I chose it, because it's the beginning of a recursion. However, I doubt that you have heard that term before. Without knowing it, it'll be hard to find a good line. Finding a good line for a breakpoint is a skill that develops over time.
Next, enter whatever is needed to reproduce the problem. On my machine, it looks like this:
Now, the breakpoint is hit and interesting stuff will happen.
Before that interesing stuff happens, let's look at the state of your program. As we have the call stack frames and variables:
One important thing to notice: your code is currently running line 31 (the actual method call) and while running that line, it is now running line 24.
Debugging the recursion
Now click the "Step into" button once. Note how the call stack changed and all variables seem to be lost.
We see that the same method ("question1") is called again. That's what programmers call a recursion.
Also: the variables are not lost, they are just "local" to that method. If you select the method from before, the variables will still be there:
Now, click "Step over" a few times, until you're asked for input again.
Enter "yes" as you did before.
Then, click "Step over" once. You are inside if guess == secret_word: at the print statement now.
Then, click "Step over" once. The text was printed and you are at the while loop.
In the next step, the condition guess != secret_word will no longer be met and the code will continue after the while loop, which is where the method ends.
Hitting "Step over" one more time will bring you back to where the method was before, your code has left the recursion:
Your code is back in line 24, within the while loop that asks you if you want to start over again.
Now that you understand what your code does, it should be possible to find a fix.
Takeaways
Typically it's not the computer who doesn't understand your code. It's you who doesn't understand your code :-)
A debugger will help you understanding what you told the computer. If there is a method on the call stack, then you called that method. Cool thing: you can look at each method and their variables and that'll allow you to make conclusions on how it arrived there.
Even cooler: you could change the values of these variables in order to play a "what-if" scenario.
IMHO, real debugging is more powerful than printf debugging (but still, a log file is an important concept of its own).

Python - Recurring Questions

So, instead of Python basically following the cascading script as it usually does is it possible where it will never end unless you type "end" and you can ask it any question over & over again?
I'm basically creating a bot where you basically activate it by typing 'Cofo, activate' and it will reply 'Cofo activated, how may I help you today?' and from there you can ask it things like 'What's the weather today' and 'what's 9 + 4' etc, etc. A little like Jarvis but without actual speech, more text based.
Sorry I haven't given a very good explanation, I can't really explain what I want but hopefully you understand.
the way to do this with a while loop:
while True:
user_data = raw_input('What do you want? ')
if user_data == 'quit': break
else:
print 'I can\'t do "{}" yet.'.format(user_data)
All this script does is echo back your input, so ignore the details - the main thing is that the loop runs until the user enters 'quit' (or whatever word you want to specify).
As noted by #cricket_007, you need a while loop. Check the tutorial for a simple introduction and the docs for a formal syntax definition.
Asking indefinitely for user input is a common pattern, be sure to check out this canonical question about a related issue: asking for user input until a valid response is provided.

Trying to call an function with a variable imbedded in the middle of it in Python

I'm creating a program with a menu that asks the user via raw_input to choose a specific chapter of narrative in the program they want to read. That portion of the code is:
mainma = raw_input ("Which chapter do you want? (1-10): ")
Here's where my problem is: I'm trying to code the call so that it will go to the requested chapter that is defined as:
Chap(mainma)menu()
as I was working on the assumption that if mainma = 1, it would invoke Chap1menu() where that particular chapter data is stored, the same if mainma = 3 it would invoke Chap3menu(). The syntax error I'm getting disagrees with me. What am I doing wrong?
You don't really want to try to turn user input directly into variable names; it's possible but it's messy, brittle, and insecure. What you want to do instead is create a list or dictionary that maps the input to the chapter functions; something like:
chapters = {'1': Chap1Menu,
'2': Chap2Menu,
#etc.
}
and then use it like so:
chapters[mainma]()
Just use m as a parameter to the function Chapmenu. For example:
def Chapmenu(m):
if m == 1:
# code for Chap1menu goes here
elif m == 2:
# code for Chap2menu goes here
elif m == 3:
# code for Chap3menu goes here
etc.
Then just call Chapmenu(mainma)
You have an opportunity for efficient code design here -- presumably the chapter menu functions share a lot of behavior between them. You shouldn't every copy-and-paste code in a program like that, because it's harder to read and a risk to update (too easy to get them out of whack with each other).
Whatever you were putting into Chapter#Menu, write a sliiiightly more general function that accepts the chapter number as an argument. This helps reuse code that's similar between chapters. The differences get stored in some list or dictionary (here insides, minimal):
insides = list('qwertywuiop')
def ChapterMenus(chapternum, **kwargs):
print('Chapter %d: About the Letter %s'%(chapternum, insides[chapternum]))
print(kwargs)
if __name__=='__main__':
mainma = raw_input("Which chapter do you want? (1-10): ")
mainma = int(mainma) #Be more helpful validating this
if mainma in range(1,11):
ChapterMenus(mainma, text='Ants')
else:
print('Tsk! A real chapter number, please!')

Text adventure in Python issue

I am working on a text adventure in Python. I'm very new to the concept of object oriented programming (and programming in general), so I'm not entirely sure what went wrong. Well, what I've done so far is made two methods; one that handles what the user types in, and one that dictates what will happen in the game, using other methods defining rooms that I will create in the future. One problem I have, though, is that I can't test the program by running it! When I run it, there is no prompt for user input - the program just ends without returning any error. There's not much code so maybe you could help me in determining the problem! I'm sure there's something really obvious in there I've forgotten...
class Main(object):
def handle_events(self, userinput, cmd):
self.userinput = userinput
self.cmd = cmd
userinput = raw_input('> ')
cmd = {'use' : use,'quit' : quit, 'help' : help}
if userinput[0] not in cmd:
print "Invalid command. Check [help] for assistance."
def main(self, handle_events):
print '''You are in a dark room filled with
strange and ominous objects.
After some feeling around, you think
you can make out a light switch.'''
self.userinput
if userinput[1] == 'switch':
print "You flicked the switch!"
Main().main
You are not calling your method. Main().main is just a reference to the method. To call it you need another set of parentheses: Main().main().

Categories