This Python Script is working, but I have not been able to run it in Revit

Hello! I am currently trying to create a script (node - sequence) able to select the optimal combination of formwork panels dimensions in order to cover both width and length of a concrete beam. I designed this script in python, hoping to be able to use it in Dynamo, but I have not been able to do so so far.

If anyone could help me understand how to actually get the desired input and output from the code, I would greatly appreciate it. Below, the code in python syntax, in which the input parameters will be in bold case and the output in italics.

import itertools
class nums(object):

#Get all combinations from list 
def combinations(self, elements):        
    allCombs = []        
    for i in range (0 , len(elements) + 1):
        for comb  in itertools.combinations(elements, i):
            allCombs.append(comb)
    return allCombs[1:]

#Remove greater than target or return if the same
def purge (self,elements, target):
    purged = []
    for i in range (0, len(elements)):
        if elements[i] < target:
            purged.append(elements[i])
        elif elements[i] == target:
            return target
    return purged

#Add list sublists
def sums (self , elements):
    added = []
    for i in range (0, len(elements)):
        add = 0
        for j in range (0, len(elements[i])):
            add += elements[i][j]
        added.append(add)
    return added

#Get distances from elements to target
def distances (self, elements,target):
    
    diffs = []
    for i in range (0, len(elements)):
        diffs.append(target - elements[i])
    return diffs

#Get the closest element index to zero
def closest (self, elements):
    positives = []
    for i in range ( 0 , len (elements)):
        if elements[i] > 0:
            positives.append(elements[i]) 

    closeTozero = min (positives)
    return elements.index ( closeTozero )

#return combination at index
def getCombElement ( self, index , combs):
    return combs[index]

#return the closest dimension to a target
def getClosest (self , dims, target):
    purged = self.purge(dims, target)
    if isinstance(purged, float) or  isinstance(purged, int): 
        return [purged]
    combs = self.combinations(purged)
    added = self.sums(combs)
    diffs = self.distances(added, target)
    close = self.closest(diffs)
    comb = self.getCombElement(close , combs)
    return comb

#return the closest dimension to a list of targets
def getClosestForAll ( self, dims , targets):
    closests = []
    for i in range (0, len(targets)):
        closests.append([targets[i], self.getClosest(dims, targets[i])])
    return closests

if name == ‘main’:

mynums = nums()
allCombs =  mynums.getClosestForAll([**0.3,0.45,0.60,0.75,0.90,1.2,1.4**], [**1.4, 0.80,2**] )
_print allCombs_
1 Like

I am not sure what you mean, have you read this?
http://dynamoprimer.com/en/09_Custom-Nodes/9-4_Python.html

Can you post what you are doing in Dynamo and any errors that show? Just the script doesn’t really tell what the problem is.

1 Like

First of all, thank you both for your fast and kind response.

Now, I am going to elaborate a little more on what I am doing with Dynamo:

I have a set of different sized beams of concrete, and I need to find the most optimal combination of formwork panels for them. Since the formwork is commercial, it already has set dimensions in both width and length and all of them are combinable among themselves, ie, both are lists of dimensions, one of the systems of formwork has the following properties:

Then, I am trying to create a code that will successfully select the best combination of panels with specific dimensions to cover most of the element (I don’t need to define it as area, since all of the dims are interchangeable, we can keep it as distances). With the code I developed in python, I am able to do that by manually entering the lists and running it in VSCode, but, when I try to insert this code into a Python script node like this:

Where IN[0] is the list of dimensions available (either for width of length) for commercial formwork and IN[1] is the list of the actual dimensions (either for width of length) for the desired concrete element to be cast; but as soon as I run it, I get this error:

error

Most likely the error lays on the ‘‘translation’’ of the code from python to the actual python node, or maybe i am not specifying the input and output variables properly, but I am recurring to the forum because I do not know how to do it properly.

Any guidance is greatly appreciated.

I don’t think you have to check top-level script environment as every python script you are running is inside Dynamo itself and runs separately as module.

so line 79 where you have:

if __name__ == ‘__main__’:

is obsolete. Remove it and it should work. Of course you have to remove the indentation in like 80 and 81 as well.

2 Likes

Hzamani, thanks a lot for your reply, I deleted line 79 and it’s now displaying a new error:

Sorry if the questions are dumb, but i am not very proficient with dynamo, so sometimes I don’t get what the errors are referring to, any guidance is always thanked

For example, when it says that nums is not defined, I don’t know how else to define it, other than what is shown in the code screenshots

I need to see your entire Dynamo script to have a better idea. And I’m also learning so not any expert of this anyway. But happy to give it a try.

The Entire thing is a little bit difficult to post here, but this process in completely isolated from the rest of the script, its only inputs are 2 lists {0.30,0.60,0.45,0.90,1.2,1.4} and {0.80,3} where the first one is the list from where i should choose the elements to combine and the second is the target i am trying to reach with the combinations.

Both inputs go into the python script with the code shown above.

You need to be more transparent mate if you want people to help you here. Understandable if you don’t want to share the whole thing but one needs to know what elements are being fed into your Python script. You can chop the parts of your script that are irrelevant and post the rest or put some mock input list and the Python script only in there. Anyways. You are telling me that the inputs are only two lists of doubles but your code doesn’t allocate a variable name to IN[0] and IN[1]. So not sure where you are using these lists.

It is a matter of size… Not transparency…

Anyway… IN[0] y IN[1] refer to the inputs of the node as defined in line 5 of the code pasted above. that’s why they have that format

I’m gonna try to paste only a part of it, being this enough for it to understand it

Ok! How big is your dyn file? :grinning: You gotta put a lot of node in there to get it to 100kb at most.

line 5 of your code says:

dataEnteringNode = IN

you need to define it the way you want to use it for instance:

list1 = IN[0]
list2 = IN[1]
1 Like

I didn’t know you could upload files to this forum, I will try to upload mine, thanks a lot

1 Like

Cast in Place Element Selector v5.0.dyn (137.1 KB)

Hi @leosanabriam.

Change the indentation at the end and assign allCombs to OUT.

1 Like

Hello Salvatoredragotta!

I did what you told me and it’s still shooting me an error, asking for this:

Did it show it to you?

No it didn’t

Cast in Place Element Selector v5.0.dyn (137.1 KB)

I had deleted a coma…

Honestly thank you very much!

Is your name Salvatore Dragotta (written like that) so I can put it in the acknowledgements of the assingment?

Yes that’s my name :+1:

Please mark the post as solved :grinning: