Select to view content in your preferred language

GetParameter() - Double Value needs to be re-cast as a Double (from string)

135
9
Thursday
MGAL
by
Occasional Contributor

In my tool, I have one parameter that accepts a double value. In my script, I have to re-cast the value as a float() type. 

proximity_threshold = float(arcpy.GetParameterAsText(1))

 This feels kind of silly to have to re-cast the value that was originally input as the correct data type. 

Is there a more elegant solution here that I'm not seeing? 

0 Kudos
9 Replies
AlfredBaldenweck
MVP Regular Contributor

Yeah just use arcpy.GetParameter()

MGAL
by
Occasional Contributor

That's what I thought too...

When I change the line to...

proximity_threshold = arcpy.GetParameter(1)
arcpy.AddMessage(proximity_threshold)
arcpy.AddMessage(type(proximity_threshold))

if near_dist < proximity_threshold:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: '<' not supported between instances of 'float' and 'str'

Messages before the failure show 10, and <class 'str'> respectively. Here's my tool parameter config for good measure.

MGAL_0-1765476976378.png

-M

0 Kudos
DavidSolari
MVP Regular Contributor

Alfred's suggestion is the intended way to get a Double parameter so I can't say why it's failing for you. As a workaround, try getting all your parameters using arcpy.GetParameterInfo() and then use the value or valueAsText parameters as needed. For example, a drop-in replacement for the first line of your sample is:

proximity_threshold = arcpy.GetParameterInfo()[1].value

 

0 Kudos
MGAL
by
Occasional Contributor

That worked...

I'm still not understanding why the double data type is so buried in the tool. For example, I also have a boolean parameter in this tool, and the ".GetParameter()" method works w/o transformation. 

In my mind, the toolboxes parameters should dictate the data type of the incoming data as it was configured in the toolbox. Otherwise, what's the point of setting a data type? 

0 Kudos
DanPatterson
MVP Esteemed Contributor

It is one reason that I use the old school sys.argv

Accessing parameters in a script tool—ArcGIS Pro | Documentation

you just have to remember that sys.argv[0] is the script and sys.argv[1] is parameter id 0


... sort of retired...
0 Kudos
AlfredBaldenweck
MVP Regular Contributor

Dumb question, but what's the parameter type of near_dist?

0 Kudos
MGAL
by
Occasional Contributor

near_dist isn't a parameter... it's derived from the script. it's the variable for the output of .distanceTo() the geometry method (outputs double). 

the script joins information from two different line feature classes, to a table of inspection points. where the tables' ID's don't match 1:1 (for reasons i don't want to get into :/) the script reverts to a proximity match. the proximity match is the min threshold that automatically matches the line to the point. 

def find_closest_line(pcs_geom, input_fc, oid_idx, shape_idx, proximity_threshold):
    near_dists = {}
    for feats in input_fc: 
        for k,v in feats.items():
            oid = v[oid_idx]
            shape = v[shape_idx]
        near_dist = pcs_geom.distanceTo(shape)
        if near_dist < proximity_threshold:
            # arcpy.AddMessage("Bullseye!")
            return list(feats.values())[0]
        else:
            near_dists[oid] = near_dist
    if len(near_dists) == 0:
        return False
    closest_oid = sorted(near_dists.items(), key=lambda item: item[1])[0][0]
    closest_feat = [oid for rows in input_fc for oid in rows.keys() if oid == closest_oid]
    for feats in input_fc:
        for k,v in feats.items():
            if v[oid_idx] == closest_oid:
                return v
    return closest_feat

(note that "input_fc" is really a list of python dictionaries derived from SearchCursor)

depending on the size & location quality of the incoming dataset, this value can be adjusted to speed up the process, or slow down the process to get better accuracy. the tool also has a boolean parameter that puts the process into a test mode to allow the user to see the results as a formatted arcpy message, before the data is appended to the master inspection table. 

not a dumb question! 

0 Kudos
AlfredBaldenweck
MVP Regular Contributor

So, I tested this just now on 3.5.5 and I don't have any problem?

AlfredBaldenweck_0-1765554912943.png

"""
Script documentation

- Tool parameters are accessed using arcpy.GetParameter() or 
                                     arcpy.GetParameterAsText()
- Update derived parameter values using arcpy.SetParameter() or
                                        arcpy.SetParameterAsText()
"""
import arcpy


def script_tool(param0):
    """Script code goes below"""
    x = float(10)
    y = param0+x
    arcpy.AddMessage(y)
    return

if __name__ == "__main__":
    param0 = arcpy.GetParameter(0)
    script_tool(param0)

 

AlfredBaldenweck_1-1765554980164.png

AlfredBaldenweck_2-1765554994406.png

I'd double-check the types of everything again. You can arcpy.AddMessage(type(x)) to make sure.

If everything is actually as intended, this is super weird and would probably worth trying to replicate in an unrelated toolbox with a very simple tool (as above).

0 Kudos
DanPatterson
MVP Esteemed Contributor

you can float both with issue in python

(float(1) == float("1")) and (float("1.0") == float(1.0))
True

so if it isn't an integer, float/double or text, what is it?


... sort of retired...
0 Kudos