Related
This is the code that I made when I tried making an if-then statement but, it always defaults to else. Also i just started trying to code from online tutorials today.
print('yes or no?')
if sys.stdin.readline() == 'yes' :
print('Yay')
else :
print('Aww')
This is what happens:
Console:yes or no?
Me:yes
Console:Aww
I've been looking stuff up for half an hour and can't figure out how to fix this please help
sys.stdin.readline() reads a line which ends with '\n' (when you hit "enter").
So you need to remove this '\n' from the captured input using strip().
print('yes or no?')
if sys.stdin.readline().strip() == 'yes' :
print('Yay')
else :
print('Aww')
I tried to explain and solve your specific problem but you could of course use raw_input() or input() (PY3) as mentioned in the other answer.
In python, getting the input of a user's string can be done via input() (or in python 2.7, use raw_input()).
If you include the code:
user_input = raw_input("yes or no?")
This will first print the string "yes or no?", then wait for user input (through stdin), then save it as a string named user_input.
So, you change your code to be:
user_input = raw_input("yes or no?")
if user_input == "yes":
print("Yay")
else:
print("Aww")
this should have the desired effect.
Ok I used user_input and input instead of sys.stdin.readline() on strings and i used it in a basic calculator here it is :
import random
import sys
import os
user_input = input("Would you like to add or subtract?")
if user_input == 'add' :
print('What would you like to add?')
plus1 = float(sys.stdin.readline())
print('Ok so %.1f plus what?' % (float(plus1)))
plus2 = float(sys.stdin.readline())
print('%.1f plus %.1f equals %.1f' % (float(plus1),float(plus2), float(plus1+plus2)))
elif user_input == 'subtract' :
print('What would you like to subtract?')
minus1 = float(sys.stdin.readline())
print('Ok so %.1f minus what?' % (float(minus1)))
minus2 = float(sys.stdin.readline())
print('%.1f minus %.1f equals %.1f' % (float(minus1), float(minus2), float(minus1 - minus2)))
else :
print('That is not one of the above options')
Thanks alot guys!
I have been trying to program a maths quiz that both works and is as efficient as possible. Looking over my code I saw I had a lot of integer inputs and that lead to me having the program to ask the question/exit the system if the criteria isn't met, so to help me I thought that it would be useful to create a new function. Here is my attempt:
def prompt_int(prompt=''):
while True:
if status == prompt_int(prompt=''):
val = input(prompt)
if val in (1,2):
return int(val)
return true
elif status != prompt_int(prompt=''):
val = input(prompt)
if val in (1,2,3):
return int(val)
return true
else:
print("Not a valid number, please try again")
However, when I try to implement this function around my code it doesn't work properly as it says that status isn't defined however, when I do define status it goes into a recursion loop. How can I fix this problem?
Here is my original code before i try to implement this function:
import sys
import random
def get_bool_input(prompt=''):
while True:
val = input(prompt).lower()
if val == 'yes':
return True
elif val == 'no':
return False
else:
sys.exit("Not a valid input (yes/no is expected) please try again")
status = input("Are you a teacher or student? Press 1 if you are a student or 2 if you are a teacher")# Im tring to apply the new function here and other places that require integer inputs
if status == "1":
score=0
name=input("What is your name?")
print ("Alright",name,"welcome to your maths quiz."
"Remember to round all answer to 5 decimal places.")
level_of_difficulty = int(input(("What level of difficulty are you working at?\n"
"Press 1 for low, 2 for intermediate "
"or 3 for high\n")))
if level_of_difficulty not in (1,2,3):
sys.exit("That is not a valid level of difficulty, please try again")
if level_of_difficulty == 3:
ops = ['+', '-', '*', '/']
else:
ops = ['+', '-', '*']
for question_num in range(1, 11):
if level_of_difficulty == 1:
number_1 = random.randrange(1, 10)
number_2 = random.randrange(1, 10)
else:
number_1 = random.randrange(1, 20)
number_2 = random.randrange(1, 20)
operation = random.choice(ops)
maths = round(eval(str(number_1) + operation + str(number_2)),5)
print('\nQuestion number: {}'.format(question_num))
print ("The question is",number_1,operation,number_2)
answer = float(input("What is your answer: "))
if answer == maths:
print("Correct")
score = score + 1
else:
print ("Incorrect. The actual answer is",maths)
if score >5:
print("Well done you scored",score,"out of 10")
else:
print("Unfortunately you only scored",score,"out of 10. Better luck next time")
class_number = input("Before your score is saved ,are you in class 1, 2 or 3? Press the matching number")
while class_number not in ("1","2","3"):
print("That is not a valid class, unfortunately your score cannot be saved, please try again")
class_number = input("Before your score is saved ,are you in class 1, 2 or 3? Press the matching number")
else:
filename = (class_number + "txt")
with open(filename, 'a') as f:
f.write("\n" + str(name) + " scored " + str(score) + " on difficulty level " + str(level_of_difficulty))
with open(filename, 'a') as f:
f = open(filename, "r")
lines = [line for line in f if line.strip()]
f.close()
lines.sort()
if get_bool_input("Do you wish to view previous results for your class"):
for line in lines:
print (line)
else:
sys.exit("Thanks for taking part in the quiz, your teacher should discuss your score with you later")
if status == "2":
class_number = input("Which classes scores would you like to see? Press 1 for class 1, 2 for class 2 or 3 for class 3")
if class_number not in (1,2,3):
sys.exit("That is not a valid class")
filename = (class_number + "txt")
with open(filename, 'a') as f:
f = open(filename, "r")
lines = [line for line in f if line.strip()]
f.close()
lines.sort()
for line in lines:
print (line)
Well, just a part:
def prompt_int(prompt=""):
while True:
val = input(prompt)
if val in ("1", "2"):
return int(val), True
Will ask again and again. And return when the user enter "1" or "2"!
But better: "if val in "12":
def prompt_int(prompt=""):
while True:
val = input(prompt)
if val.isdigit():
return int(val)
Hi if you dont want to have valid values send to your you could change your code as the function above.
But you could also change it to do the system exits:
def prompt_int(prompt="", authorized=()):
while True:
val = raw_input(prompt)
if val.isdigit():
if int(val) in authorized:
return int(val)
else:
sys.exit("Bla bla bla too bad")
def prompt_int(prompt=''):
while True:
if status == prompt_int(prompt=''):
This line will look for the name "status" in the global namespace (module's namespace), and raise a NameError if there's no global variable named 'status'.
If there's one, it will then recursively calls prompt_int without any possible termination, resulting theoretically in an endless recursion, but practically (in CPython at least) in a RuntimeError when it will hit the maximum recursion depth.
There are also quite a few other things that won't work as you expect:
val = input(prompt)
if val in (1,2):
In Python 3.x, val will be a string, so it will never compare equal to an int. In Python 2.x, input() is a shortcut for eval(raw_input()), which might return an int, but is also a huge security flaw since it unconditionnally execute untrusted code.
return int(val)
return true
The second return statement will never be executed, obviously, since the function will exit at the first one.
A simpler implementation might look like this:
# rebinds raw_input to input for python < 3
import sys
if sys.version_info.major < 3:
input = raw_input
def prompt_int(prompt='', choices=None):
while True:
val = input(prompt)
try:
val = int(val)
if choices and val not in choices:
raise ValueError("{} is not in {}".format(val, choices))
return val
except (TypeError, ValueError) as e:
print(
"Not a valid number ({}), please try again".format(e)
)
While we're at it, there's room for improvement in other parts of your code. Let's start with this:
def get_bool_input(prompt=''):
while True:
val = input(prompt).lower()
if val == 'yes':
return True
elif val == 'no':
return False
else:
sys.exit("Not a valid input (yes/no is expected) please try again")
First point: your naming is not consistent. If your other function is named prompt_int, this one should be named prompt_bool. Also, you have one function (prompt_int) looping forever and the other one exiting the whole program on invalid input, which is another inconsistency. If you want to allow the user to exit on any prompt, provide an explicit option for it, ie:
def prompt_bool(prompt, quit='Q'):
prompt += " (hit '{}' to exit) : ".format(quit)
while True:
val = input(prompt).strip().upper()
if val == quit:
sys.exit("Goodbye")
elif val == 'yes':
return True
elif val == 'no':
return False
else:
print "Invalid input '{}', please try again".format(val)
Of course you then want to provide the same option in prompt_int(), which leads to a more generic function:
def get_input_or_quit(prompt, quit="Q"):
prompt += " (hit '{}' to exit) : ".format(quit)
val = input(prompt).strip()
if val.upper() == quit:
sys.exit("Goodbye")
return val
def prompt_bool(prompt):
while True:
val = get_input_or_quit(prompt).lower()
if val == 'yes':
return True
elif val == 'no':
return False
else:
print "Invalid input '{}', please try again".format(val)
And of course you also replace the call to input by a call to get_input_or_quit in prompt_int.
We could go on for long - splitting all your code in distinct, self-contained function, writing a "main()" function to drive them (instead of having the "main" part at the top level), and obviously using the operator module instead of eval().
I'm creating a dialogue tree for a text-adventure game that uses a list to hold the dialogue choices. When a user selects an option from the list, it responds and then removes that option from the list so that users can't select it again. The problem is that once I select one option (the first instance of the loop), the second choice always returns an error.
Here's the code:
x = 1
dec1 = '"Why are you doing this? What do you want?"'
dec2 = '"You keep talking about Thread. What is it?"'
dec3 = '"Can you help me?"'
dec4 = 'Say nothing.'
decision = [dec1, dec2, dec3, dec4]
while x == 1:
for i in decision:
print '%d. %s' % (decision.index(i) + 1, i)
current_input = input.return_input(charstate)
if isinstance(current_input, int):
if int(current_input) > len(decision) or int(current_input) < 1:
print '\n"I don\'t understand, %s."' % charstate.charname
continue
elif int(current_input) == decision.index(dec1) + 1:
print 'text'
decision.remove(dec1)
elif int(current_input) == decision.index(dec2) + 1:
print 'text'
decision.remove(dec2)
elif int(current_input) == decision.index(dec3) + 1:
print 'text'
decision.remove(dec3)
elif int(current_input) == 4:
print 'text'
x += 1
else:
exit(1)
else:
print '\n"I don\'t understand, %s."' % charstate.charname
continue
The problem appears to be that after I select one option, the if conditional returns an error because decision.index(dec#) no longer exists. At least, that's what I've been able to figure out. The specific error is "ValueError: x is not in list". I'm trying to figure out a way to set it up so that that doesn't happen.
The only idea I've had is creating separate try...except statements for each of the choices, which seems incredibly inelegant and bloated. There has to be something simple that I'm missing.
Thanks everyone!
edit: input.return_input(charstate) is a function that just returns a raw_input. "charstate" is an object that holds the current character information and choice history--it's passed between events and scenes.
Delete from the array by the index instead, i believe this will give you the functionality your looking for
dec1 = '"Why are you doing this? What do you want?"'
dec2 = '"You keep talking about Thread. What is it?"'
dec3 = '"Can you help me?"'
dec4 = 'Say nothing.'
decision = [[dec1,'text1'], [dec2,'text2'], [dec3,'text3'], [dec4,'text4']]
while True:
for i in decision:
print '%d. %s' % (decision.index(i) + 1, i[0])
current_input = input.return_input(charstate)
if isinstance(current_input, int):
if int(current_input) > len(decision) or int(current_input) < 1:
print '\n"I don\'t understand, %s."' % charstate.charname
continue
elif int(current_input) in xrange(1,len(decision)):
print '%s' % (decision[int(current_input)-1][1])
del decision[int(current_input)-1]
elif int(current_input) == 4:
print 'text'
break
else:
exit(1)
else:
print '\n"I don\'t understand, %s."' % charstate.charname
continue
Ok, I actually figured out how to do what I needed to do. pseudonym's answer was a good first step for me, but then I realized I needed to actually run separate code depending on the answer, not just print something different.
I've restructured the code so that I don't need to call an index to identify which answer was chosen. It was actually a relatively simple fix, once I got my head around it.
dec1 = '"Why are you doing this? What do you want?"'
dec2 = '"You keep talking about Thread. What is it?"'
dec3 = '"Can you help me?"'
dec4 = 'Say nothing.'
decision = [dec1, dec2, dec3, dec4]
while True:
for i in decision:
print '%d. %s' % (decision.index(i) + 1, i)
current_input = input.return_input(charstate)
if isinstance(current_input, int):
current_input = int(current_input)
if current_input - 1 in xrange(0, len(decision)):
response = decision[current_input - 1]
elif current_input - 1 not in xrange(0, len(decision)):
print '\n"I don\'t understand, %s."\n' % charstate.charname
continue
else:
exit(1)
else:
print '\n"I don\'t understand, %s."\n' % charstate.charname
continue
if response == dec1:
print 'dec1'
elif response == dec2:
print 'dec2'
elif response == dec3:
print 'dec3'
elif response == dec4:
print 'dec4'
break
else:
exit(1)
del decision[current_input - 1]
I've been trying to program a Mad-Libs Simulator in Python 3.3.3 and I have been receiving the error:
Traceback (most recent call last):
File "/Users/RuzHayes_Laptop/Desktop/Programming:Design/Programs/Python Mad Libs Program 000.py", line 80, in <module>
templates=[("The"+" "+adj+" "+n+" "+v+" "+adv+pun),(adj+" "+pluralize(n)+' '+(v[:len(v)-1])+" "+adv+pun)]
TypeError: Can't convert 'NoneType' object to str implicitly
In the following code:
print("Welcome!")
print("When you would like to try out ")
print("Python Mad Libs Program, Prototype000,")
begin=input("press the enter/return key.")
print()
print()
print("Initializing befuddlement...")
print()
import random
sentenceCap=35
sentenceBottom=25
numOfSentences=random.randint(sentenceBottom,sentenceCap)
caps={"a":"A","b":"B","c":"C","d":"D",'e':'E','f':'F','g':'G','h':'H','i':'I','j':'J','k':'K','l':'L','m':'M','n':'N','o':'O','p':'P','q':'Q','r':'R','s':'S','t':'T','u':'U','v':'V','w':'W','x':'X','y':'Y','z':'Z'}
tempstore=[" "]*numOfSentences
irregplrls={'child':'children','ox':'oxen','moose':'moose'}
def testforoo(x):
for j in range(0,len(x)):
if j+1<=len(x) and x[j:j+1]=='oo'.lower():
return True
return False
def pluralize(x):
l=len(x)
for i in irregplrls:
if i == x:
return irregplrls[x]
if x[l-1]=="y":
return x[:l-1]+"ies"
elif x[l-1]=="s" and x[l-2]=="u":
return x[:l-2]+"i"
elif x[l-1] in ('s','x'):
return x+"es"
elif x[-2:] in ('ch','sh'):
return x+"es"
elif 'f'==x[l-1] or x[l-2]:
if 'f'==x[l-1]:
return x[:l-1] + 'ves'
elif 'f'==x[l-2]:
return x[:l-2]+"ves"
elif testforoo(x)!=False:
return x[:testforoo(x)-2]+'ee'+x[testforoo(x):]
else:
return x+'s'
print()
print("Retrieving craploads of words...")
print()
verb=["moves","jumps", "hides","sniffs","gazes","sneezes","calls"]
noun=["rabbit","dog","cat","otter","seal","elephant","fox",'baby','moose','octopus']
adjec=["happy","angry","cute","enormous","elegant","annoying"]
adver=["merrily","frustratedly","incoherently","morosely","peppily",'exuberantly']
endpunct=[".","!"]
print()
print("Simulating human grammar-speak...")
print()
print()
for i000 in range(0,numOfSentences):
v=random.choice(verb)
n=random.choice(noun)
adj=random.choice(adjec)
adv=random.choice(adver)
pun=random.choice(endpunct)
askinput=random.randint(0,round(numOfSentences/5))
whichinput=random.randint(0,3)
if askinput==0:
if whichinput==0:
n=input("Please input a noun. ")
elif whichinput==1:
v=input("Please input a verb. ")
elif whichinput==2:
adj=input("Please input an adjective. ")
elif whichinput==3:
adv=input("Please input an adverb. ")
templates=[("The"+" "+adj+" "+n+" "+v+" "+adv+pun),(adj+" "+pluralize(n)+' '+(v[:len(v)-1])+" "+adv+pun)]
final=templates[random.randint(0,len(templates)-1)]
if final[:1]==final[:1].lower():
final=caps[final[:1]]+final[1:]
tempstore[i000]=final
print()
print()
print("Producing proof of illiteracy...")
print()
print()
for i001 in range(0,len(tempstore)):
sent=tempstore[i001]
print(sent)
I am very confused and I need help. I have now found the problem to be in the end of the pluralize definition, but otherwise I am very confused. The program worked until I changed pluralize to account for certain nouns not being correctly pluralized.
I will appreciate any help you can give me. I have only been programming for about a month now and this is the hardest program I have ever attempted.
Thank you and Merry Christmas! That is, of course, if you celebrate Christmas.
def testforoo(x):
for j in range(0,len(x)):
if j+1<=len(x) and x[j:j+1]=='oo'.lower():
return True
return False
is
def testforoo(x):
for j in range(0,len(x)):
if x[j]=='oo'.lower():
return True
return False
because if len(x) is 4, then j runs from 0 to 3 and j+1 from 1 to 4, then j+1 always <= len(x) .
it is also
def testforoo(x):
return any(x[j]=='oo'.lower() for j in range(0,len(x)))
The reason of the error is when pluralize(n) returns None (I don't know in which case), the addition of None to a string can be processed.
If you use the formatting with %s (or with format), there won't be the problem anymore.
I improved your code at certain places. See:
begin=input("Welcome!\n"
"When you would like to try out\n"
"Python Mad Libs Program, Prototype000,"
"press the enter/return key.")
print("\nInitializing befuddlement...")
import random
sentenceCap=35
sentenceBottom=25
numOfSentences=random.randint(sentenceBottom,sentenceCap)
tempstore=[" "]*numOfSentences
irregplrls={'child':'children','ox':'oxen','moose':'moose'}
def testforoo(x):
return any(x[j]=='oo'.lower() for j in range(0,len(x)))
def pluralize(x):
if x in irregplrls:
return irregplrls[x]
if x[-1]=="y":
return x[:-1]+"ies"
elif x[-2:]=="us":
return x[:-2]+"i"
elif x[-1] in 'sx':
return x+"es"
elif x[-2:] in ('ch','sh'):
return x+"es"
elif 'f'==x[-1] or x[-2]:
if 'f'==x[-1]:
return x[:-1] + 'ves'
elif 'f'==x[-2]:
return x[:-2]+"ves"
elif any(x[j]=='oo'.lower() for j in range(0,len(x))):
return x[:testforoo(x)-2]+'ee'+x[testforoo(x):]
else:
return x+'s'
print("\nRetrieving craploads of words...")
verb=["moves","jumps", "hides","sniffs","gazes","sneezes","calls"]
noun=["rabbit","dog","cat","otter","seal","elephant","fox",'baby','moose','octopus']
adjec=["happy","angry","cute","enormous","elegant","annoying"]
adver=["merrily","frustratedly","incoherently","morosely","peppily",'exuberantly']
endpunct=[".","!"]
print("\nSimulating human grammar-speak...\n")
for i000 in range(0,numOfSentences):
v=random.choice(verb)
n=random.choice(noun)
adj=random.choice(adjec)
adv=random.choice(adver)
pun=random.choice(endpunct)
askinput=random.randint(0,round(numOfSentences/5))
whichinput=random.randint(0,3)
if askinput==0:
if whichinput==0:
n=input("Please input a noun. ")
elif whichinput==1:
v=input("Please input a verb. ")
elif whichinput==2:
adj=input("Please input an adjective. ")
elif whichinput==3:
adv=input("Please input an adverb. ")
templates=["The %s %s %s %s%s" % (adj,n,v,adv,pun),
"%s %s %s %s%s" % (adj,pluralize(n),v[:len(v)-1],adv,pun)]
final = random.choice(templates)
final=final[0].upper() + final[1:]
tempstore[i000]=final
print('numOfSentences==',numOfSentences,i000)
print("\nProducing proof of illiteracy...\n")
print ('\n'.join(tempstore))
I'm not sure of what the function pluralize() does, I let the function testforoo() and didn't try to modify this part, examine it carefully, the instruction elif 'f'==x[-1] or x[-2]: seems suspect to me, it must be elif 'f'==x[-1] or 'f'==x[-2]: in my opinion.
If one or more of n, v, adj, or adv is not being assigned correctly, then its value is None. The line your error is on is concatenating strings together, but if one of the variables is not a string, it throws the error you're seeing.
Try printing the values of those variables at different places until you can track down exactly where the issue with their assignment lies.
I made a simple script which finds the Square root of a number. The user inputs a number and it finds the square root and shows the result. I want it to check whether the input was a number or not. If it was a number it'll continue else it'll show a message, and reset.
I tried using:
while num != int(x):
print "That is not a valid number"
return self.page()
But that only shows an error.
Can someone help me out on this?
Here is the code:
import math
import sys
class SqRoot(object):
def __init__(self):
super(SqRoot, self).__init__()
self.page()
def page(self):
z = 'Enter a number to find its square root: '
num = int(raw_input(z))
sqroot = math.sqrt(num)
print 'The square root of \'%s\' is \'%s\'' % (num, sqroot)
choose = raw_input('To use again press Y, to quit Press N: ')
if choose == 'Y' or choose == 'y':
return self.page()
elif choose == 'N' or choose == 'n':
sys.exit(0)
print "SqRoot Finder v1.0"
print "Copyright(c) 2013 - Ahnaf Tahmid"
print "For non-commercial uses only."
print "--------------------------------"
def main():
app = SqRoot()
app()
if __name__ == '__main__':
main()
One of the python principles is EAFP:
Easier to ask for forgiveness than permission. This common Python coding style assumes the existence of valid keys or attributes and catches exceptions if the assumption proves false.
x = raw_input('Number?')
try:
x = float(x)
except ValueError:
print "This doesn't look like a number!"
If you don't want to use the ask forgiveness method, here is a simple function which should work on any valid float number.
def isnumber(s):
numberchars = ['0','1','2','3','4','5','6','7','8','9']
dotcount=0
for i in range(len(s)):
if (i==0 and s[i]=='-'):
pass
elif s[i]=='.' and dotcount==0:
dotcount+=1
elif s[i] not in numberchars:
return False
return True
Note: You can add base 16 easy by changing numberchars to:
numberchars = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f']