I have a script that needs updating for using with Revit 2023 that utilizes the ‘If’ node.
It works fine for 2022 and before. When I open it in 2023, Dynamo tells me I should update it if I want to keep using it when it is phased out in the future.
When I try to use the latest version instead, it doesn’t work the same.
I tried a few things, but just wasn’t getting anywhere with it…
I have a list of numbers that I want rounded to the nearest even number.
I use ‘If’ to test if the number is odd - if so, add ‘1’ to it. If not, just give me the number in the list.
With the old ‘If’, there is not an issue with the list length.
With the new ‘If’ node, from a list of 327 items, I get a new list of 106,929 items. It’s multiplying the list length by itself.
There is a note included with the new version of the node, but it doesn’t make sense to me.
Can someone help me understand why it is doing this now?
Much appreciated!
I’ve found the best way to get consistent if behaviors is to dive into Python. A zip iteration can work through the lists vs treat them as objects, which the new node appears to be doing.
tests = [True, False, False]
trues = ["a","b","c"]
falses = [1,2,3]
outcomes = []
for b,t,f in zip(tests, trues, falses):
if b:
outcomes.append(t)
else:
outcomes.append(f)
print(outcomes)
IMO this is just moving ‘when the pain hits’. Maybe it’s just me dealing with the consequences of 1000’s of un-mitigated changes over 7 years at Autodesk, but I would whole heartedly avoid this.
The problem is that when the Python inevitably breaks (see prior sentence) this makes it so the users have to find every instance of a simple if statement that was placed as a Python node with no identifier in terms of node name, comment, or other data point that parses readily.
Don’t get me wrong on this - if your graphs and library is unorganized and unstructured than it’s likely fine. Put out he fires as the pop up. But if you want to be systematic about it and proactive so that the deployed graphs work, I recommend swapping the old If node for the new one.
Place the new node and leave the lacing on Auto
and se the input for true and false to use @L1 list level. This is 90% what the previous node was used for - a single true/false to pass the shorter list of the inputs.
The next most common use case is to set the test input to also use @L1 input. From what I’ve seen/edited (a few hundred graphs) this covers 99% of things. For the outliers I wound up refactoring anyway and didn’t have to rework anything.
Net result on the 99% of the cases has been 10 minutes of work and the Dynamo team owns the updates going forward (while the Python, IronPython/PythonNet, the Dynamo team and you own the Python node solution).
2 Likes
If the if node was consistent performant from build to build I’d agree.
Python will generally be far more dependable in my experience for forcing iteration behaviors than assuming the goalposts don’t move from build to build (and not get worked back into old builds). I agree it’s not going to be a long term solution given the engine changes from build to build. My code is CP3 compatible though so should be pretty consistent from Revit 2021+ ideally, assuming CP3 is hanging around in the mid-long term.
It’s that 1% that will discourage users from engaging with Dynamo I’m finding more often than not. One ‘script ran with errors’, and they’re generally running back to add-ins.
Considering there is a Python project on the currently underway roadmap, we know things will change. What isn’t known is if they will be detrimental to any code. This simple If script? More likely not. There’s other stuff on the roadmap which also has me conscious of Python use, but that is admittedly more niche.
And as I’ve recently worked with a company which had about a thousand Iron Python 2 nodes in their graph library… Well I’ve seen how bad things can get in the upgrade front when things don’t work out. And the most common one which needed to be touched was actually a If node written to perform like the updated If node… Admittedly I might be bitter on this one of all that, but I also don’t want to see someone have to rework things significantly on their own when they could let Dynamo manage it.
As far as comparing a fully developed add-in to Dynamo… if there is a purpose built add-in for the task at hand which has been made functional in their build and is accessible, yes use that. There are a lot more benefits and features which such a tool can take advantage of that has already been handled. But:
- Many Dynamo uses don’t have a commercial equivalent add-in;
- Of those which there is an add-in available they are out of the firm’s price range;
- And more still aren’t available for a particular situation (new Revit release or update; systems where other add-ins need to call a common dependency and neither handle namespace collision; etc.);
- Often the timeline to procure an otherwise viable tool exceeds the project timeline (I once was told ‘good news we bought an add-in to fix that thing’ for an issue I had to deal with 8 months prior);
- And where the stars align and none of the above block release, most forms don’t have a resource to identify, test, and deploy such uses in a timely manner (how long does it take most firms to roll out new Revit releases?);
Granted you’re fortunately skilled enough to be able to do such development on your own, and many developers and community members are also in that boat. But Dynamo exists to make it easy for the 99% of users to get into programming, not to replace the existing customization ecosystem.
And so if it is one node in a small library, sure Python away. But if it is a larger effort, don’t switch to a custom script when an out of the box node exists.
1 Like
Since I sort of derailed things for @ahensley76YSD, I thought I would post some design script which I think will remove the need for an If statement and calculating the number and one more than the number for a lot of integers:
incrementedOdds = Math.Round(x/2)*2;
A code block containing that has likely been supported since before Dynamo even existed, but certainly since Dynamo 0.62, so you likely have a few years of use our of it as it’s been stable for over a decade now.
You could also implement a Python equivalent too. Both of those would also likely outperform having to manage a list of all the numbers a list of all the numbers plus 1, and the list of boolean values - at a minimum you’ve got 3274 values in memory right now, but the design script above or a Python version will reduce that to 3272 - the initial state and the final state.
You should also be able to use ‘Auto’ lacing with all inputs set to @L1 on the new If node to get the result you are after.
Lots to chew on here - love it. Thank you both.
First, the solution:
@jacob.small: Both options worked - I had tried messing with levels before reaching out, but I didn’t go down to L1.
Setting just the True and False inputs to L1 wasn’t enough - I did have to set the ‘test’ input to use levels, also. (Both L1 and L2 for that input gave the same results, and what I needed.) And now I know that the node still seems to basically do the same thing, with a few tweaks. That was a main question.
The second option you mentioned - using Design script: This worked, although I had an error message: “Multiple definitions for ‘Math’ are found as DSCore Math, Orchid.Common.Math” (I have Orchid installed) - so I deleted ‘Math’ and re-typed it - Dynamo then added ‘DSCore’ to the front. After that, it did just what I needed. (in case anyone else tries this)
I tried the Python suggestion last night, but it wasn’t quite what I needed. Now I can’t get it to return results for a screen shot this morning.
The screen shot shows all three options for anyone interested.
Extra info - what I was ultimately working toward was getting two lists of even numbers (length params in a glass family) to calculate a newly adjusted area using the nodes.
I’ll probably stick with using the ‘If’ node with the newer settings for now. I use it in some other scripts for other purposes, so hopefully I can do that same fix if needed.
Other comments - @GavinCrump: I appreciate the Python script idea, but I have very little experience with it. I wish I did! Seeing how easy it can be to fix things makes me want to learn more. I just don’t have the free time to dive into it. So I do like to take advantage of what comes with Dynamo / Revit installs as much as possible.
A lot of good points made in the comments from you guys. My main concerns as a Revit and script developer are about deployment and package management - I try to keep scripts to using the default installs as much as possible
-We probably won’t be doing add-ins any time soon - it will likely just be me continuing the development for the foreseeable future unless we use Revit in more phases (I hope) in the future.
Using the default nodes and figuring things out ‘when the pain hits’, as Jacob mentioned, is best in my situation for now (and I get to keep learning that way).
P.S. I marked this response as a the solution because I wanted to show the conversation, and that two options worked.
3 Likes
No worries - totally respect that Python is more a workaround vs a direct solution. Jacob is very much right that it is one a developer focused resource would need to support, as I do have to where I work (I spend at least 25% of my week in Python in one form or another these days). I stuck with OOTB/packages approach for quite a while until Dynamo became more of a tool for ‘me’ vs having to distribute it out to team members as well, so it’s sound logic.
I look forward to seeing stability and consistency improve as we move into the future of Dynamo.
In case it serves as a learning resource in future exploration, I’ve attached it in a Dynamo script so the implementation is clear - I wrote the example in a more general Python sense so it needs some adjustment to work in Dynamo vs as written.
zip and split.dyn (6.9 KB)
3 Likes
That’s great, thank you for the additional clarification with the sample file. I’ll give it a try.
Thank you!
2 Likes