Retry user input in Python script - python

I'm trying to figure out if there is a way to "force" a Python script to not "throw me back" into the bash environment if I commit a simple error in my Python script.
Here's an MWE (MWE.py) to illustrate the point:
How can you tell Python NOT to kick me out of the program if I press 3 in the MWE below?
x = raw_input("Please input a number 1 or 2: ")
if (x == '1'):
print '1'
elif (x == '2'):
print '2'
#else:
#print 'Neither 1 nor 2.'
Notice that my last two lines are commented out. If I uncomment them, obviously I will get the respective print statement and the program will finish successfully. However, let's assume that I didn't have those last two lines, and wanted MWE.py to "stay in Python mode" (so to speak) and not harshly return me to the bash shell, thereby forcing me to rerun from scratch with python MWE.py.
Is there a way to accomplish this somehow?
Obviously, this is a trivial MWE but I'm trying to understand the principle: is it possible to just return the last prompt that I was presented with right before I committed an input error (such as committed in this MWE when I pressed 3). Is there basically a "generalized way" to get back to x = raw_input("Please input a number 1 or 2: ") (or whatever else was the most recent prompt that I was given before I made an input error)?
This seems particularly important in programs that require multiple user inputs at different stages. I would hate to start all over.

It's called a loop (the parentheses around the conditions are not required):
x = None
while x != '1' and x != '2':
x = raw_input("Please input a number 1 or 2: ")
if x == '1':
print '1'
elif x == '2':
print '2'
else:
print 'Neither 1 nor 2.'
print "all OK"
There are many ways of writing this. You should pay attention to how you initialise x before the loop, None is typical in python.
Also note the the value of x is a string, not an int.
This would quickly become unwieldy if you had a large number of possible values to test. So an alternative approach is to use an infinite loop and break out on a correct reply:
x = None
while True:
x = raw_input("Please input a number 1 or 2: ")
if x == '1':
print '1'
break
elif x == '2':
print '2'
break
else:
print 'Invalid input, try again'
print "all OK"

Related

How to print different functions according to a given input

I'm learning python since few weeks ago and I need some help with a code. I'm triying to run a code that display certain value according to the input given by the user, so if user enters 1, x value is shown. I've tried a lot of different ways to do it but surely I'm skipping or ignoring something. How could I make this work? Thanks. (This code only prints second_statement no matter what the user inputs).
def first_statement(x):
print("xxxx")
def second_statement(x):
print("yyyy")
x = input("If you want x thing press 1, otherwise, press 2: ")
if x == 1:
print(first_statement(x))
else:
print(second_statement(x))
You can change 1 to '1' in if statement or just convert input to int using int() in input line.
First way
def first_statement(x):
print("xxxx")
def second_statement(x):
print("yyyy")
x = input("If you want x thing press 1, otherwise, press 2: ")
if x == '1':
print(first_statement(x))
else:
print(second_statement(x))
second way
def first_statement(x):
print("xxxx")
def second_statement(x):
print("yyyy")
x = int(input("If you want x thing press 1, otherwise, press 2: "))
if x == 1:
print(first_statement(x))
else:
print(second_statement(x))
Error:
Because input gives a string even if you enter a number so you have to convert it to a number using int or float.
or use string to compare with the input.

comparing user input and list created by text file using in operator always returns false

