Possible bug in Dynamo / Python

Hi guys,

I’ve created a script to automatically set the Doors / Windows mark based on the ToRoom FromRoom information.

It collects the Doors / Windows and the ToRoom /FromRoom information and with a simple python script using IF / ELSE statements assign a prefix and a name to each mark, then sets the parameter.

I added a bit more code to the python script to add “.1”, “.2” etc in case the Marks are duplicated.

It works fine with windows but the python script gives an error if I change the category to Doors (however it works with Doors if I remove the code that adds the suffix).

The code:

ToRooms = IN[0]
FromRooms = IN[1]
c =
prefijo ="Ventana de "

for i,j in zip(ToRooms, FromRooms):
if “None” in i : c.append(prefijo + j)
elif “Distribuidor” in i and j != “(None)” : c.append([prefijo + j]);
else : c.append([prefijo + i]);

dups = {}

for i, val in enumerate©:
if val not in dups:
# Store index of first occurrence and occurrence value
dups[val] = [i, 1]
else:
# Special case for first occurrence
if dups[val][1] == 1:
c[dups[val][0]] += ("." + str(dups[val][1]))

    # Increment occurrence value, index value doesn't matter anymore
    dups[val][1] += 1

    # Use stored occurrence value
    c[i] += ("." + str(dups[val][1]))

OUT = c

I’m using Dynamo 1.3.1.1736 and Revit 2017 x64 1 build 7.0.416.0


Same, with Doors:

Doors, but removing problematic code from Python:

Here is the script to download:

ventanas.dyn (14.9 KB)

And the source for the Python code to add .1 .2 is https://stackoverflow.com/questions/30650474/python-rename-duplicates-in-list-with-progressive-numbers-without-sorting-list

Cheers

Much of your screenshot is illegible - can you do another export?

Edited: changed the pics. The .dyn is there as well.

The error is list objects are unhashable, even they are converted to string and are the same as the windows script

Sounds like you need to incorporate a means of dealing with the list. Post the Python script with the preformatted function and hopefully someone more Python savvy can weigh in.

Sorry for the delay, this is the code (IN[]0 and IN[1] are converted to strings before entering the Python script. Maybe the problem resides in the NULL elements):

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.

ToRooms = IN[0]
FromRooms = IN[1]
c = []
preffix ="Window of "

for i,j in zip(ToRooms, FromRooms):
        if  "None" in i : c.append(prefijo + j)
        elif "Corridor" in i and j != "(None)" : c.append([preffix + j]);
        else : c.append([preffix + i]);

# NOW STARTS THE PIECE OF CODE THAT WORKS RANDOM. BASICALLY IT ADDS 1,2,3...
# AFTER THE REPEATED ELEMENTS IN A LIST.

dups = {}

for i, val in enumerate(c):
    if val not in dups:
        # Store index of first occurrence and occurrence value
        dups[val] = [i, 1]
    else:
        # Special case for first occurrence
        if dups[val][1] == 1:
            c[dups[val][0]] += str(dups[val][1])

        # Increment occurrence value, index value doesn't matter anymore
        dups[val][1] += 1

        # Use stored occurrence value
        c[i] += str(dups[val][1])

OUT = c

I’ve splited the problematic part of the python script into a separated node and messed a bit with it and now it’s working properly. Honestly I can’t identify what did I change, but the fact is it is working now.

In case it is useful for anybody, the code below will take a strings list and add .1, .2 , .3, etc. to every duplicated element in the list, while keeping intact the order of the elements.

c = IN[0]

dups = {}

for i, val in enumerate(c):
    if val not in dups:
        # Store index of first occurrence and occurrence value
        dups[val] = [i, 1]
    else:
        # Special case for first occurrence
        if dups[val][1] == 1:
        c[dups[val][0]] += ("." + str(dups[val][1]))

    # Increment occurrence value, index value doesn't matter anymore
    dups[val][1] += 1

    # Use stored occurrence value
    c[i] += ("." + str(dups[val][1]))

OUT = c