Grasshopper GhPython Script - Array[str]

Hello
I’m working on a GhPython Script which uses an external API
The function I’m using is asking for a parameter in the form of Array[str]. How do I define a variable with this type?

Here is the Runtime Error:

Runtime error (ArgumentTypeException): expected Array[str], got list

Here is the Help on the function i’m using:

Help on method-descriptor ModalParticipatingMassRatios

ModalParticipatingMassRatios(…)
ModalParticipatingMassRatios(self: cAnalysisResults, NumberResults: int, LoadCase: Array[str], StepType: Array[str], StepNum: Array[float], Period: Array[float], UX: Array[float], UY: Array[float], UZ: Array[float], SumUX: Array[float], SumUY: Array[float], SumUZ: Array[float], RX: Array[float], RY: Array[float], RZ: Array[float], SumRX: Array[float], SumRY: Array[float], SumRZ: Array[float]) → (int, int, Array[str], Array[str], Array[float], Array[float], Array[float], Array[float], Array[float], Array[float], Array[float], Array[float], Array[float], Array[float], Array[float], Array[float], Array[float], Array[float])

And here is how I’m defining the variables at the moment:
NumberResults = 0
LoadCase = []
StepType = []
StepNum = []
Period = []

etc…

Here is how the function is called(this line produces the Runtime error that i’m trying to solve)
ret = ETABSmodel.Results.ModalParticipatingMassRatios(NumberResults, LoadCase, StepType, StepNum, Period, UX, UY, UZ, SumUX, SumUY, SumUZ, RX, RY, RZ, SumRX, SumRY, SumRZ)

And i’ve attached the .gh file
ETABStest.gh (4.3 KB)

Thanks in advance

Hi Jono- you can convert to an array like so (I happen to have needed this the other day is the only reason I know) :

from System import Array
import Rhino

    p0 = Rhino.Geometry.Point3d(0,0,0)
    p1 = Rhino.Geometry.Point3d(5,0,0)
    p2 = Rhino.Geometry.Point3d(5,5,0)
    p3 = Rhino.Geometry.Point3d(0,5,0)
    pt_list = [p0, p1, p2, p3]
    pt_array = Array[Rhino.Geometry.Point3d](pt_list)  <<<<< This is the bit you need - tell it what kind of thing is in the list, in this case a Point3d, then the list.

Does that do it?

-Pascal

In case you are already using a .NET list (System.Collections.Generic) you can also simply write mylist.ToArray(). This will copy the data, so it’s not very efficient. But of course the big drawback of working with arrays is, that you need to know the length of the array before adding anything to it.

Without the bottleneck of converting lists to arrays, just init a new array like so:


pt_array = Array.CreateInstance(Rhino.Geometry.Point3d, 4)
pt_array(0) = Rhino.Geometry.Point3d(0,0,0)
pt_array(1) = Rhino.Geometry.Point3d(5,0,0)
pt_array(2) = Rhino.Geometry.Point3d(5,5,0)
pt_array(3) = Rhino.Geometry.Point3d(0,5,0)

This of course only makes a difference if your buffer is very large.

Thanks for your responses. I ended up doing this which seems to work but if anyone has a cleaner way to do it, I’d be interested to know

LoadCase  = System.Array[System.String](["a","b"])
StepType  = System.Array[System.String](["a","b"])
StepNum  = System.Array[float]([1.0,2.0])

I think you haven’t understood our both posts. What you have done is the short way of what Pascal was writing. And I just added to this, that this approach is not efficient, because you generate a Python list which is then converted into a .Net Array. So you heap-allocate twice. The way I was describing, directly initializes an array, without the need for creating a Python list. But the definition of “clean” is quite subjective. If you mean shortness, then what you have written is probably cleanest.