Reverse Engineering an ArcPy Script

Existing scripts are a great resource for learning both Python and ArcPy

We will take apart a relatively small script and see how it works

We will also extend it to work with an ArcPy script dialog box

This will make it convenient for the user to communicate with the script with parameters

We will look at batch_rename_layers.py by Amber R. Cannon at Weather Decision Technologies

Here is an ESRI download link to the same file

For this lecture, I will color Python commands in black and others specific to ArcPy in orange

Hint--Use arcpy.AddMessage() when you want to print values to the console window

Let�s look at the original script, line by line:

import arcpy

The import command allows the script to access the arcpy module

All of our scripts that interact with ArcGIS functionality will include this line

mxd = arcpy.mapping.MapDocument("CURRENT")

This line creates a global MapDocument variable, mxd, which represents the loaded map document object returned by arcpy.mapping.MapDocument()

Please remember that characters bracketed by a pair of single or double quotes is a literal (constant, static, immutable) string

ArcPy uses strings like "CURRENT" to pass keywords (like CURRENT) to the arcpy objects

We will look at Python classes and objects in another lecture

See the documentation for arcpy.mapping.MapDocument

All the properties relating to the currently-loaded map document are now stored in mxd

Many of our scripts will include a line very much like this one

df = arcpy.mapping.ListDataFrames(mxd, '')[0]

Once you have a MapDocument object, you can see what�s in it

ListDataFrames takes 2 parameters�a MapDocument object and a filter string�and returns a list of DataFrame objects

Our code assumes that there is only 1 interesting DataFrame object (at position [0] in the returned list) and does not apply any filters to the output

for lyrs in arcpy.mapping.ListLayers(mxd, "*", df):

ListLayers creates a list of the layers in a given MapDocument and DataFrame (represented by mxd and df in our code)

Since we end up with a list, we can iterate through it in a for loop

Each element on the list is a Layer object

The following code is executed for each Layer object on the list:

if lyrs.name == '<old_name>':

Every layer object has a name

If this layer is named '<old_name>', then this if returns true

'<old_name>' is just a literal string placeholder in this code

We will modify this code to use dialog parameters so that the user can change the existing name of a layer (specified by '<old_name>'here) to a new name:

lyrs.name = '<New Name>'

Layers in the current map document and data frame matching the existing name will be changed to the new name

The remaining lines of code update the ArcMap TOC and view to reflect our changes

Bringing the script into our toolboxes

Download batch_rename_layers.py and save it to your flash drive

Right-click your script toolbox in ArcToolbox and select Add�Script�

Create a name, label, and description for your tool

Remember: the name field cannot have spaces in it

Click Next

Navigate to batch_rename_layers.py, select it, and click Next

In the Add Script dialog, create 2 parameters under Display Name, both with Data Type set to String:

Be sure to add them in the same order that I have

Click Finish�your script is now in your script toolbox

Try running it by double-clicking on its label in your script toolbox

A dialog box pops up that asks for values for your old_name and new_name parameters

Type something in each field (any text at all will do for now) and click OK

You will see something like this:

Great�it runs; but it doesn�t do anything useful yet

Modifying your new script to work with your parameters

Right now, your script is using the placeholders

Let�s edit the script to change its behavior

Right-click the label for your script and pick Edit�

Make the following edits:

#if lyrs.name == '<old_name>':

#lyrs.name = '<New Name>'

if lyrs.name == arcpy.GetParameterAsText(0):

lyrs.name = arcpy.GetParameterAsText(1)

#Remember, equivalency is tested by == (2 adjacent �equals� signs) and assignment is performed with =

You can probably guess that arcpy.GetParameterAsText() returns the values of user parameters in the order in which they appeared in the Add Script dialog box

Our first parameter (at position 0) is old_name

The second parameter (at position 1) is new_name

We could improve this behavior but for now it�s fine the way it is

As long as you remember which parameter is which in your own code

Go get some data and test the script!

Note: layer names are case sensitive�type them in exactly as you see them in the TOC

You should see the name in the TOC change to the new name if you are successful