In the book "Python for the absolute beginner" by Michael Dawson, in the chapter on Lists and Dictionaries I have learned a great deal and am trying to make a new program as practice using the old Magic 8-Ball as my inspiration. Below is the code I have come up with so far.
It works up to a point...the random generated number gets generated but the elif doesn't seem to work. I know there are better ways and simpler ways, but I am doing this to reinforce my understanding of dictionaries.
I have put several print statements in to see if I was getting a number selected and the else statement is if all goes bad. As the code stands now all I get is the number printed and the else produces "Does not compute. Exit works fine. I have also confirmed the dictionary is fine using the commented out print "ball" statement.
So my issue is why does the elif statement seem to not process the random number generated. Whom ever answers has my heartfelt thanks and appreciation.
# Import the modules
import sys
import random
# define magic 8-ball dictionary
ball = {"1" : "It is certain.",
"2" : "Outlook is good.",
"3" : "You may rely on it.",
"4" : "Ask again later.",
"5" : "Concentrate and ask again.",
"6" : "Reply is hazy, try again later.",
"7" : "My reply is no.",
"8" : "My sources say no"}
# for items in ball.items():
# print(items)
ans = True
while ans:
question = input("Ask the Magic 8 Ball a question: (press enter to quit) ")
answer = random.randint(1,8)
print(answer)
if question == "":
sys.exit()
elif answer in ball:
response = ball[answer]
print(answer, response)
else:
print("\nSorry", answer, "does not compute.\n")
random.randint() returns an integer. Your dictionary's keys are all strings. Thus, when you do answer in ball, it will always be False, because "1" != 1
What you can do is either make all the keys integers (remove the quotation marks), or make answer a string by doing:
answer = str(random.randint(1,8))
Note that you shouldn't be using an elif here. If your input is nothing, both your if and elif will be True, and most of the time you don't want this. Instead, change your elif/else to just an if/else:
if question == "":
sys.exit()
if answer in ball:
response = ball[answer]
print(answer, response)
else:
print("\nSorry", answer, "does not compute.\n")
One final thing. answer will always be in ball, because you dynamically created the dictionary. Here, you can use dict.get(). Eg:
if not question: # You can do this instead
sys.exit()
print(ball.get(answer))
You are looking up on the dictionary with a number whereas the keys are strings in the dict. So, you have to convert the number to string with str.
Change
answer = random.randint(1,8)
to
answer = str(random.randint(1,8))
The string "1" is not the int 1. So answer is actually not in ball.
Try converting it like answer = str(random.randint(1,8))
Related
I'm trying to figure out how to work with loops in Python and I need a little help. The code I wrote is just something I'm playing with. It's not an assignment or anything like that.
What I'm trying to figure out is how to loop the program so that it asks the user to input something to start the questions over. This is what I have so far:
def monkeys():
apes = "This is not a monkey!"
monkey_yes = "This is a monkey!"
is_it_a_monkey = apes + monkey_yes
monkey_question = input("Type in Gorilla, Chimp or Macaque and make sure they're capitalized: ")
for question in is_it_a_monkey:
if monkey_question == 'Gorilla' or monkey_question == "Chimp":
print(apes)
continue
else:
print(monkey_yes)
break
def main():
while True:
if again not in {"y","n"}:
print("Please enter valid input")
elif again == "n":
return "Good bye!"
elif again == "y":
return monkeys()
monkeys()
I'm trying to get main() to do most of the work since that's what my teacher wants on our assignments. Everything under main() is something I copied to see if that would work but it only returns this:
Type in Gorilla, Chimp or Macaque and make sure they're capitalized: Gorilla
This is not a monkey!
This is not a monkey!
This is not a monkey!
This is not a monkey!
It was a lot longer than just the 4 lines but this is not what I'm looking for.
I see a couple of problems here...
First of all, you're concatenating two strings...
apes = "This is not a monkey!"
monkey_yes = "This is a monkey!"
is_it_a_monkey = apes + monkey_yes
When you go into your for-loop, the interpreter is looking at each character of that concatenated string. This is why you output 38 lines of "This is not a monkey!" For what you're trying to do, you don't need a for-loop. Try this instead:
def monkeys():
apes = "This is not a monkey!"
monkey_yes = "This is a monkey!"
monkey_question = input("Type in Gorilla, Chimp or Macaque and make sure they're capitalized: ")
if monkey_question == 'Gorilla' or monkey_question == "Chimp":
print(apes)
else:
print(monkey_yes)
The next issue I see is that you don't call the main function at all. Instead of calling moneys() at the bottom of your code, call main().
Next issue is using "while True:". If you're going to use a boolean as a while condition, make sure you put logic in your code to change that condition. Changing it to "False" should be what exits your main, not a return statement. Your main() would be better off starting like this:
def main():
keep_going = True
while keep_going:
monkeys()
Notice you should call your monkeys() function first, otherwise nobody will know what to input when the program starts. You also need code asking if they want to continue running the program. Right after your monkey() call, do something like this:
monkeys()
again = input("Would you like to try again? (y/n) ")
The next issue is your use of return statements. Instead of doing this:
elif again == "n":
return "Good bye!"
do this...
elif again == "n":
print("Good bye!")
keep_going = False
Lastly, you have "if again not in {"y","n"}:". You have to assign a value to "again" or you'll get more errors. If you use the example above, it should meet your needs.
Keep plugging at it and don't lose hope. You're getting close to understanding it.
First of all, you call monkeys() but you should call main() instead since that's where the loop is. Second, return causes a function to halt execution and to continue where you called it. In order to continue looping, remove the returns in main().
To get a better understanding of how your code works read this article about debugging. It shows some tips that allow you to see step-by-step what your code is doing.
You should use this code instead, which (as many have pointed out including #Code-Apprentice above) calls the function main() as you intend. #Code-Apprentice 's answer also includes a good explanation of why this works. This code is almost exactly the same as yours above; only the last line is different:
def monkeys():
apes = "This is not a monkey!"
monkey_yes = "This is a monkey!"
is_it_a_monkey = apes + monkey_yes
monkey_question = input("Type in Gorilla, Chimp or Macaque and make sure they're capitalized: ")
for question in is_it_a_monkey:
if monkey_question == 'Gorilla' or monkey_question == "Chimp":
print(apes)
continue
else:
print(monkey_yes)
break
def main():
while True:
if again not in {"y","n"}:
print("Please enter valid input")
elif again == "n":
return "Good bye!"
elif again == "y":
return monkeys()
main()
The reason I am submitting this answer is to point out that, despite calling main(), you are going to encounter another problem right away. You refer to a variable again in main(), but you never assign a value to again in the first place (if you run this code, you can expect to see an error of the form, "NameError: global name 'again' is not defined."). Addressing this next error is beyond the scope of your question; there are lots of ways that you can re-write this code to accommodate again, if you choose.
I have a little piece of code in Python where I'm trying to compare a user input to a specific element in an array. Here is the code:
movies = ["movie 1", "movie2", "movie3"];
answer = raw_input("What is your guess: ")
if answer == movies[1]
then print ("yes that is correct")
else:
print ("no that is incorrect")
I know the indentation above looks wrong becasue I typed it out in the text box and I'm new to this site as well as python.
I also know that I probably need to use some sort of conditional loop, maybe a while loop, but I'm having trouble finding where I can compare user input string value to a string value in my array. Any ideas how I might accomplish this?
Have fun with Python! I guess you are trying to make a loop which keeps receiving inputs from user to compare with the desired input until user types the correct input. If so, one way, it can be implemented as following (but think of adding a break condition, like input == "Bored" , to avoid infinite loop and hard stopping your code):
movies = ["movie 1", "movie2", "movie3"]
correctAnswer = movies[1]
is_notCorrect = True
while(is_notCorrect):
answer = raw_input("What is your guess: ")
if answer == correctAnswer:
print("Yes, that is correct")
is_notCorrect = False
else:
print("No, that is incorrect")
In the code above, when is_notCorrect turns into False. At next condition checking, it will break condition, and done with the loop.
Your code has some issues
movies = ["movie 1", "movie2", "movie3"]; # No need the semi-colon in Python
answer = raw_input("What is your guess: ")
# Need a colon here after if condition, new line, and indent.
#If you don't like the colon, you need to write a different way with one line of code Eg: <Do A> if <Condition happens> else <Do B>
if answer == movies[1]
then print ("yes that is correct") # No then in if-else statement in Python
else:
print ("no that is incorrect")
myName = input("Hey there, what's your name?")
print("Hello",myName,"!")
print("Here's a game called ''Guess my number'', in this game you will have to guess my number in 5 tips, I will think of a number between 1 and 20.")
ready = input("Are you readyyyy!?")
if ready = "yes" or "yeah" or "totally" or "hell yeah" or "yupp" or "yepp" or "uhumm" or "sure": <-- here's the problem it says, at "sure"'s 1st "-sign
print("Let's go!")
loop = "y"
else:
print("I'm sorry to hear that.")
loop "n"
Could please anyone help, beginner here. I tried to delete and add new word, I restared the program and the computer because there's something clearly wrong. If I delete a word like "sure" the pointer will still point to the same exact place but there's nothing there...
You're using a single = sign in your if statement. That's not allowed. If you want to check for equality, you'll need to use ==. The = operator is only for assignment statements.
While changing = to == will fix the syntax error, your code still won't work exactly right. That's because == will not be distributed over all the or options you show. The expression a == b or c gets interpreted as (a == b) or c, and if c is "truthy" (as any non-empty string will be), the expression will be considered true.
Instead, you probably want to use something like if ready in {"yes", "yeah", "totally"}. This creates a constant set object and tests if the value of the ready variable is in the set (which is a fast check).
You are using a = instead of a == in your if statement. However, I would recommend doing if ready.lower() in {"yes", "yeah", "totally", "hell yeah", "yupp", "yepp"} to account for them using all uppercase.
Also, you seem to be missing your actual loop statements. I noticed you had variables named loop that are 'y' and 'n' but don't actually use them. You should also do something like this:
myName = input("Hey there, what's your name?")
print("Hello",myName,"!")
print("Here's a game called ''Guess my number'', in this game you will have to guess my number in 5 tips, I will think of a number between 1 and 20.")
loop = True
while loop:
ready = input("Are you readyyyy!?")
if ready.lower() in {"yes", "yeah", "totally", "hell yeah", "yupp", "yepp", "uhumm", "sure"}:
print("Let's go!")
loop = False
#To break out of the while loop that will keep asking them when they are ready
else:
print("I'm sorry to hear that.")
I am trying to create a questionnaire where it asks multiple yes/no questions, and after receiving all of the responses a different output is shown depending on the combination of answers provided.
For example, if there were three questions and someone answered no, no, then yes, they would see one output (just a simple sentence that I will create), but if someone else answered yes, no, yes, they would see a different response at the end. I don't want to provide feedback after each individual question, only when all questions have been answered.
I was trying to use if/else, but that didn't seem to be working for my purposes (at least the way I was doing it, but I am very new to Python!). I'm sorry that I don't have much to work with, but I am trying to learn and have been doing Google search after Google search to no avail. Thank you!!
EDIT: Here's what I've been trying. Is there any way to extend on this? What I've done is based on my limited knowledge of Python.
female = raw_input("Are you female?")
over18 = raw_input("Are you over 18?")
shopping = raw_input("Do you like to go shopping?")
And then I know how to do something like
if female=="yes":
print "blahblah"
else:
print "something else"
But I don't know how to use all three responses to contribute to what will print. I also can't figure out how to restrict each question to just a yes/no answer.
EDIT 2:
Can I use multiple if statements as shown below? I know how to use just one response to change the output, but having three influence just one output is just throwing me for a loop.
female = raw_input("Are you female?")
over18 = raw_input("Are you over 18?")
shopping = raw_input("Do you like to go shopping?")
if (female=="yes" and over18=="yes" and shopping=="yes"):
print "1"
if (female=="yes" and over18=="yes" and shopping=="no"):
print "2"
if (female=="yes" and over18=="no" and shopping=="no"):
print "3"
if (female=="yes" and over18=="no" and shopping=="yes"):
print "4"
if (female=="no" and over18=="yes" and shopping=="yes"):
print "5"
if (female=="no" and over18=="yes" and shopping=="no"):
print "6"
if (female=="no" and over18=="no" and shopping=="yes"):
print "7"
if (female=="no" and over18=="no" and shopping=="no"):
print "8"
else:
print "invalid"
It looks like that is functioning relatively well, but no matter what combination of "yes" and "no" I use it will give me the correct number output but then also say "invalid." However, if I take out the else, it won't restrict the answers to "yes" or "no," will it?
One way that occurs to me is to make a dictionary keyed by a tuple of yes/no responses - one for each question. So if you have, say, 2 questions - 1 and 2, you'd have 4 possible outcomes. YY, YN, NY, and NN. You can create a dictionary with keys that correspond to these. So something like
def ask_question(qn):
resp = raw_input(qn)
if resp.lower() in ["yes", "y"]: # Handles Yes, yes etc.
return True
else:
return False
responses = {(True, True) : "Old Male",
(True, False) : "Young Male",
(False, True) : "Old Female",
(False, False) : "Young Female"}
answers = []
questions = ["Are you male?", "Are you over 18?"]
for q in questions:
answers.append(ask_question(q))
print responses[tuple(answers)]
Since the actual answers are in data (rather than code), you can read these out from a file which you can edit/generate easily. It's a much more conventient way of mananging than a huge and hairy if/elif/else block.
Pretty new to python/programming in general, this is my biggest project yet.
I am writing a program that will do SUVAT equations for you. (SUVAT equations are used to find the displacement, start/end velocity, acceleration and time travelled by an object with constant velocity, you may call them something different.)
I made this list:
variables = ["Displacement", "Start Velocity", "End Velocity", "Acceleration", "Time"]
which is used in the following while/for loop:
a = 0
while a==0:
for variable in variables:
# choice1 is what the user is looking to calculate
choice1 = raw_input("Welcome to Mattin's SVUVAT Simulator! Choose the value you are trying to find. You can pick from " + str(variables))
# will execute the following code when the for loop reaches an item that matches the raw_input
if choice1 == variable:
print "You chave chosen", choice1
variables.remove(variable) #Removes the chosen variable from the list, so the new list can be used later on
a = 1 # Ends the for loop by making the while loop false
# This part is so that the error message will not show when the raw_input does not match with the 4 items in the list the user has not chosen
else:
if choice1 == "Displacement":
pass
elif choice1 == "Start Velocity":
pass
elif choice1 == "End Velocity":
pass
elif choice1 == "Acceleration":
pass
# This error message will show if the input did not match any item in the list
else:
print "Sorry, I didn't understand that, try again. Make sure your spelling is correct (Case Sensitive), and that you did not inlcude the quotation marks."
Hopefully the comments I have written in the code should explain my intentions, if not, feel free to ask anything.
The problem is that when I run the code, and input choice1, the for loop activates the last line of code:
else:
print "Sorry, I didn't understand that, try again. Make sure your spelling is correct (Case Sensitive), and that you did not inlcude the quotation marks."
and then prompts me to enter the input again, and will do this as many times as it needs to get to the item on the list that I am typing.
However, I specifically coded that if what I input does not match the item on the list the for loop is currently checking, but does match one of the other items on the list, then it should pass and loop round to checking the next item.
I am probably doing something stupid, but I don't see it, so please help me figure out what I have to do to get my desired result? I assumed it was the syntax I had wrong so that is why that is the title.
Thanks for any help, I appreciate it.
Besides the problem with the indentation in your pasted code, I would rewrite it as such:
while True:
choice = raw_input('...')
if choice in variables:
print "You chave chosen", choice
# Remove the chosen member from the list
variables = [v for v in variables if v != choice]
# Break out of loop
break
# Print error messages etc.
Also remember that string comparisons are case sensitive. I.e 'Displacement' != 'displacement'.