[英]User input - validation and confirmation -
I am trying to perform something that has certainly been asked several times before (specifically Asking the user for input until they give a valid response , but I'm either trying to do something too complex or not thinking about my loops the correct way. 我正在尝试执行某些之前肯定会被要求执行的操作(特别是要求用户提供输入信息,直到他们给出有效的响应为止 ,但是我正在尝试执行过于复杂的操作或没有以正确的方式考虑循环。
In the code below, I am trying to do a few things: 在下面的代码中,我正在尝试做一些事情:
loan_ids
) loan_ids
) In the second func, I am trying to combine the first one and then also ask the user to confirm the loan_ids
before cutting out: 在第二个func中,我尝试合并第一个func,然后还要求用户在
loan_ids
之前确认loan_ids
:
y
, then end the loop y
,则结束循环 n
, go back to the first function and ask again n
,请返回第一个功能并再次询问 I'm trying not to violate the Don't Repeat Yourself principle, but for the life of me I can't figure out the placement of the loops. 我试图不违反“不要重复自己”的原则,但是对于我一生,我无法弄清楚循环的位置。 I'm also relatively new to python and programming structure, so open to idiomatic comments on the design as well
我对python和编程结构还比较陌生,因此也欢迎对设计发表惯用的评论
def get_unique_loans_from_user():
"""Get list of loan_ids from user
This function is mean to capture raw loan_ids a user wishes to look up.
Returns tuple of unique loan_ids
"""
loan_ids = []
while True:
loan_id = raw_input('> Loan Id: ')
# If nothing entered, exit
if len(loan_id)==0:
break
# Make sure an integer was entered
else:
try:
int(loan_id)
except ValueError:
print loan_id + " is not a real integer, so likely not a valid loan id"
continue
# if an integer was entered, append to running list as an integer and continue
# We only need to return the unique list of loan ids
else:
loan_ids.append(int(loan_id))
# Convert unique list of loans to tuple to use in SQL
loans = tuple(np.unique(loan_ids))
# Return the tuple of loans
return loans
And the second piece - the way it's currently written forces the same result when a user enters anything but y
- I'm trying to cause different behavior depending on whether the use has invalid input vs. actually confirms the loan_ids
are incorrect. 第二部分-当前编写的方式会在用户输入除
y
任何其他内容时强制产生相同的结果-我试图根据用户使用的输入是否无效而实际导致的loan_ids
错误,从而导致不同的行为。 I also have used an extra break statement at the end, which I'm fairly sure is not best practice 最后,我还使用了一个额外的break语句,我敢肯定这不是最佳实践
def confirm_loan_ids():
""" Confirm the list of loan ids is what the user wanted"""
while True:
# Get loan ids from user through raw input
ids = get_unique_loans_from_user()
# Print out the ids to the user
print "Printing loan ids. There are {0} ids".format(len(ids))
print ids
# Confirm with user these are the correct ids
answer = raw_input('> Are these the loan ids you expected? [y/n] ')
# If user confirms correct, and continue
if answer == 'y':
print "\nExcellent - moving on\n"
print "Here are your loan ids:"
print ids
break
# If the answer is n, repeat the question
elif answer == 'n':
print "\n-------------> Let\'s try again\n"
continue
# If answer is not no or yes, ask again
elif (len(answer) == 0) or (answer not in ('y','n')):
print "Please enter only y or n"
continue
else:
print "This is only a test"
# The If loop only breaks when the answer is 'y'
break
return ids
Try this. 尝试这个。 It reduces some of the requirements to use
continue
, instead letting the loop naturally iterate again. 它减少了使用
continue
一些要求,而让循环自然地再次迭代。 This reduces visual noise in the code. 这样可以减少代码中的视觉噪声。
For your second function, you can again simplify the logic to remove the need to use continue, instead only breaking when the input is good. 对于第二个功能,您可以再次简化逻辑以消除使用继续的需要,而仅在输入良好时才中断。
The code needs to loop again for the yes/no confirmation, so to avoid issues with having to break out of nested loops, the yes/no loop is in another function. 代码需要再次循环以进行“是/否”确认,因此为避免必须退出嵌套循环的问题,“是/否”循环位于另一个函数中。 This function won't return until a valid input is received.
在收到有效输入之前,此函数不会返回。
Hopefully this gives you some slightly clearer logic to work with? 希望这使您可以使用一些更清晰的逻辑?
You can reinstate your numpy.unique
function if you want instead of set
, but I don't generally use numpy
and importing it just for that purpose seems a bit excessive I used set
instead. 如果需要而不是
set
,可以恢复numpy.unique
函数,但是我通常不使用numpy
,并且仅出于此目的导入它似乎有点过分,而我改用set
。 I don't know your exact requirements, so don't know if set
or numpy.unique
is more appropriate. 我不知道您的确切要求,所以也不知道
set
或numpy.unique
是否更合适。
from __future__ import print_function
def get_unique_loans_from_user():
loan_ids = []
while True:
loan_id = raw_input('> Loan Id: ')
try:
loan_id_int = int(loan_id)
if loan_id_int == 0:
break
loan_ids.append(loan_id_int)
except ValueError:
print("%s is not a real integer, so likely not a valid loan id" % loan_id)
# note: this will alter the order.
return tuple(set(loan_ids))
def yesnoconfirm(msg):
while True:
answer = raw_input(msg)
if answer in ('y', 'n'):
return answer
else:
print('not a valid input')
def confirm_loan_ids():
while True:
ids = get_unique_loans_from_user()
print("Printing loan ids. There are {0} ids".format(len(ids)))
print(ids)
answer = yesnoconfirm('> Are these the loan ids you expected? [y/n] ')
if answer == 'y':
break
elif answer == 'n':
print("\n-------------> Let\'s try again\n")
else:
print("oops something went wrong")
print("\nExcellent - moving on\n")
print("Here are your loan ids:")
print(ids)
return ids
print(get_unique_loans_from_user())
raw_input('continue?')
confirm_loan_ids()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.