Totally agree, but the main problem in the forum is that some users are still doing the work of some lazy people.
Regards,
2 Likes
Yna_Db
October 24, 2017, 8:13pm
8
@Organon
I can’t resist to cite your very first lesson to coding in this thread 'cause I simply love it
4 Likes
@Yna_Db ,
Hahaha, it’s the hard truth.
Regards,
1 Like
Yna_Db
October 24, 2017, 8:18pm
10
Organon:
the hard truth
… so much easier to say with a touch of humor
3 Likes
Yna_Db
October 26, 2017, 7:16pm
11
To complement this IF-ELSE STATEMENT proposal, here are a few additional examples:
Empty Lists and nulls tend to cause problems with certain functions, including If.
Use python instead.
test = IN[0]
true = IN[1]
false = IN[2]
empty = []
if test == empty:
out = true
else:
out = false
OUT = out
layer = IN[0]
styles=[]
for i in layer:
if i == "red" :
styles.append("0.13mm")
elif i == "yellow":
styles.append ("0.18mm")
else :
styles.append ("0.13mm")
OUT = styles
just make a python script using if, elif and else for all six enumerations
item = IN[0]
lst = []
for i in item :
if i == 0 :
lst.append('Interior')
elif i == 1 :
lst.append('Exterior')
elif i == 2 :
lst.append('Foundation')
elif i == 3 :
lst.append('Retaining')
elif i == 4 :
lst.append('Soffit')
else :
lst.append('Core-shaft')
OUT = lst
you are indeed. Your code only works on a singleton (i.e. one object, or in your case, a number). As you want to provide a list you need to store your result in a list and iterate over the input list. One method is a simple loop to iterate through the list (and python has some pretty powerful built-in itertools which you should check out on python.org which are more efficient than loops):
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
#The inputs to th…
Can some one tell me what I’m doing wrong here?.
[image]
Just luckily solved it myself if anyone has the same issue here’s my solution
[Capture]
Python
# Assign curves to groups according to whether they are connected via shared start points and end points. Group numbers are not important.
# Colin McCrone, 2015-09-28
import clr
import math
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
# Determine whether two points are equal
def PointsEqual(pt1, pt2):
tolerance = 0.00001
if (math.fabs(pt1.X …
Yna_Db
November 1, 2017, 10:09pm
12
The following posts are related to PYTHON LISTS :
@staylor You have to iterate over your list of documents using a for loop. Right now you are defining doc as a list, so essentially in line 18 you are saying param_list = ListObject.FamilyManager.GetParameters() See below example, when I query the object type of the input without a for loop, it shows me the object is a list. If I query the object type of the input elements with the for loop, it returns the object type of the items in the list
[iterateoverdocs]
So, you need to put your code w…
Hi @Jordan_Billingsley - I already have a very simple Python script that accomplishes supplying a boolean output for whether or not elements are pinned are not, which I will provide below. You can use this inputting your wall elements, then using Filter.ByBoolMask with its output.
To encourage you to understand how the script works & to further learn using Python with the Revit API I will provide an explanation on how it works. if you look at the API Docs that @Nick_Boyts referenced above you w…
There’s probably a cleaner way of doing this but a simple use of append will work.
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference('DSCoreNodes')
from DSCore import *
#The inputs to this node will be stored as a list in the IN variables.
dataEnteringNode = IN
items = IN[0]
inlist = IN[1]
newlist = []
for indices in inlist:
sublist = []
for i in indices:
sublist.append(items[i])
newlist.append(sublist)
#Assign your output to the O…
Strange. Works fine on my end. Have you tried closing the file and re-running it?
[image]
As an FYI, you should paste your Python code using the Preformatted Text option. Just highlight your pasted text and click </> in the toolbar above.
Yes, but I don’t think that’s what you need here. As @awilliams said, you can wrap your if statement within your for loop.
However, if you wanted to iterate through both lists simultaneously you would use:
for i, j in zip(list1, list2):
This would essentially get you paired values list1[0]/list2[0], list1[1]/list2[1], etc.
@Nick_Boyts your last one will go out of index… you need to pad
[Capture]
list1 = IN[0]
list2 = IN[1]
index = IN[2]
def pad(var, length):
return var[:length] + [None]*(length - len(var))
pad(list1, len(list1) + len(list2) )
for idx, item in zip(index,list2):
list1.insert(idx, item)
OUT = list1
You could also write your own ‘Type Summation’
[image]
The code in the example has two possible outputs, adjust commenting for the solution you want.
import sys
sys.path.append('C:\\Program Files (x86)\\IronPython 2.7\\Lib')
import collections
#The inputs to this node
fam = IN[0]
area = IN[1]
#group the values in a dictionary
elemVal = collections.defaultdict(int)
#sum grouped values
for f, v in zip(fam, area) :
elemVal[f] += v
#Output sorted as types(list0) and sums(list1)
OUT = zip(*e…
I have noticed that this before too, and it looks like UnwrapElement() is converting the Pyton List into a Collections.Generic.List. That’s whyisintance() returns false.
[image]
@Cesar_Escalante
Using Python, option 1:
[image]
def MergeSort(lst1,lst2):
MergedList=[]
for index,i in enumerate(lst1):
MergedList.append(i+lst2[index])
MergedList[index].sort()
return MergedList
OUT=MergeSort(IN[0],IN[1])
Option 2:
[image]
MergedList=[i+IN[1][index] for index,i in enumerate(IN[0])]
for i in MergedList:
i.sort()
OUT=MergedList
Hi JN,
Have you tried setting the lacing of the custom node that you created to Longest?
Otherwise you could use a for loop in Python:
import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB 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 TransactionM…
the function works with nulls as well :
[image]
we take each element among sublists and then find largest
i’m not sure I got this part
@ Hannes - use List Comprehensions - they are much faster than loops:
import clr
clr.AddReference(‘ProtoGeometry’)
from Autodesk.DesignScript.Geometry import *
dataEnteringNode = IN[0]
OUT = [i for sublist in IN[0] for i in sublist]
https://docs.python.org/2/tutorial/datastructures.html
Nice that you got it to work!
If you wanted to combine the lists in python you could have used zip()
for view,curves in zip(views,curvelist):
#Create curveloop
loop = CurveLoop()
for c in curves:
loop.Append(c.ToRevitType())
#Set cropregion in Transaction
TransactionManager.Instance.EnsureInTransaction(doc)
view.CropBoxActive = True
view.GetCropRegionShapeManager().SetCropShape(loop)
outputlist.append(view)
TransactionManager.Instance.TransactionTaskDone()
OUT = outputlist
I am guessing you have 2 sublists and really what you’re asking is how can you perform cross product lacing with sublist 1 against sublist 2?
Try this (this only works on a list with two sublists; if you are trying to match each item from sublist 1 with all items with sublist 2, then match each item from sublist 2 with all items from sublist 3…etc then this wont work and you should think about how to manage your data better)
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScri…
The Konrad’s function using lists comprehension:
elements = IN[0]
ProcessLists = lambda function, lists: [ProcessLists(function, item) if isinstance(item, list) else function(item) for item in lists]
sum = lambda x: x + 1
if isinstance(elements, list):
out = ProcessLists(sum, elements)
else:
out = sum(elements)
OUT = out
[image]
Try using a definition like so above your inputs…
def tolist(obj1):
if hasattr(obj1,“iter”): return obj1
else: return [obj1]
And for the input beams write the following…
beams = tolist(UnwrapElement(IN[0]))
This is what I use for inputs to ensure they are an iterable object. Very common point of failure in writing python nodes.
(I can’t seem to format the code on my mobile, but indented code after the first line naturally)
Hi @salvatoredragotta
Both versions get the ElementId using the same method, which is the .Id Property (any object that inherits from Element has it).
What’s different, is what they do with the resulting ElementId objects retrieved. The method you use, will depend what you will do with the collection of ElementIds. More details below.
The 2nd in your example, creates a list (built-in Python list ) which is a generic, container native to Python, the other creates a List, a .NET data-type.
Pyt…
2 Likes
Yna_Db
November 3, 2017, 10:33pm
13
These posts relate to STRINGS in Python:
you could do all that or use half a line of python code:
[Revit_2017-10-07_13-21-40]
On a side note: I assume you’re getting the trailing zeroes because you’ve converted a double value to a string. In that case you could also use this python code to get what you want straight away:
[image]
You could try to implement it by using a python script.
[image]
text = IN[0]
newText = []
#add newline to the string
for t in text[:-1]:
newText.append(t+'\n')
#add last line without newline
newText.append(text[-1])
OUT = ''.join(map(str, newText))
@3Pinter
You can also use a line of code in python:
OUT=[i.split('- ')[1] if '- ' in i else i for i in IN[0]]
or without list comprehension:
OUT=[]
for i in IN[0]:
if '- ' in i:
OUT.append(i.split('- ')[1])
else:
OUT.append(i)
[image]
@yyi is right. The problem here is that the code doesn’t accept different types of inputs (single integer or list of integers, single list of strings or nested lists, etc.)
What I would do is adapt the code to the worst case scenario for each case, being this when you have nested list of strings for the first one and a list of integers for the second. Pay attention to the if statement using isinstance().
Remove Characters
import re
inputList = IN[0]
outputList = []
def RemoveCharacters(list…
python, regex, string
Yna_Db
November 14, 2017, 10:31pm
14
This post is about FUNCTIONS :
A couple of things:
In python def means that a function is defined. Nothing will happen before you call the function.
I think you need to convert the reference plane to a sketch plane before it can be used to set the workplane.
insert is a function and should use (), not [].
https://forum.dynamobim.com/t/passing-nodes-as-functions-in-python-script/16324/4
Tomasz,
The ProcessList() method takes care of zipping the two arguments from lists. You don’t have to perform that inside your Intersection() method. Basically change it to:
def Intersection(elA, elB):
return elA.DoesIntersect(elB)
Then call it like so:
OUT = ProcessList(Intersection, ducts, walls)
Make sure that the two lists ducts and walls are exactly of the same structure. It works like this:
ducts = [duct1, duct2, duct3]
walls = [wall1, wall2, wall3]
Calling ProcessList(Interse…
@yyi is right. The problem here is that the code doesn’t accept different types of inputs (single integer or list of integers, single list of strings or nested lists, etc.)
What I would do is adapt the code to the worst case scenario for each case, being this when you have nested list of strings for the first one and a list of integers for the second. Pay attention to the if statement using isinstance().
Remove Characters
import re
inputList = IN[0]
outputList = []
def RemoveCharacters(list…
In python it may actually work faster than to convert to some text showing the type name and then testing on that. You could do the same thing there, but there’s a better alternative.
Standard python comes with the isinstance function. As an example:
[image]
In that the Python Code:
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.
#Assign your output to the OUT variable.
OUT = map…
I took another look at this, but had to turn to python to make it work:
[image]
(Edit: Python is updated, center and bottom had swapped places)
import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB.Structure import *
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
#Functions for list handling
def ProcessList(_func…
@Chad_Clary ,
This is indeed a little tricky because these elements don’t have a Parameter called name, but instead its a property. Here’s how you can handle it.
[image]
Here’s the code that’s inside of Python:
# Copyright(c) 2016, Konrad K Sobon
# @arch_laboratory, http://archi-lab.net
# Import Element wrapper extension methods
import clr
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
# Import DocumentManager and TransactionManager
clr.AddReference("Revit…
I wrote a 30 page handout for my AU class on Python for Dynamo, thought I would leave this here
13 Likes
Yna_Db
November 17, 2017, 8:11pm
16
This is a very good document that let you get started with a clear view on the possibilities opened by this language, along with a few tips that will make it all fun from the start. I add a link into the introductory post so it can be found easily. Thanks a lot
Yna_Db
November 17, 2017, 10:13pm
18
It seems consistent to add this other nice tutorial here:
VIDEO
7 Likes
For a non-programmer like myself, which would be the natural course then?
I am assuming first learning the basics of Python, for which I am following some course on edX and reading some tutorials, but this doesn’t seem to relate to geometric or graphical capabilities at all (Which I assume is because of the introductory level of the course).
So what would be next after learning the basic stuff?
How can I connect Revit or Dynamo or both to Python? This is like the missing link for me. I am sure you will guide me, and many others after me, on the right path.
Thank you all.
For most Dynamo users, I would say that Python only really shines when dealing with lists (especially of multiple levels) and Revit API work (which are things usually done in C# but can be done in python nodes). For geometric capabilities, I can only think of python being useful for its import libraries, math functions/capabilities, looping, or if you can find a python function online that already has what you want.
Someone please correct me if I am wrong though.
1 Like
If your into Python but need to check your syntax occasionally,
check out this Beginners Python Cheat Sheet,
beginnersPythonCheatSheet.pdf (1.7 MB)
downloaded from Eric Matthes author of Python Crash Course
http://ehmatthes.github.io/pcc/cheatsheets/README.html
lots of free resources available above but considering Eric went to the bother of making the cheet sheet free why not link to his book, I might even buy it myself…
Eric Matthes
5.0 out of 5 stars,
ASIN: B07J4521M3,
No Starch Press,
21 May 2019,
£19.63
with thanks to @DiRoots for twitter and @jose.oliveiraJXEPU for linkedin posts
4 Likes
Python use in Dynamo is really growing which is a good sign. Here’s a my AU class about using Python for Dynamo which is meant to build up your skills with the software. It starts from basic fundamentals and builds to more complex examples.
2 Likes
Great compilation of information! Thank you to all contributors!
There is also my presentation from AU London 2018 on Python
in Dynamo for Beginners
You can also access a bunch (65+) of heavily annotated Python scripts in Dynamo from 11+ contributors here: https://github.com/Amoursol/dynamoPython - huge shoutout to all who contributed!
8 Likes