Python Def not looping through all items

Hello all!

I previously found a solution to extract the element type, and name from an import instance. I’m now trying to use that code as a definition, and it seems like it only loops through one of the items in the list. I tried doing another for loop for the cad import instances but I get an iteration over non-sequence of type error. I’m not 100% sure but it seems like I’m looping wrong. Here is a screenshot of my python and the information going into IN[1] is a true bool.

Thanks in advance!

# Made by Gavin Crump
# Free for use
# BIM Guru, www.bimguru.com.au

# Boilerplate text
import clr

import sys
sys.path.append('C:\Program Files (x86)\IronPython 2.7\Lib')

import System
from System import Array
from System.Collections.Generic import *

clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

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

clr.AddReference("RevitAPI")
clr.AddReference("RevitAPIUI")

import Autodesk 
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI import *

# Current doc/app/ui
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication 
app = uiapp.Application 
uidoc = uiapp.ActiveUIDocument

def worksetCreator(element, eXworkset):
	for i in element:
		elemType = (doc.GetElement(i.GetTypeId()))
		elemName = (Element.Name.__get__(elemType))
		elemRName = elemName[:-4]
		if elemRName not in eXworkset:
			return i, elemType, elemRName


# Define list/unwrap list functions
# Preparing input from dynamo to revit
cad = FilteredElementCollector(doc).OfClass(ImportInstance).ToElements()
unWcad = UnwrapElement(cad)
pntCloudInt = UnwrapElement(FilteredElementCollector(doc).OfClass(PointCloudInstance).ToElements())
Navis = UnwrapElement(FilteredElementCollector(doc).OfClass(DirectShape).ToElements())
eXworkset = IN[0]
run = IN[1]

# Do some action in a Transaction
#TransactionManager.Instance.EnsureInTransaction(doc)
# your actions
#TransactionManager.Instance.TransactionTaskDone()
result = []
if run == True:
#	try:
	cadEle = (worksetCreator(unWcad, eXworkset))
	result.append(cadEle)
#	except:
#		pntCloudEle = (worksetCreator(pntCloudInt, eXworkset))
#		result.append(pntCloudEle)
#	else:
#		navisEle = (worksetCreator(Navis, eXworkset))
#		result.append(navisEle)
#	finally:
#		result.append("WL")
else:
	result.append("Workset Already Created")
# Output and Changing element to Dynamo for export
# <element>.ToDSType(True), #Not created in script, mark as Revit-owned
# <element>.ToDSType(False) #Created in script, mark as non-Revit-owned
OUT = result

hi @patrick_podeyn

It will surely not loop because when the conditions of the IF statement is once satisfied, the function will immediately return a value and not proceed any more. The solution to your problem is to define a list variable before the for-loop and append i, elemType, elemName to that variable.

like this:

def worksetCreator(element, eXworkset):
	output = list()

	for i in element:
		elemType = (doc.GetElement(i.GetTypeId()))
		elemName = (Element.Name.__get__(elemType))
		elemRName = elemName[:-4]

		if elemRName not in eXworkset:
			output.append(i, elemType, elemRName)

	return output
3 Likes

Might want to make sure you don’t keep my name on the top of the boilerplate in the final form :wink:

6 Likes

@GavinCrump maybe a silly question but why?
If I find some code I always keep the originator’s name.
It’s good for reference and it’s also making sure no one thinks I know how to fix it if it breaks. :yum:

2 Likes

Yeah, I happen to agree with @alien here, I would always give credit where credit is due. If the script is based on other code, I would simply state around the part I have taken that this is based up on the work by [Author] and lavish them with thumbs ups! :slight_smile:

4 Likes

I often put the URL of where it came from too. That can be useful in future.

2 Likes

I have it in there to remember who the awesome person is that created this awesome thing. Also when someone else goes in to look at the python code, they too can recognize who the awesome person is that created the awesome thing.

1 Like

I’m getting an error that I’m appending too many arguments into the output. I just tried to create a blank list for each output and it only returned the one instance.

@blsalvio I think I found the solution, I need to use output.extend(a,b,c) instead of append. Now I need to figure out how to break the list into sublists.

FYI, no need to unwrap elements that come from FECs since they are already native Revit elements. You only need to Unwrap Dynamo elements if they are supplied from an Input (Green I’d items).

5 Likes

In this case I think it wasn’t my code, but they’re likely using my boilerplate template. I’m humbled in either case (and always admire Patrick’s work, so no intended offense), but I don’t recognise any of the code in the screenshots. Happy for him to take credit over whatever solution he reaches :slight_smile:

2 Likes

Yes, I am using your supplied boilerplate then adding and modifying the code. I’ll probably change it to say “BoilerPlate awesomeness supplied by Gavin Crump:slightly_smiling_face:

3 Likes

Haha glad it is of use. Be aware I’ve found an issue in the Unwrap list function (def uwlist etc.) recently. The returned element is specified as ‘Input’, but should actually be ‘result’. Whoops!

Just uploaded the updated template to github.

3 Likes

hi @patrick_podeyn ,

my bad, it shoud be:

output.append([i, elemType, elemRName])

1 Like