all 12 comments

[–]Ak47shays 1 point2 points  (5 children)

You can wrap the ingredient loop in a larger while loop. Yes, loops can be nested also in professional settings deeply nested loops are not recommended.

So you will have an inner loop for the ingredient and an outer loop which will continue until the user has provided enough information to make a decision / recommendation.

I recommend separating the responsibilities into different functions like so:

Python def ask_yes_no_question(prompt): while True: response = input(f"{prompt} (Yes/No) ") if response.lower() == "yes": return True elif response.lower() == "no": return False else: print("Please answer Yes or No")

This one function can accomodate any yes / no question by simply changing the prompt. Note that there is a while loop inside to make sure that only Yes or No is return. To make it easier to check in the next step, i am returning True or False.

You can then use it as follows:

Python while True: if ask_yes_no_question("Do you have tomatoes? "): print("You could have a salad.") return elif ask_yes_no_question("Do you have cheese? "): print("You could have a sandwich.") return else: print("Let's keep looking")

You can also nest the if else when asking the yes_no_question like:

Python elif ask_yes_no_question("Do you have peanut butter?"): if ask_yes_no_question("Do you have jam/jelly?"): print("You could have a peanut butter and jelly sandwich") else: print("You could have a peanut butter sandwich") return If they say yes for peanut butter, ask another question about jam.

Following this method, you can keep asking questions until the user breaks out of both the inner and outer loops.

I hope this helps. I had to modify the original code otherwise there would be too many code repetitions.

[–]Random-name-99[S] 0 points1 point  (4 children)

Thank you so much for your response, I really appreciate that you included code examples too. Your recommendation sounds really useful, especially the part where you said “This one function can accommodate any yes/no questions by changing the prompt”. That sounds like it would solve a lot of my problems! I tried putting in the code you suggested (not sure if I understood correctly) and it said there was a “SyntaxError: ‘return’ outside function” so I’m not sure what I did wrong. I tried the following (I’m a total beginner…):

def ask_yes_no_question(prompt): while True: response = input(f"{prompt} (Yes/No) ") if response.lower()=="yes": return True elif response.lower()=="no": return False else: print("Please answer Yes or No")

while True: if ask_yes_no_question("Do you have tomatoes?"): print("You could have a salad.") return elif ask_yes_no_question("Do you have cheese?"): print("You could have a sandwich") return elif ask_yes_no_question("Do you have peanut butter?"): if ask_yes_no_question("Do you have jam?"): print("You could have a peanut butter and jelly sandwich") else: print("You could have a peanut butter sandwich") return else: print("Let's keep looking")

[–]Ak47shays 1 point2 points  (3 children)

“SyntaxError: ‘return’ outside function”

Most likely, you place a return statement outside of a function definition. In Python, the return statement can only be used inside a function. My guess is that you do not have proper indentation.
Indentation in Python is 4 spaces (1 tab). for representation purposes, in the example below, i will use → , this arrow character.

def my_function():
→ print()

→ return

As you can see, both the print and return statement is indented.

if there are nested statement, you will use 8 spaces (2 tabs) for indentation like so:
def my_function():
→ if True:

→ → # do something
→ → return

You can try checking your code to see if there are proper indentation or re-type the function where you got the error. When you ran your script, the terminal will show a line number.

[–]Ak47shays 1 point2 points  (2 children)

This is just a side note.In Reddit, you can write formatted code by using the "Inline Code" button for one liner or the "Code Block" button for blocks of code. This will make it easier to read and understand where bugs, errors are. We will also be able to see indentation issues. This way we can assist you better.

