Я задаю пользователям ряд вопросов и записываю их ответы. Мои задающие вопросы проверяют форматирование этих ответов и возвращают флаг, если пользователь вводит что-то странное (например, my name is 102
).
Я бы хотел, чтобы эта программа сразу же вырвалась из набора вопросов, если какой-либо из этих ответов неверен. Я пытаюсь использовать цикл while для этого, но мне ясно, что этот цикл while проверяет только значение флага в конце каждого цикла, поэтому он не будет перезапускать процесс запроса вопроса до тех пор, пока блок вопросы сделаны.
Обратите внимание, что в этом примере переменная letter является суррогатом пользовательского ввода. На самом деле код выглядит не так.
def string_checker(letter, output):
if type(letter) != str:
print('You did not give me a string!')
output = 1
return output
output = 0
# this should go until question 3, when the user makes a mistake
while output == 0:
# question 1
letter = 'bob'
print(letter)
output = string_checker(letter, output)
# question 2
letter = 'aldo'
print(letter)
output = string_checker(letter, output)
# question 3 --- user gets this wrong
letter = 1
print(letter)
output = string_checker(letter, output)
# question 4
letter = 'angry'
print(letter)
output = string_checker(letter, output)
# but it seems to ask question 4, regardless
print('done!')
Есть ли способ изменить этот код, чтобы question 4
никогда не запрашивался?
ОБНОВЛЕННЫЙ КОД НА ОСНОВЕ ОТВЕТА ДЖАСПЕРА
Основываясь на ответе Джаспера с полным решением ... эта модификация моей проблемы решила ее. Поднимая ValueError внутри функции проверки, блок try немедленно выходит из строя, и мы можем выйти из main, используя return.
def string_checker(letter):
if type(letter) != str:
raise ValueError
def main():
# this should go until question 3, when the user makes a mistake
try:
# question 1
letter = 'bob'
print(letter)
string_checker(letter)
# question 2
letter = 'aldo'
print(letter)
string_checker(letter)
# question 3 --- user gets this wrong
letter = 1
print(letter)
string_checker(letter)
# question 4
letter = 'angry'
print(letter)
string_checker(letter)
# we make a mistake at question 3 and go straight to here
except ValueError as ve:
print('You did not give me a string!')
return 'oops'
# exit
return 'done'
for letter in ['x', 'y', 1, 'z']: print(letter); x = string_checker(letter, x); if x != 0: break
(разброс по нескольким строкам, с правильным отступом и без точек с запятой). Если вы увидите, что почти один и тот же блок кода повторяется 4 раза таким образом, у вас должно возникнуть дрожь - или у вас подергивается нос от запаха кода. (Возможно, есть более эффективные способы кодирования этого, но это будет простой шаг вперед.) - person Jonathan Leffler   schedule 22.07.2014print
операцию. Я не вижу, как переход от отдельных букв к строкам сводит на нет мои наблюдения об использовании списка, но тогда я не вижу разницы между созданием списка (возможно, во время выполнения) и записью списка от руки (окончательно, когда вы кодируете ); действительно, использование списка открывает путь к гораздо большей гибкости. Действительно, неясно, откуда берутся струны; возможно, вы скрываете от нас какое-то взаимодействие с пользователем, что затрудняет оценку. Однако это ваша проблема, а не моя. - person Jonathan Leffler   schedule 22.07.2014python
в начале заголовка. Если вы уже поместили эту информацию в теги, этого достаточно. Заголовок должен быть правильно сформированным предложением без случайных тегов. - person Bakuriu   schedule 22.07.2014input
python2, имейте в виду, что вы не должны использовать ее, поскольку она открывает огромные дыры в безопасности в вашей программе. Также для проверки данного типа используйтеisinstance(something, str)
, а неtype(something) == str
. Наконец, если длина кода зависит от количества вопросов, у вас все равно что-то не так. - person Bakuriu   schedule 22.07.2014