Assign String based on Range

I have a list (lets call it List A) with 4 columns. Column 2 has a number. There is another list (List B) with a name and 2 numbers associated with it. What’s needed is to add the name from the List B to List A, but based on if List A, Column 2 is within the range of List B’s numbers.
Here’s List A:

Here’s List B:

Is this possible?

@Cadguru42 sure, you tweak them.

# Load the Python Standard and DesignScript Libraries
import sys
import clr

clr.AddReference('System')
from System.Collections.Generic import List


#Preparing input from dynamo to revit
lst_0 = IN[0]
lst_1 = IN[1]

result = []

# kinda brute force
for val in lst_1[1]:
    match = None
    for sublst in lst_0:
        type, lower, upper = sublst
        if lower < val and val < upper:
            match = type
    result.append(match)
     
OUT = result

An now a non Python :snake: option :sweat_smile:.

1 Like

hi

cordially
christian.stan

Hi
a solution using pandas and bisect (python)

import sys
import clr

import pandas as pd
from bisect import bisect_left, bisect_right

def get_intersect_value(value):
    i = bisect_right(interval_values, value)
    return interval_keys[i-1]

data, interval_keys, interval_values = IN
df = pd.DataFrame(data = data, columns=["ColomnA", "ColomnB_Value", "ColomnC", "ColomnD"])
df["Column_BasedRange"] = df['ColomnB_Value'].apply(get_intersect_value)

OUT = repr(df), df.values.tolist()

add_column_pandas_by_bisect_DYN3_v0.1.dyn (11.2 KB)

lol. i thought abt using nodes. but i still went with python. cant resist the comfort that python provides. especially if op knows how to use pandas dataframe. for large datasets, pandas will be much faster than brute force.

1 Like

Personally i would allwas go for a NON Python :snake: option firtst (and show Python as an alernative).

So
A: People learn Dynamo (nodes).
and
B: People aren’t reliant on someone else’s code.

2 Likes

Hi, the ideal solution is to progress, whether it’s Node, Python, C#, or (JSON, which I don’t understand yet) .

Sincerely,
christian.stan

3 Likes

I would say, there is nothing that excludes anything else, for me it is only for building buildings, personally I have no interest in being some kind of data/software engineer. and will never become as im a building engineer…so I just use whatever my little brain allows, so I can design buildings in the best possible way in terms of quality and speed, that is usually what my customers want and pay me for, so the greater my skills the better for my customers…:wink: :wink: just my opinion :wink: :wink: but many opinions on that…fair enough :wink: :wink:

4 Likes

Somewhat agree.

But if you are trying to learn Dynamo first
and there is a NON Python :snake: solution
then it also good (idea) to post that.

Ofcourse it is also nice to have a Python :snake: solution for people who want to learn Python :snake:.

Just my opinion :upside_down_face:.

2 Likes

yeah, i feel you. i work in a code-heavy environment, so coding comes naturally to me. i am probably an outlier in the community.

not trying to be pedantic but using node is relying on code written by others. :joy:

Ofcourse. I am aware of that. But nodes are ‘easy’ to understand.
Dynamo is called graphical (visual) programming for a reason :winking_face_with_tongue:.
Python :snake: isn’t really grapical imo :sweat_smile:.

But again, just my opinion :innocent:.

Keep up the good work :heart:.

2 Likes

Sure.
But unless you wrote all the APIs you called there you are too.
And Python.
And the C interpreter for Python.
And the .NET ecosystem.
And the C interpreter that passes everything to machine code…

The first benefit to nodes is someone else is helping with maintenance. In the case of the our of the box nodes, that is Autodesk. In the case of packages that is the package author. In the case of Python you are taking ownership of the entirety of the maintenance. That is technical debt which will eventually come due, in some cases with minimal impact (change the engine and coordinate that across all uses), and in other cases it will be far more disruptive.

The second benefit is they author faster and with less required prerequisite knowledge. It takes a LOT longer to reach a functional skill set in Python than Dynamo. It’s a matter of weeks vs months for functional, and hours vs days for basics.

That said, we NEED both. And C#. And APS. And every other toolset for automation tools which are out there. The most valuable topics on here (in my opinion) are the ones which have ten different solutions using five different methods. The more we expand the horizons the more everyone benefits.

3 Likes

I’m not a programmer by nature. I dabble a little, but I’m primarily a civil designer. I don’t know Python and just learning Dynamo for now in order to get a table of pressure parts that meets a government requirement since Autodesk doesn’t have a way to do it within C3D.

I’d love to see a way to do this with just nodes. I tried using greater than, less than nodes into a logical AND operator, but it doesn’t seem to work.

The “y” comparisons are the direct number list that’s used to create the overall List B. It’s probably something to do with the number of items in that list compared to the 24 in List A. I can rearrange List B however its needed, though. List A needs to stay the way it is with the name from List B added to the first column, though.

I’ve also thought about using a Dictionary(s) for this, but not sure how to go about it.

So your lists to check for ‘fit within’ having values of [ [1000,1500],[1500,2200],[2200,2900]…] isn’t really the right question to ask when it comes to Node based methods.

If you look at the values, they are sequential - 100,1500,2200,2900… so rather than testing for ‘fit within’ you can test for if the value is less than the first item in the pair. If it is less than 1000, you know it predates your range. If it is less than 1500, then you know it is the first item in your range, etc… you might need to add a ‘maximum’ list at the end, or you can deal with the edge case of a value exceeding your range separately.

So List.GetItemAtIndex can pull those upper limiting values. And then you test each of your values for being less than each of the items in that list using a < node. Watch the lacing and list levels on this - if you have 10 possible values in which the items can fall then you need lists of 10 booleans. If not your lacing and list levels are off.

After that you can using the node List.IndexOf get the first index of ‘True’ to find the first value which you sit under.

Next use a List.GetItemAtIndex to pull the correct value from the original list.

1 Like

But unless you wrote all the APIs you called there you are too.

oh absolutely.

That said, we NEED both. And C#. And APS. And every other toolset for automation tools which are out there. The most valuable topics on here (in my opinion) are the ones which have ten different solutions using five different methods. The more we expand the horizons the more everyone benefits.

agree.

but man u guys are serious. :joy:

3 Likes

I think I’m getting there.

As of now there are 6 items in List A (this will change depending on drawing). I have run a less than test on those 6 using the dictionary values with a Cross Product lacing method. This produces a list of 300 items with pairs of true/false for each of the 6 items from List A. There are 25 ranges, btw.

Looks like I need to some kind of test for if 1st item false AND 2nd item true, then return…something.

You only need to text the first or second value in the list, and get the first item which is true.

If you go first, add one to the index.

If you go second, add an additional item to the list to account for values less than your first sample.

1 Like

I think I’m understanding what @jacob.small is saying now. I’m going to work on two methods. While working on that I saw Math.Map and it got me thinking of trying to use it as well.

If an item in Math.Map is not 0 or 1, then it’s a match. Now I need to figure out how to get that false in the Or node to equate to a name, though.

Blockquote
If you go second, add an additional item to the list to account for values less than your first sample.

I used this method and think I got it working. Thanks!

I’m still curious if the Math.Map method would work as well.

1 Like