Complex If/And/Else Statements

Hello! I’m fairly new to Dynamo. I am trying to do something that looks like this using a standard Revit formula:

if(and(x > 0, y > 0), if(x > y, x - y, y - x), if(and(x < 0, y < 0), if(x > y, x + -y, y + -x), if(x < 0, y + -x, x + -y)))

It is actually pretty simple with two integer inputs and one integer output but has a whole bunch of conditions.

The Formula Node won’t accept it, what is the most streamlined way to do this without a ton of nodes?

Thanks!

Sorry for me not understanding but where are you trying to put this formula?

The inputs are parameter values taken from elements and the output is a parameter value being inserted into same elements. I got that part working well.

Sorry i should have targeted the question more.
-Are the forumlas inside a family parameter or are they part of a sheet parameter etc etc… where exactly is it going?

I want to place this formula in a Dynamo node.

This formula I quoted above as an example was part of a schedule as a calculated value (but had actual parameter names instead of x/y). The input parameters are built-in parameters (start/end level offset = x/y) and the result of the calculation is inserted into a separate family parameter. I want to use Dynamo to set a family parameter value, I can’t do this in the family because it is using built-in parameters as part of the formula.

It looks like an absolute function for x - y, e.g. difference between two levels as a positive value
I’ve broken the logic down in python, hopefully you can follow along

def calculate(x, y):
    if x > 0 and y > 0:  # both positive
        if x > y:
            result = x - y
        else:
            result = y - x
    elif x < 0 and y < 0:  # both negative
        if x > y:
            result = x - y
        else:
            result = y - x
    else:  # one pos, one neg or at least one equals 0
        if x < 0:
            result = y - x
        else:  # x = 0 and y is any value, or y <= 0 and x >= 0
            result = x - y # if x = 0 and y pos returns negative number

    return result

# Why not abs?
calc_output = []
abs_output = []

for x in range(-1, 2): # [-1, 0, 1]
    for y in range(-1, 2):
        calc_output.append(calculate(x, y))
        abs_output.append(abs(x - y))

print(calc_output)
print(abs_output)

Result

[0, 1, 2, 1, 0, -1, 2, 1, 0]
[0, 1, 2, 1, 0, 1, 2, 1, 0]

You can see that the logic is flawed in that it does not catch the edge case of x = 0 and y is positive resulting in a negative answer

The Revit parameter formula for this is abs(x - y) or you can use Math.abs node

1 Like

Wow thanks, much appreciated. What a great community. I will give this a whirl tomorrow and see if I can improve it, or just use the abs formula. I can just pop this in a Python node correct?

But yes, I want to take two values (start level offset and end level offset) and use them to determine the rise of a structural member, sometimes these parameters may be negative to the level and sometimes positive, zero is unlikely but theoretically possible. I’m sure there are more common dynamo-centric ways of extracting this geometry (which is used to determine the vertical slope of an element), which I will try to tackle next, but I wanted to see if this would work.

This is what my first attempt looks like, I tested numerous scenarios, including with 0 values, and have been unable to break it (though I bet I will eat those words lol.) It reports the rise of inputted structural framing elements using start level offset and end level offset values as inputs.

> # Load the Python Standard and DesignScript Libraries
> import sys
> import clr
> clr.AddReference('ProtoGeometry')
> from Autodesk.DesignScript.Geometry import *
> 
> # The inputs to this node will be stored as a list in the IN variables.
> StartLevelOffset = IN[0]
> EndLevelOffset = IN[1]
> 
> #Create an empty list for the result
> rise = []
> 
> # Calculate the rise of an element using Start Level Offset and End Level Offset Parameters
> 
> def calculate(x, y):
>     if x > 0 and y > 0:  # both positive
>         if x > y:
>             result = x - y
>         else:
>             result = y - x
>     elif x < 0 and y < 0:  # both negative
>         if x > y:
>             result = x - y
>         else:
>             result = y - x
>     else:  # one pos, one neg or at least one equals 0
>         if x < 0:
>             result = y - x
>         else:  # x = 0 and y is any value, or y <= 0 and x >= 0
>             result = x - y # if x = 0 and y pos returns negative number
> 
>     return result
> 
> listnum=0
> 
> for i in StartLevelOffset:
>   rise.append(calculate(StartLevelOffset[listnum],EndLevelOffset[listnum]))
>   listnum=listnum+1
> 
>   
> # Assign your output to the OUT variable.
> OUT = rise

So now I’ve got to ask… what is the “Dynamo way” to calculate the rise of an element? (I say “Dynamo way” because Dynamo seems to be all about extracting and outputting geometric data and I assume there is a way to do this with nodes.)

Learned so much since this post! Here is an update for anyone reading in the future -

The very simple Dynamo way to calculate the rise of an element is to get the Z Values from the start and end points (in this case with a simple Element.GetLocation node, then Curve.StartPoint/Curve.EndPoint, then Point.Z,), and then get the absolute value of either of them subtracted from the other (there is a Math.Abs node, probably a simple way to put this in a code block as well.) None of that Python script was necessary. But it was great to do to start learning Python scripting, and this is the way to do more complex logic operations.

2 Likes