How to make a lacing in Python Script

python

#1

Dear all,

I am trying to add some code lines to an existing python scrip node from a package to make it work as long lacing. The node that I want to modify is the Group.FromElements one.

This is the Python Script that we find inside the node and that only works by introduce a list of elements a name for the group but not a list sublists and a list of names:

    import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
from System.Collections.Generic import *

clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument
items = UnwrapElement(IN[0])
ids = list()
rejects = list()
for item in items:
	try:
		ids.append(item.Id)
	except:
		rejects.append(item)
items = List[ElementId](ids)

TransactionManager.Instance.EnsureInTransaction(doc)
try:
	group = doc.Create.NewGroup(items);
	group.GroupType.Name = IN[1]
except:
	group = list()
TransactionManager.Instance.TransactionTaskDone()

OUT = (group,rejects)

Any help would be much appreciated.
Best,

Sergio


#2

Can you paste your python code using Preformatted Text </>? It makes the code easier to read and copy if necessary.

Lacing is more of a Dynamo (visual) thing rather than a textual coding thing. You really just want to control the iteration or looping of the code. A for loop is probably what you’d want here, so that something is done for every item in a list, regardless of list length.


#3

Thanks so much Nick for your prompt reply. I have changed the text using Preformatted Text. I also reed that using a for or while loop I can achieve what I need but I do not know how. If you could modify the text that I have to introduce in the Python script, it would be much appreciated. Regards


#4

The code works, so I’m a little confused on what you’re trying to do. Can you show the rest of your graph and explain the part about lacing? Are you trying to create more than one group?


#5

Thanks again Nick. That’s exactly what I want to achieve, to create a list of groups from a list of sublist with the elements and with a list of names. Find the a screen shot attached. Kind regards


#6

Is there a reason you can’t just use the node? It allows you to using lacing for multiple groups.
The Python option would be to add another list so that rather than iterating through a single list of elements you iterate through a list of list of elements. (Iterate through sublists of grouped elements then iterate through each element in the sublist.)

There should be multiple examples of this already on the forums.


#7

Thanks Nick, the node works well but I am trying to learn how to modify a Python Scrpt to add the licing functionality. Definitely I have reed about the of and while loop functionality in different posts but I am still starting to learn about Python. I am struggling with this exercise so that is why I decided to post here. If you know exactly what should I write in the script, I would be really greatful.


#8

If you’re trying to learn Python then the best way to do that is to write the code yourself. Trial and error is a big part of learning to code.

You already have everything you need in your code. You just need to add an extra layer of iteration (another for loop). Instead of starting with a list of elements (items) you need to start with a list of grouped elements then get the items within those groups. As I said before, there are many posts on the forums that cover converting nodes to accept lists or lists of lists.


#9

I have been reading a lot about Python but still no success. If you could be a litle bit more specific that would be really appreciated. Kind regards, Sergio.


#10

Try getting a for loop to work for a single list of items. It’s no different to then loop for each item within a sublist within a list.


#11

What Nick proposes is Python lingo for lacing :slight_smile:


#12

What is being described it seems is carrying out a for loop within a for loop. I agree with @Nick_Boyts, this could be easily achieved by changing the lacing of the node being input.

But in python terms to access a nested list (this is assuming a 2 level list) would be :

for i in items: 
   for j in i: 
       do_something()

this is saying for each item in the top list [i] … then for every item within this list [j]…

think…

i[0],j[0]
i[0],j[1]
i[1],j[0]
i[1],j[1]
i[2],j[0]
i[2],j[1]

This will only work for a two-level list, if you want to access the most nested items you would need to look into a recursive function which tests for list lengths until you are down to single items.

Without looking too much into the code … from a brief glance it seems you would want to change

ids = list()
rejects = list()
for item in items:
    try:
	    ids.append(item.Id)
    except:
	    rejects.append(item)
items = List[ElementId](ids)

to

ids = [] # this is shorthand for a list 
rejects = []
for sub_list in items: # this will iterate through the top list
    for item in sub_list: # this will iterate through all items within the top lists 
        try:
	        ids.append(item.Id)
        except:
	        rejects.append(item)
items = List[ElementId](ids)

Hope this helps / makes sense

(I’m slightly to dubious as to how good a name sublist is here for a variable, but hopefully it serves to illustrate the point)