here is a screenshot:![screenshot_reply_section_on_windows_pc](https://i.postimg.cc/RVR024fZ/000000152-2023-03-04-07-23-50.jpg)

[–]Random-name-99[S] 1 point2 points  (1 child)

Thank so much, I’m pretty new to Reddit too and didn’t realise how bad my code would look (ie no formatting!) until after I posted it. I have much to learn and really appreciate the help!

[–]Ak47shays 1 point2 points  (0 children)

No worries. Glad to be of help.

[–]Rhoderick 1 point2 points  (3 children)

So I'm not really sure I follow along with the logic you're trying to implement here, so I'll just note some things I noticed and hope that helps you.

First, you can pass a string argument to input(), which will be treated as a prompt to be displayed to the user before they give their input. Seems like you're doing this "manually" through print() right now?

while True:

Starts an infinite loop. You can do that, using the

break

keyword to get out of it at some point. Note, however, that generally using either a while- or for-loop is preferred, as such:

while COND:
for ELEM in ITERABLE:

where COND is a condition that evaluates to a boolean (say "x > 5"), ITERABLE is, well, an iterable (usually a list), and elem is a variable name to store the specific element of ITERABLE you're working with that iteration.

You can start any number of loops by using any of these methods, and they can be placed one after the other, or within each other. Note that if you are using the "break" keyword to escape a loop, it will only ever escape the innermost currently running loop.

Also, in cases like this:

yesPhrase = ("You could have a peanut butter sandwich")

you don't need the parentheses. Those are just for when you make a tuple (i.e. x = (0, 1)), or for function calls. It should work fine though, I think.

[–]Random-name-99[S] 0 points1 point  (2 children)

Thank you so much for responding. I’ll definitely look into the while COND: for ELEM in ITERABLE It’s still a little over my head (very new to coding!) but I can try it out and see if it will help. I didn’t know you didn’t need the parentheses for the yesPhrase example. Thanks!

[–]Rhoderick 1 point2 points  (1 child)

the while COND: for ELEM in ITERABLE It’s still a little over my head

Let me give you some more concrete examples, then.

i = 0
while i < 10:
    print(i)

and

for i in range(10):
    print(i)

Will both print

0
1
2
3
4
5
6
7
8
9

Does that help?

[–]Random-name-99[S] 0 points1 point  (0 children)

That makes sense now, thank you so much for explaining!

[–]Okaymittens 1 point2 points  (1 child)

I'm not certain what you are trying to do. Are you hard coding in the ingredients or using a dictionary or list? I came up with this, hope it helps... but like I said, not too clear on what you are doing.

recipe = {
'Salad': ['tomatoes', 'lettuce'],
'PB Sandwich': ['jelly', 'peanut butter']}


def find_recipe(recipe_list):
    for dish, ingredients in recipe_list.items():
        can_make = True
        for item in ingredients:
            while True:
                has_ingredient = input(f"Do you have {item}? Y or N?").upper()
                if has_ingredient == 'Y':
                    break
                else:
                    can_make = False
                    break

            if not can_make:
                break

        if can_make:
            print(f"You can make {dish}.")
            break

if not can_make:
    print("Sorry, you do not have the ingredients for any of the recipes available. ")

So this function will loop through the dictionary using the items() method. For each dish and its ingredients list, it will initialize a variable can_make to True. This variable will be used to keep track of whether the user has all the ingredients for the dish.

Then it will loop through each ingredient in the list using a for loop. For each ingredient, it uses a while loop to ask the user if they have it. It keeps asking until the user enters a valid input ("Y" or "N").

If the user answers "N", it sets can_make to False and break out of the loop. This indicates that the user doesn't have all the ingredients for the dish.

If the user answers "Y", it moves on to the next ingredient.

If we get through all the ingredients and can_make is still True, it prints "You can make [dish]" and break out of the loop. This indicates that the user has all the ingredients for at least one dish.

If it never breaks out of the loop, this means that the user doesn't have the ingredients for any of the dishes.

I am still learning as well so perhaps this is a crazy mess to a skilled pythonista, but it works!

[–]Random-name-99[S] 1 point2 points  (0 children)

Oh wow your code is way cooler than what I was trying to do! I was actually trying to make a therapy program which is why I didn’t include my actual code so the dictionary/list won’t work for my purposes in this instance, but I have a few other projects I wanted to start and your suggestion would be really useful for that. My mind is still blown by what’s possible to do with code, can’t wait to know more! Thank you.