Search code examples
pythondictionaryfor-loopif-statementpyomo

How to include a if check into a for loop


I try add a constraint expressions to a python/pyomo model: the code I tried is this:

for r_k in VAR1: 
    for p_v in VAR2:
        for b_n in VAR3:
            IF mix[b_n][p_v]() >= 0:
                model.cons.add(model.func2[r_k,b_n,p_v]*q1[b_n][p_v] - model.func1[r_k,b_n,p_v] ==0)

If I leave the IF loop away it runs fine. The code above produces a Syntax error. Only downside is it creates 1000s of extra mathematically trivial constraints that are not needed.
"mix" is only a sparsely populated "binary" dictionary (i.e. mostly zeros, a few ones in between). A constraint is only needed where there is a "1". It seems there is an issue with evaluating/calling the dictionary values within the for loops. Any idea how to resolve this would be much appreciated. Thanks.


Solution

  • You've got two errors in your code:

    • if is lowercase in Python. IF does NOT exist in any of the standard modules
    • assuming mix is a dicitonary, you can't call it. By adding braces () behind a variable or anything in the scope, you tell python to treat it as a callable and try to execute it.

    Assuming the rest of your code works fine, this should solve your problem:

    for r_k in VAR1: 
        for p_v in VAR2:
            for b_n in VAR3:
                if mix[b_n][p_v] >= 0:
                    model.cons.add(model.func2[r_k, b_n, p_v] * q1[b_n][p_v] - model.func1[r_k, b_n, p_v] == 0)
    

    Further remarks:

    • if (and elif, else) is NOT a loop, it is a conditional statement! for or while are loops.
    • you check for mix[b_n][p_v] >= 0, but state that a constraint is only needed when "there is a "1"". So shouldn't your condition be mix[b_n][p_v] > 0 or even more explicitly mix[b_n][p_v] == 1? (Explicit is better than implicit, see The Zen of Python, second statement)