Creating an access code program. I created a list and placed the file in it.
The output is: ['Cameron', 'Cameron', 'sudocode', 'Sudocode'...] ect. That part is fine.
I have tried using many different methods, mainly the 'in' operator to get boolean value of True. Never happens. I type in 'Cameron' and I get back false. Here is the code.
`
with open("kwaccess.txt") as file:
keyword1 = file.read().splitlines()
keyword_accesslist = [x.rstrip() for x in keyword1]
print(keyword_accesslist)
output is: ['Cameron', 'cameron', 'sudocode', 'Sudocode', 'Python or python']
for attempt in keyword_accesslist:
print(verify1)`
# Another attempt
if attempt in keyword_accesslist:
verify1 == True
else:
verify1 == False
If I type in Cameron, which is in the list for certain or any of the keywords, I get back False 5 times (for the 5 elements in the list, then it moves on to next part of code. Everything else works. Even the random number generator that I use the 'in' operator to compare with the user input and works perfect. It's the file into a list that has the compare jacked up. What am I missing...how do you compare a list element to the user string input with the 'in' operator.
I've gotten this error a few times during this long stretch of 'Denying' further coding day :)
TypeError: 'in ' requires string as left operand, not list...not currently, but along the way
Good luck Master coders.
HERE IS THE CODE:
def code_generator(string):
test = str(string) + str(randint(200,2000))
return test
def list_random_true():
codenumber = [number for number in range(200,2000)]
return codenumber
def access_code(attempt):
with open("kwaccess.txt") as file:
keyword1 = file.read().splitlines()
keyword_accesslist = [x.rstrip() for x in keyword1]
print(keyword_accesslist) # output is: ['Cameron', 'cameron', 'sudocode', 'Sudocode', 'Python or python']
##This is my PROBLEM AREA, can't rotate through the elements in list and compare against attempt
verify1 = False
for x in range(len(keyword_accesslist)):
verify1 = attempt == str(keyword_accesslist[x])
if verify1 == True:
x = 1
for x in range(3):
print("Verifying...")
time.sleep(3)
break
else:
x += 1
input("Access Denied. Please re-enter password. ")
if x == 3:
print("Your account has been locked. Please contact Admin Services.")
exit()
else:
pass
numbercheck = str(list_random_true()) # Each number in own element to check
for number in numbercheck:
verify2 = number in attempt
if verify2 == True: # Second Security Attemp
print("Access Granted")
break
else:
pass
BEGINNING OF PROGRAM
try:
compare = input("Please enter Secret Code. ")
except EOFError as e:
pass
attempt = code_generator(compare)
access_code(attempt)
Ok I checked out your code. With what you have, I do not understand what you are doing. verify1 = attempt == keyword_accesslist[x] will always return false as attempt is attempt is the user input but with some random digits appended to it, which is never the first element of keyword_accesslist. In addition, are you trying to check each word in keyword_accesslist and see if the attempt is equal or just the first element? Because you only iterate once every x, then if the check is wrong it will print "access denied" THEN check the next keyword_accesslist.
With some guesses, I think this is similiar to what you want:
verify1 = False
tries = 0
while tries < 3:
for password in keyword_accesslist:
verify1 = attempt == password
if verify1:
for x in range(3):
print("Verifying...")
time.sleep(3)
break
if not verify1:
tries += 1
attempt = input("Access Denied. Please re-enter password. ")
if tries == 3:
print("Your account has been locked. Please contact Admin Services.")
exit()
It's not the best, but I have changed the loop so that it probably does what you want it to do. It uses a nested loop to check for the password and the outer while loop to keep track of tries. I've attempted to use your logic, but I don't understand some of your other functions.
This feels like a debugging problem and not suited for stackoverflow, but I hope that you recieved the help you need.

I need to figure out how to make my program repeat. (Python coding class)

I am a beginner student in a python coding class. I have the majority of the done and the program itself works, however I need to figure out a way to make the program ask if wants a subtraction or an adding problem, and if the user would like another question. I asked my teacher for assistance and he hasn't gotten back to me, so I'm simply trying to figure out and understand what exactly I need to do.
import random
x = int(input("Please enter an integer: "))
if x < 0:
x = 0
print('Negative changed to zero')
elif x == 0:
print('Zero')
elif x == 1:
print('Single')
else:
print('More')
maximum = 10 ** x;
maximum += 1
firstnum = random.randrange(1,maximum) # return an int from 1 to 100
secondnum = random.randrange(1, maximum)
compsum = firstnum + secondnum # adds the 2 random numbers together
# print (compsum) # print for troubleshooting
print("What is the sum of", firstnum, " +", secondnum, "?") # presents problem to user
added = int(input("Your answer is: ")) # gets user input
if added == compsum: # compares user input to real answer
print("You are correct!!!")
else:
print ("Sorry, you are incorrect")
You'll want to do something like this:
def foo():
print("Doing good work...")
while True:
foo()
if input("Want to do more good work? [y/n] ").strip().lower() == 'n':
break
I've seen this construct (i.e., using a break) used more often than using a sentinel in Python, but either will work. The sentinel version looks like this:
do_good_work = True
while do_good_work:
foo()
do_good_work = input("Want to do more good work? [y/n] ").strip().lower() != 'n'
You'll want to do more error checking than me in your code, too.
Asking users for input is straightforward, you just need to use the python built-in input() function. You then compare the stored answer to some possible outcomes. In your case this would work fine:
print('Would you like to test your adding or subtracting skills?')
user_choice = input('Answer A for adding or S for subtracting: ')
if user_choice.upper() == 'A':
# ask adding question
elif user_choice.upper() == 'S':
# ask substracting question
else:
print('Sorry I did not understand your choice')
For repeating the code While loops are your choice, they will repeatedly execute a statement in them while the starting condition is true.
while True: # Condition is always satisfied code will run forever
# put your program logic here
if input('Would you like another test? [Y/N]').upper() == 'N':
break # Break statement exits the loop
The result of using input() function is always a string. We use a .upper() method on it which converts it to UPPERCASE. If you write it like this, it doesn't matter whether someone will answer N or n the loop will still terminate.
If you want the possibility to have another question asked use a while loop and ask the user for an input. If you want the user to input whether (s)he want an addition or substraction you already used the tools to ask for such an input. Just ask the user for a string.

Loop and validation in number guessing game

I have previously studied Visual Basic for Applications and am slowly getting up to speed with python this week. As I am a new programmer, please bear with me. I understand most of the concepts so far that I've encountered but currently am at a brick wall.
I've written a few functions to help me code a number guessing game. The user enters a 4 digit number. If it matches the programs generated one (I've coded this already) a Y is appended to the output list. If not, an N.
EG. I enter 4567, number is 4568. Output printed from the list is YYYN.
import random
def A():
digit = random.randint(0, 9)
return digit
def B():
numList = list()
for counter in range(0,4):
numList.append(A())
return numList
def X():
output = []
number = input("Please enter the first 4 digit number: ")
number2= B()
for i in range(0, len(number)):
if number[i] == number2[i]:
results.append("Y")
else:
results.append("N")
print(output)
X()
I've coded all this however theres a few things it lacks:
A loop. I don't know how I can loop it so I can get it to ask again. I only want the person to be able to guess 5 times. I'm imagining some sort of for loop with a counter like "From counter 1-5, when I reach 5 I end" but uncertain how to program this.
I've coded a standalone validation code snippet but don't know how I could integrate this in the loop, so for instance if someone entered 444a it should say that this is not a valid entry and let them try again. I made an attempt at this below.
while myNumber.isnumeric() == True and len(myNumber) == 4:
for i in range(0, 4)):
if myNumber[i] == progsNumber[i]:
outputList.append("Y")
else:
outputList.append("N")
Made some good attempts at trying to work this out but struggling to patch it all together. Is anyone able to show me some direction into getting this all together to form a working program? I hope these core elements that I've coded might help you help me!
To answer both your questions:
Loops, luckily, are easy. To loop over some code five times you can set tries = 5, then do while tries > 0: and somewhere inside the loop do a tries -= 1.
If you want to get out of the loop ahead of time (when the user answered correctly), you can simply use the break keyword to "break" out of the loop. You could also, if you'd prefer, set tries = 0 so loop doesn't continue iterating.
You'd probably want to put your validation inside the loop in an if (with the same statements as the while loop you tried). Only check if the input is valid and otherwise continue to stop with the current iteration of your loop and continue on to the next one (restart the while).
So in code:
answer = [random.randint(0, 9) for i in range(4)]
tries = 5
while tries > 0:
number = input("Please enter the first 4 digit number: ")
if not number.isnumeric() or not len(number) == len(answer):
print('Invalid input!')
continue
out = ''
for i in range(len(answer)):
out += 'Y' if int(number[i]) == answer[i] else 'N'
if out == 'Y' * len(answer):
print('Good job!')
break
tries -= 1
print(out)
else:
print('Aww, you failed')
I also added an else after the while for when tries reaches zero to catch a failure (see the Python docs or maybe this SO answer)

