Filter elements by different condition input by user

Hi,
Im trying to making a script that places electrical components in our model, based in where the ventilation engineer has placed their components, “a shadow object”. This i have figured out how to do for one object at a time, but i want it to be a bit more dynamic. I have made an Excel schedule where the rows represent a different filter for the linked elements from the vent.model. Here i want the user of the script to have the option to specify the name, type, and parameters of the familys in the vent.model they want to filter by. I also want the option til select what contrition to filter by: N/V=dont filter by this contition E = Equals, C=Contains, BW= Beginswith and EW=Endswith.


Here is the problem i have now. How can I filter the elements by different conditions? I have tried, very poorly, to make a python script that does what i have tried to describe here, but it did not work, i’m no expert in python, but i want to become better at it, so if someone can solve it with python that would teach me a lot :slight_smile: but nodes works also.

@mons.reseland

Can you post those files?
Revit, Excel, and .dyn

I can post the .dyn file and the Excel file. i cannot post the RVT file unfortunately
Filter fra excel.dyn (140.1 KB) Link element filter.xlsx (20.1 KB)

hello @mons.reseland

there are some syntaxe problems in your code, here an example with fixes
remember to post your code with the <> tags it will help those who will help you

if metode == "N/V": 
	resultat = elementer 
elif metode == "E": 
	resultat = elementer == val
elif metode == "C": 
	resultat = val in elementer
elif metode == "BW": 
	resultat = elementer.startswith(val) 
elif metode == "EW": 
	resultat = elementer.endswith(val)
else:
	resultat = False

Hi @c.poupin
Here is my original code:

<elementer = IN[0]
metode = IN[1]
val = IN[2]

resultat = [“none”]

if metode == “N/V”:
resultat = elementer
if metode == “E”:
if elementer.equals(val):
resultat = True
else resultat = false
if metode == “C”:
if elementer.contains(val):
resultat = True
else resultat = false
if metode == “BW”:
if elementer.startswith(val):
resultat = True
else resultat = false
if metode == “EW”:
if elementer.endswith(val):
resultat = True
else resultat = false

OUT = resultat>

I tried what you said, but i only got false out of my python node.

Hello,
an Example

@c.poupin the script does not recognize that the list of elements is a list of lists. I have to make the script look in the different sublist for all the elements that match the inputs by the user and return a true or flse value, from there i can filter out the elements with a filter bool mask. kind of like this

do i perhaps need to do a “for loop” or something?

Hello
try this (the code is to be adapted if ever there are more conditions)

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

def getDataParameter(lstmetode, lstval):
	for idx, (metode, val) in enumerate(zip(lstmetode, lstval)):
		if metode is not None and val is not None:
			return idx, metode, val
	
	
lstelementer = IN[0]
lstmetode = IN[1] 
lstval = IN[2] 
outCheck = []
idx, metode, val = getDataParameter(lstmetode, lstval)
for elementer in lstelementer[idx]:
	if metode == "N/V": 
		resultat = elementer 
	elif metode == "E": 
		resultat = elementer == val
	elif metode == "C": 
		resultat = val in elementer
	elif metode == "BW": 
		resultat = elementer.startswith(val) 
	elif metode == "EW": 
		resultat = elementer.endswith(val)
	else:
		resultat = False
	outCheck.append(resultat)
	
OUT = 	outCheck

Hello @c.poupin
Awesome, thank you, almost there :slight_smile: I think that when the metode equals N/V the result should be true, because then the script passes all the elements to the next evaluation. So i see that now the script does not keep the list structure, to the next part, it only evaluate the first sublist. I need it to be adaptive so i can add as many lines in my excel sheet as i want and the script will evaluate all the elements in each sublist by that sublists condition, if that makes sense :slight_smile: Here is a picture of how it works now.

I also modified the scrip a little, but i did not get the result i wanted

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

def getDataParameter(lstmetode, lstval):
	for idx, (metode, val) in enumerate(zip(lstmetode, lstval)):
		if metode is not None and val is not None:
			return idx, metode, val
	
	
lstelementer = IN[0]
lstmetode    = IN[1] 
lstval       = IN[2] 
outCheck = []
idx, metode, val = getDataParameter(lstmetode, lstval)
for elementer in lstelementer[idx]:
	if metode == "N/V": 
		resultat = True
	elif metode == "E": 
		resultat = elementer == val
	elif metode == "C": 
		resultat = val in elementer
	elif metode == "BW": 
		resultat = elementer.startswith(val) 
	elif metode == "EW": 
		resultat = elementer.endswith(val)
	else:
		resultat = False
	outCheck.append(resultat)
	
OUT = 	outCheck

using zip function

1 Like

Thank you so much @c.poupin! your code, it worked beautifully :slight_smile:
I have learned so much