Select to view content in your preferred language

Tool validator query

2025
4
10-22-2013 08:46 AM
NeilAyres
MVP Alum
I think I am reasonably competent at python / arcpy coding. But mostly I use this as py code running straight out of IDLE.
Its quick and easy, but all the data sources / outputs are hard coded.

So recently I have become inspired to turn some of my more re-usable code into proper scripts in a tool box.

This tool takes in a PointZ Fc and uses its attribute data to create a polylineZM of the drill hole trace.
You can see from the attachment that I have successfully disabled the second half of the dialog until an associated table is selected.
No probs there.
So a couple of questions to those of you with more experienced than me with coding the tool validator classes.
I wanted to make sure that the user selects 3 different attribute fields for the numeric inputs. Selecting 2 that are the same would be nonsense.
I tried to do this in updateParameters like this:
if self.params[3].value and self.params[4].value:
      if self.params[3].value == self.params[4].value:
        self.params[4].setErrorMessage("Cannot pick the same field")
      else:
.....

But this didn't really do anything. No little red crosses appeared and the tool ran anyway.
So is there an easier way to ensure that 3 different inputs are picked that I havn't noticed yet?
Or what would be the correct way to do this in a toolvalidator.

I have read (and re-read) all the help stuff on this but can find no pointers yet on how to do this.
Also looked at some of the videos from Dev Summit 2012 re tool scripting.

Thanks in advance,
Neil
Tags (2)
0 Kudos
4 Replies
DouglasSands
Deactivated User
I haven't used the Tool Validator, but I have done tool validation with Python Toolbox (.pyt) files, and the syntax is similar, so maybe this help.
In a tool that I have I am checking the same thing with the following code:

if parameters[1].valueAsText == parameters[2].valueAsText:
    parameters[1].setErrorMessage("FIELD1 value cannot be the same as FIELD2 value.")
    parameters[2].setErrorMessage("FIELD2 value cannot be the same as FIELD1 value.")


You do not need to check if both fields have been set first. Also, you want to check the "Value As Text", which will return a the name of the field specified. I think that paramter.value would return a Field Object.

So I would think that the following would work for you:
if self.params[3].valueAsText == self.params[4].valueAsText:
    self.params[3].setErrorMessage("Cannot pick the same field")
    self.params[4].setErrorMessage("Cannot pick the same field")


But like I said, I haven't done exactly what you are trying. But since the syntax for all of this is generally poorly documented, a lot of what I have learned to do with pyt files has come from copying/modifying the help info for the tool validator box syntax.

Good luck,
- Russell

PS ... and this is a stretch... but at least with a pyt file you can dynamically update the fields such that it is impossible for the two fields to be the same. For example, the code block below makes sure that whatever fields a user specifies as input for two early parameters cannot be used as input for a third parameter (and keeps the list of options up to date if anything changes). This would go in the update parameters section. Again the syntax is for pyt files.

def updateParameters(self, parameters):
    '''Modify the values and properties of parameters before internal
    validation is performed.  This method is called whenever a parameter
    has been changed.'''
    #Need to make sure that the additional fields option ONLY lists fields
    #that will not be standardized.
    if parameters[0].value:
        old_fields = [field.name for field in arcpy.ListFields(parameters[0].value)]
        if parameters[1].altered:
            if parameters[1].valueAsText in old_fields:
                old_fields.pop(old_fields.index(parameters[1].valueAsText))
        if parameters[2].altered:
            if parameters[2].valueAsText in old_fields:
                old_fields.pop(old_fields.index(parameters[2].valueAsText))
        parameters[3].filter.list = old_fields


The above sets the 4th parameter value options to be a list of fields from the input to the 1st parameter. However, any values selected in the 2nd and 3rd parameters will be removed from the list of options for the 4th parameter.
0 Kudos
NeilAyres
MVP Alum
Thanks Russell (or is it Doug..).
I will try messing with the valueText story. You're probably right, the output of .value is not the name of the field but an object.
I have seen constructs looking like this param[0].value.value, now what does that mean!!!
I wonder if there is a page somewhere which details all the parameters (or is it methods...) for the param object.
Your last bit was interesting and I will certainly pursue it. Construct a list of the fields before then pop them off the list as they are selected. Could be a way to do it.
I am curious that in your developments, you have skipped over "normal" python script tools and gone straight to pyt's.
What is the reason for this?

Thanks again for your inputs.
Cheers,
Neil
0 Kudos
DouglasSands
Deactivated User
There is such a page - arcpy.Parameter(). Unfortunately though there are so many different ways to access and define parameters depending on how you are writing scripts it gets confusing very fast, because the documentation isn't always consistent page to page.

I actually started the "regular" way, I'd say. Initially I wrote scripts that were hard coded or used raw_input() after I noticed that scripts were executing faster, and easier to modify, than models in Model Builder. Then I started using the scripts as tools in ArcGIS. Again the standard/old way. Accessing parameters with arcpy.GetParameter() etc and defining things in the dialogue window.

When 10.1 came out I initially stayed clear of pyt files because I couldn't find a good editor for them. But I managed to get Aptana Studio 3 to recognize the pyt extension as a python file, and started to make an effort to use them. The main reason I like pyt files more than the standard way of doing things is that PYT files are self contained (almost). All of the code for running the file is in the PYT file and if you share it with someone, they don't have to do anything other than point ArcGIS at the file. This is convenient for me as I'm writing scripts that I share with people who aren't familiar with python and aren't always good at getting things set up right. One other thing that is nice is that they are 'easier' to set up and control. All of the parameter definitions and validation are in the script. This means that you don't need to bounce back and forth between ArcGIS and the script if you need to change something about a parameter, or add a new one. Its all just there in the script, which is nice.

That said, there are a few very frustrating things about going the PYT route:

  1. Its not always clear what is causing ArcGIS not to recognize a tool. Sometimes the tool is invalid, but ArcGIS gives you 0 information about this and then you need to go through line by line and try and find the missing comma etc that is causing the issue.

  2. PYT files are not a one and done thing if you want to include tool help. The tool help dialogue is still defined by editing the tool description in ArcCatalog. This is then stored in an external XML file that you need to make sure you are sending along wherever your PYT file goes.

  3. IDLE won't recognize PYT files, its necessary to find an editor that you like and that will allow you to associate new file extensions with python.

  4. There is next to no documentation for a lot of the advanced things you can do. Usually just a mention that something is possible, but not how.


In light of this, a lot of times I write things up as a hard coded file that I am executing, and then build the PYT file around it. I'm actually spending some of my free time trying to set up some tutorial type documents organizing what I've learned over the past year or so, because even though its not all rainbows and unicorns, I do think that they are worth the investment for people to take advantage of them.

- Doug / Russell
0 Kudos
NeilAyres
MVP Alum
Doug & Russell,

thanks a lot. Look forward to seeing some more of your insights here.
Back to tool validator.....

Cheers,
Neil
0 Kudos