Python - Function calling problems

I just started learning python 2 days ago and Im trying to make some kind of text based adventure to practice , the only problem Im having is with functions:
def menu_op():
print('1- Action 1')
print('2- Action 2')
choice= input('Choose action: ')
return choice
def action_op(x):
if x == 1:
print('You chose action 1')
if x == 2:
print('You chose action 2')
menu_op()
action_op(menu_op())
The idea behind this is to call the menu function , which gives a value equal to user's input , which gets fed into the action function when the latter is called and does something depending on the user choice.
Cant tell what im doing wrong though , as the code doesnt seem to work.
Thanks in advance
It looks like you are using Python 3.x. In that version, input returns a string object like raw_input did in Python 2.x. This means that the return value of the function menu_op will always be a string.
Because of this, you need to compare x with strings rather than integers:
if x == '1':
print('You chose action 1')
elif x == '2':
print('You chose action 2')
I also changed the second if to elif since x could never equal both '1' and '2'.
You're calling menu_op() function twice. The first time it gets called choice is not passed to action_op()
menu_op() #return is not catched
action_op(menu_op())
And the value returned from menu_op is a string so you should compare strings in action_op instead of comparing x with integers
def action_op(x):
if x == 1:
^^^ #should compare strings here -> x == "1"
choice= int(input('Choose action: ')) # make choice an int to compare
In [1]: 1 == "1"
Out[1]: False
In [2]: 1 == int("1")
Out[2]: True
input is a string and you are comparing if x == 1 where x is "1"

Categories