Optional script input parameters

3802
10
Jump to solution
03-13-2017 01:08 PM
PredragJevtic1
New Contributor

I have created a script (see below) that works ok but only in case if all parameters are required inputs. Quite simple, Roads(line) and Tracts(polygon) feature classes , first buffer Roads and then clip to Tracts. There are more feature classes in Zion.gdb but I am just doing a test script to figure out optional input parameters.

What I need is that user should be able to select the layer they want to buffer, the layer they want to clip, the output location/name of the clip, and the buffer distance. All of it has to be optional. The problem is when I set for example Tracts and Tracts_Clip feature classes to optional in Script Parameters and do not apply them in script execution because I want only Roads buffer, the script does not work. Disregard red x symbol, I shortened the path.

Any help would be much appreciated!!!

   
 
    import arcpy
    import arcpy

    from arcpy import env
    # set environment settings
    env.workspace = "C:/data/Zion.gdb"
    env.overwriteOutput = True

    # Script arguments

    Roads = arcpy.GetParameterAsText(0)
    if Roads == '#' or not Roads:  
        Roads = arcpy.GetParameterAsText(0) # provide a default value if unspecified

    Tracts = arcpy.GetParameterAsText(1)
    if Tracts == '#' or not Tracts:
        Tracts = arcpy.GetParameterAsText(1) # provide a default value if unspecified

    Tracts_Clip = arcpy.GetParameterAsText(2)
    if Tracts_Clip == '#' or not Tracts_Clip:
        Tracts_Clip = arcpy.GetParameterAsText(2) # provide a default value if unspecified

    Buffer_Distance = arcpy.GetParameterAsText(3)
    if Buffer_Distance == '#' or not Buffer_Distance:
        Buffer_Distance = arcpy.GetParameterAsText(3) # provide a default value if unspecified

    # Local variables:
    Tracts_Clip = arcpy.GetParameterAsText(2)
    Buffer_Distance = arcpy.GetParameterAsText(3)
    Roads_Buffer = "Roads_Buffer"

    # Process: Buffer
    arcpy.Buffer_analysis(Roads, Roads_Buffer, Buffer_Distance,"FULL", "ROUND", "ALL", "", "")

    # Process: Clip (1)
    arcpy.Clip_analysis(Tracts, Roads_Buffer, Tracts_Clip, "")

0 Kudos
1 Solution

Accepted Solutions
DarrenWiens2
MVP Honored Contributor

I suppose you'd want something like this. I'm not exactly sure how blank parameters are passed back through GetParameterAsText():

if Roads <> '': # if Roads isn't blank
  arcpy.Buffer_analysis(Roads,...)‍‍‍‍‍‍ # run buffer on Roads‍‍

You could also wrap your tool calls in try/except blocks. If the tool can't be run because the parameters are invalid within the try block, it will quietly move on to the except block:

try:
  arcpy.Buffer_analysis(Roads,...) # try to run buffer
except:
  pass # if buffer can't complete, do nothing and move on

View solution in original post

0 Kudos
10 Replies
DarrenWiens2
MVP Honored Contributor

You're not providing default values for the blank parameters, you're just setting them back to the original blank value.

0 Kudos
PredragJevtic1
New Contributor

If I provide default values how can I make them optional?

How to correct the script?

Thanks

0 Kudos
DarrenWiens2
MVP Honored Contributor

You'll have to shuffle around the logic a bit to test which parameters have a value and only call the appropriate tools.

For example, if Roads is blank, then don't run Buffer on Roads. If Tracts is blank, then don't run the Clip.

0 Kudos
PredragJevtic1
New Contributor

That`s theory and I know that but I need help with the script and how to tweak it .........

Thanks anyway

0 Kudos
DarrenWiens2
MVP Honored Contributor

I suppose you'd want something like this. I'm not exactly sure how blank parameters are passed back through GetParameterAsText():

if Roads <> '': # if Roads isn't blank
  arcpy.Buffer_analysis(Roads,...)‍‍‍‍‍‍ # run buffer on Roads‍‍

You could also wrap your tool calls in try/except blocks. If the tool can't be run because the parameters are invalid within the try block, it will quietly move on to the except block:

try:
  arcpy.Buffer_analysis(Roads,...) # try to run buffer
except:
  pass # if buffer can't complete, do nothing and move on
0 Kudos
PredragJevtic1
New Contributor

This TRY option works!

Thank you sir!

0 Kudos
DanPatterson_Retired
MVP Emeritus

I am confused since I don't see the defaults.  If you have an optional parameter it either isn't necessary to the workflow, but it is an addon or enhancement, but if you don't have a default for your optional parameters, you shouldn't use them subsequently.  The way I read the tools if no values is provided for the optional parameters, they will the '#' or not True.  But do you want them to use something.  I think you want to just provide a default value/featureclass for those parameters and make them required IF a certain step needs to be done.  That is different than saying, you don't have to specify something, then you want if used anyway.

In short... if you have a step that you want 'done', then it is required.  If you give them the 'option' of chosing their own value/etc, it is still a required parameter.  You can provide that 'option' by just letting them choose your default value/input.

0 Kudos
PredragJevtic1
New Contributor

As mentioned in the initial post ,  user should be able to select the layer they want to buffer, the layer they want to clip, the output location/name of the clip, and the buffer distance. All of it has to be optional. For example, I want to do only buffer on Roads but not clip to other feature classes. Or I want buffer on Roads , clip to Tracts but not clip on 3rd feature class etc.....  each parameter has to be optional (as I said there are more in gdb, this is just a test script with only two feature classes)

0 Kudos
DanPatterson_Retired
MVP Emeritus

you really need a couple of multivalue featureclass input comboboxes.  The first would be all the features you want to clip (presumably, you would want to clip before buffering), then another one that takes all the featureclasses you want to buffer.  Your workflow would only then check the following combinations

clip       buffer

-----------------

FC_0(nothing)   FC_0(nothing)   (goofed and put one in they shouldn't have)

FC_1      nothing  (clip featureclass one)

nothing   FC2       (just buffer featureclass 2

FC_3      FC_3     ( clip and buffer)

repeat for other feature classes..

Now ... FC_0  gets nothing done to it

FC_1 just gets clipped

FC2  skips the clipping and goes straight to buffer

FC3  gets clipped first, then buffered, BUT, you want the buffer for FC_3's to be dependent upon the clipped output for it... ie write it to in_memory so it is temporary.  This will have to be controlled by the script for the most part and in the case of clipping and buffering the intermediate step would be a temporary file.

Now add to this your next request that each buffer distance be different for each featureclass.  You might soon see that having a toolbox with one tool that does the clipping and another that does the buffering and a third that clips and buffers is way less confusing to program and will reuse essentially the same code with fewer required check.  Programmers choice, but design the workflow with the capabilities of the user in mind.

0 Kudos