The code below is based on this recipe. However, the key point of the recipe - that it provides a way to break out of the iteration on an iterator if the iterator is empty - doesn't seem to work here, instead behaving in the following undesired ways:
- If get_yes_no_answer() == False and there are two or more items left in the iterator, next_choice is skipped, rather than being selected on the next iteration.
- If get_yes_no_answer() == False and there are less than two items left in the iterator, my_func() returns None.
How can I ensure that:
- If get_yes_no_answer() == False and there are two or more items left in the iterator, next_choice is not skipped?
- If get_yes_no_answer() == False and there is one item left in the iterator, my_func() prints it and calls get_yes_no_answer()?
- If get_yes_no_answer() == False and there are no items left in the iterator, the except StopIteration clause is triggered?
Here's the code:
def my_func(choice_pattern, input):
# Search in input for some things to choose from.
choice_iterator = choice_pattern.finditer(input, re.M)
if not choice_iterator:
print "No choices. Exiting..."
sys.exit()
else:
# Show choices to the user. For each one, ask user for a yes/no response. If
# choice accepted, return a result. Otherwise show user next choice. If no
# choices accepted by user, quit.
for choice in choice_iterator:
print choice.group()
# get_yes_no_answer() returns True or False depending on user response.
if get_yes_no_answer():
return choice
else:
# Check if iterator is empty. If so, quit; if not, do something else.
try:
next_choice = choice_iterator.next()
except StopIteration:
print "No matches. Exiting..."
sys.exit()
else:
choice_iterator = itertools.chain([next_choice], choice_iterator)