Python Forum
If with For statement shorthand? - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: If with For statement shorthand? (/thread-38121.html)



If with For statement shorthand? - kaega2 - Sep-06-2022

Is there a way to reduce code down?

for x in resources:
            if resources[x] < MENU[option]["ingredients"][x]:
                print(f"Sorry there is not enough {x}")
                resources_sufficient = False
I was thinking something like this, but obviously this doesn't work

if resources[x] < MENU[option]["ingredients"[x] for x in resources:
            print(f"Sorry there is not enough {x}")
            resources_sufficient = False



RE: If with For statement shorthand? - deanhystad - Sep-06-2022

It is custom to indent 4 spaces.

I cannot think of a way to reduce the code and still have it perform the same way. If you don't mind it doing something slightly different.
not_enough = [x for x in resources if resources[x] < MENU[option]["ingredients"][x]]
print(f"Sorry there is not enough {', '.join(not_enough)}")
resources_sufficient = len(not_enough) > 0
It doesn't shrink it down much.


RE: If with For statement shorthand? - bowlofred - Sep-06-2022

I think you have four separate ideas (the resources to examine, the conditional, the information to the user, the status for later), so putting that on four separate lines seems completely reasonable.

You could use a list comprehension, but I wouldn't necessarily prefer it.

insufficient_resources = [k for k,v in resources.items() if v < MENU[option]["ingredients"][k]]
if insufficient_resources:
    print(f"Sorry there is not enough {','.join(insufficient_resources)}")

# or
insufficient_resources = [k for k,v in resources.items() if v < MENU[option]["ingredients"][k]]
for ingredient in insufficient_resources:
    print(f"Sorry there is not enough {ingredient}")
Rather than setting resources_sufficient as a separate variable, you can just test the truthiness of insufficient_resources.


RE: If with For statement shorthand? - deanhystad - Sep-06-2022

I think your code is backward. Your logic crashes if your resources contains ingredients that are not in MENU[option]["ingredients"]. In other words, each recipe on your menu must use every ingredient in your inventory (resources).

I would do this:
ingredients = {"A": 10, "B": 15}
resources = {"A": 11, "B": 5, "C": 5}

resources_sufficient = not any(
    [x for x in ingredients
        if resources[x] < ingredients[x]
    ]
)
print(resources_sufficient)
Output:
Sorry there are not enough B True
Well, I wouldn't really do that because the comprehension is mostly used for a side effect, and that is bad programming. I would write it this way:
ingredients = {"A": 10, "B": 15}
resources = {"A": 11, "B": 5, "C": 5}

missing_ingredients =  [x for x in ingredients if resources[x] < ingredients[x]]
if missing_ingredients:
    print("You are missing", ",".join(missing_ingredients))
And use missing_ingredients for it's bool equivalent (False if empty, else True).


RE: If with For statement shorthand? - kaega2 - Sep-06-2022

Thank you so much for all your wonderful replies!

I had seen examples where list comprehension shorted code down so much that I was hoping there was a way to do it here.

Thank you to those who gave suggestions for the overall program as well. I'm really just trying to get my head wrapped around some of the little details of the coding before moving on to my next lesson. But thank you still

Jamie


RE: If with For statement shorthand? - Gribouillis - Sep-06-2022

I would favour
missing_ingredients = [
    x for (x, needs) in MENU[option]['ingredients'].items() if needs > resources.get(x, 0)]
Now if you only want to know if at least one ingredient is missing, choose
if any(needs > resources.get(x, 0) for x, needs in MENU[option]['ingredients'].items()):
    print("At least one ingredient is missing.")