This code aims to check whether inputs are in a pre-determined list and, if not, force the user to start over again.
I understand I can use a FOR or WHILE loop and have the IF and ELSE lines nested in the loops. However, I've realised this gets rather messy and tedious on a large scale.
Is there a way to send read previous lines of code after a loop has been exited? The line that concerns us is the one with the "#problem area"; here is my code:
# Variables:
healthy = ["potato", "tomato"]
counter_ = 0
limit_ = 3
while counter_ < limit_:
shopping_list = []
wanted_item = input("What to get? \n").lower()
if wanted_item not in healthy:
counter_ = 1
print("Try again")
continue
if wanted_item in healthy:
shopping_list.append(wanted_item)
break
else:
break
if counter_ >= limit_:
print("Start over")
#problem area
else:
print("That's a good list")
print(shopping_list)
CodePudding user response:
You can try this. This can cause an infinite loop if the input is never a "potato" or "tomato".
healthy = ["potato", "tomato"]
counter_ = 0
limit_ = 3
while counter_ < limit_:
shopping_list = []
wanted_item = input("What to get? \n").lower()
if wanted_item in healthy:
shopping_list.append(wanted_item)
break
else: # if wanted_item not in healthy
counter_ = 1
print("Try again")
continue
if counter_ >= limit_:
print("Start over")
counter_ = 0
CodePudding user response:
You are talking about a goto
mechanism; and my answer is no, such a thing does not exist in Python. Thank God.
I've realised this gets rather messy and tedious on a large scale.
I think this is a strong misconception. Especially on large scale, goto
becomes absolutely unmaintainable. (Although some people probably disagree)
But ending my anti-goto-rage, let's see how your code can be refactored to do what you want while still being readable and maintainable, to demonstrate that it's in most cases just a matter of thinking about code structure.
Let's first refactor your while
loop:
- the second
if
breaks in both cases, so just move thebreak
out:
while counter_ < limit_:
shopping_list = []
wanted_item = input("What to get? \n").lower()
if wanted_item not in healthy:
counter_ = 1
print("Try again")
continue
if wanted_item in healthy:
shopping_list.append(wanted_item)
break
- both
if
s are opposed to each other, so let's make anelse
statement instead and let's move thebreak
back in (because thebreak
is only reachable in theelse
case, as otherwisecontinue
would be hit)
while counter_ < limit_:
shopping_list = []
wanted_item = input("What to get? \n").lower()
if wanted_item not in healthy:
counter_ = 1
print("Try again")
continue
else:
shopping_list.append(wanted_item)
break
- let's switch the
if
andelse
case:
while counter_ < limit_:
shopping_list = []
wanted_item = input("What to get? \n").lower()
if wanted_item in healthy:
shopping_list.append(wanted_item)
break
else:
counter_ = 1
print("Try again")
continue
- ditch the
continue
because it is now redundant, and remove theelse
as theif
is alreadybreak
ing, so everything after theif
is automatically theelse
:
while counter_ < limit_:
shopping_list = []
wanted_item = input("What to get? \n").lower()
if wanted_item in healthy:
shopping_list.append(wanted_item)
break
counter_ = 1
print("Try again")
So this is as far as I can help:
healthy = ["potato", "tomato"]
counter_ = 0
limit_ = 3
while counter_ < limit_:
shopping_list = []
wanted_item = input("What to get? \n").lower()
if wanted_item in healthy:
shopping_list.append(wanted_item)
break
counter_ = 1
print("Try again")
if counter_ >= limit_:
print("Start over")
#problem area
else:
print("That's a good list")
print(shopping_list)
I'd like to help you further, but it's unclear from your code what you are trying to achieve.
- Why do you
break
after the first correct item is entered? - Why do you want to start over? Like, what's the criterium? That a person entered more than
limit
items incorrectly? What do you mean withstart over
? Back to the start? - Is it intentional that you empty the shopping list in every loop iteration?
I'll continue my refactoring as soon as I get answers.
CodePudding user response:
so if your only issue is that you want to call code again and again until someone has inputted a desired value you can make use of a recursive function
we define a function (here just called function). Everything except the declaration of the healthy array into it. So when the function is now called (with the expression "function()") it will just run the code once like it did in your example. But defining that chunk of code as a function gives us the opportunity to call it again and again and again, so every time the function is called the code inside the function runs from top to bottom.
Now coming to the "problem area" - calling the function() itself right here will call the function each time we reach the "Try again" part of our if statement. -> so we start from the top again.
We will only leave the function if we reach the point where the function does not call itself, which is at "This is a good list"
all we need to do now (after doing the function definition part, is to call the function (this is done by writing function())
I use functions (to be more precise a recursive function) - so if you need additional resources you can use those keywords ("function" - "recursive function") to find them I would highly advise you to get familiar with functions ... functions are an essential part of most programming languages
healthy = ["potato", "tomato"]
def function():
limit_ = 3
counter_ = 0
while counter_ < limit_:
shopping_list = []
wanted_item = input("What to get? \n").lower()
if wanted_item not in healthy:
counter_ = 1
print("Try again")
continue
if wanted_item in healthy:
shopping_list.append(wanted_item)
break
else:
break
if counter_ >= limit_:
print("Start over")
function()
else:
print("That's a good list")
print(shopping_list)
function()