0

I'm creating a model, using ArcGIS ModelBuilder, and want to use SelectRandombyPercent from Randomly subsetting X% of selected features using ArcPy? to randomly select points from a feature class. The selected features will be an intermediate data set for use as a source for a Network Analyst OD Cost Matrix layer destinations. The script works perfectly from the Python shell in ArcMap.

I've added a Script in my toolbox utilizing the script from the shell. When executed, I'm prompted for parameters, get the tool executing message, and get a Succeeded (green check) result. However it doesn't actually make a selection.

What do I need to modify to have the script (run in ModelBuilder) make a selection that I can use?


It appears that the major problem with moving from Shell to Script/Tool was the function definition line (probably a rookie mistake, but definitely not easily discoverable).

FINAL WORKING CODE (verified in both toolbox and ModelBuilder):

import arcpy
import random

inLayer = arcpy.GetParameterAsText(0)
inPercent = arcpy.GetParameterAsText(1)

arcpy.AddMessage(inPercent+"% random sample")

if float(inPercent) > 100:
    arcpy.AddError ("Error: Percent is greater than 100")
    sys.exit()

if float(inPercent) <= 0:
    arcpy.AddError ("Error: Percent is less than zero")
    sys.exit()

fc = arcpy.Describe (inLayer).catalogPath
featureCount = float (arcpy.GetCount_management (fc).getOutput (0))
count = int (featureCount * float (inPercent) / float (100))

if not count:
    arcpy.SelectLayerByAttribute_management (inLayer, "CLEAR_SELECTION")

oids = [oid for oid, in arcpy.da.SearchCursor (fc, "OID@")]
oidFldName = arcpy.Describe (inLayer).OIDFieldName
delimOidFld = arcpy.AddFieldDelimiters (inLayer, oidFldName)
randOids = random.sample (oids, count)
oidsStr = ", ".join (map (str, randOids))
sql = "{0} IN ({1})".format (delimOidFld, oidsStr)
arcpy.SelectLayerByAttribute_management (inLayer, "", sql)


arcpy.MakeFeatureLayer_management(inLayer,outLayer)

I made five major changes from the source:

  1. Deletion of the DEF line.
  2. Addition of FLOAT for the percent comparison in the IF lines.
  3. Addition of message with the calculated percentage (for quick reference).
  4. Addition of an error message and function stop in the IF lines.
  5. Addition of MakeFeatureLayer parameter and output.
2

It sounds like you've got the first step to creating a script tool complete: you made a new script tool and associated it with a saved .py file. The next step is to create parameters, this lets you pass items into and out of the script. If you're using that script as-is, it takes a layer and percentage as input. Take a look at this help topic, it actually demonstrates using a script tool you've created, inside ModelBuilder: http://desktop.arcgis.com/en/arcmap/10.3/analyze/creating-tools/setting-script-tool-parameters.htm

In short, you'll need to:

  1. Add 2 input parameters to your code

    inLayer = arcpy.GetParameterAsText(0)

    inPercent = arcpy.GetParameterAsText(1)

  2. Wire up those variables to be passed into the function. It'll look something like below (note, untested, so might not be exactly right)

    def SelectRandomByPercent (layer, percent): # layer variable is the layer name in TOC #percent is percent as whole number (0-100) if percent > 100: print "percent is greater than 100" return if percent < 0: print "percent is less than zero" return import random fc = arcpy.Describe (layer).catalogPath featureCount = float (arcpy.GetCount_management (fc).getOutput (0)) count = int (featureCount * float (percent) / float (100)) if not count: arcpy.SelectLayerByAttribute_management (layer, "CLEAR_SELECTION") return oids = [oid for oid, in arcpy.da.SearchCursor (fc, "OID@")] oidFldName = arcpy.Describe (layer).OIDFieldName path = arcpy.Describe (layer).path delimOidFld = arcpy.AddFieldDelimiters (path, oidFldName) randOids = random.sample (oids, count) oidsStr = ", ".join (map (str, randOids)) sql = "{0} IN ({1})".format (delimOidFld, oidsStr) outputLayer = arcpy.SelectLayerByAttribute_management (layer, "", sql) return outputLayer

layer = arcpy.GetParameterAsText(0) percent = arcpy.GetParameterAsText(1) outputLayer = SelectRandomByPercent (layer, percent) arcpy.SetParameter(2, outputLayer )

  1. Inside the properties of the script tool (accessed by right clicking the script from the TBX in the catalog tree), add a layer and a double input parameter. (use the previously mentioned help topic as a guide)

  2. Run the tool inside ArcMap (no using a model). Does it work? Great. If so, you'll probably need to add an output parameter as well (repeat steps 1-3)

  3. Now drag the script tool into MB and connect it up.

  • Thanks for the quick response. Could you please give a little more direction on #2-I'm not sure what "wire up" means. I'm very new to programming and Python, so this is still pretty confusing to me. I've added the parameters in the properties box and the code, but I'm still getting the same result (from TBX, haven't tried MB). – dav Oct 16 '18 at 14:51
  • @dav see the update I made with code for #2 – KHibma Oct 16 '18 at 17:42
  • Thanks for your help. I've included the code I finally got working-it's still a bit different from yours, but the guidance you provided pushed me in the right direction. – dav Oct 16 '18 at 19:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.