import arcpy featureClass = arcpy.GetParameterAsText(0) # if running from Arc as a script tool, get first (0th) parameter if len(featureClass) == 0: # if not, it comes out as '' - has length 0; use this path featureClass = "C:\\Temp\\BAL_Mapping.gdb\\INTERFACE" # paths in python need either double slashes or forward slashed arcpy.AddMessage('Starting operation on: %s' % featureClass) # tell user operation is starting rows = arcpy.UpdateCursor(featureClass) # create the updatecursor rows object for row in rows: # iterate over the rows if row.Slope == "0-5" and row.Veg == "Woodland": row.BALFZ = "15" elif row.Slope == "0-5" and row.Veg == "Forest": row.BALFZ = "24" else: row.BALFZ = "0" rows.updateRow(row) # write the new value to the object del row, rows arcpy.AddMessage('Completed operation on: %s' % featureClass) # inform user of completion status
import arcpy def customUpdateCursor(FeatureClass, inField1, inField2, outField): '''customUpdateCursor(FeatureClass, inField1, inField2, outField) takes a feature class and three field names; two for input fields to the calculation and one for output performs a conditional assesment on the inputs and returns a value to the output ''' rows = arcpy.UpdateCursor(FeatureClass) for row in rows: # iterate over the rows if (row.getValue(inField1) == "0-5") and (row.getValue(inField2) == "Woodland"): row.setValue(outField, "15") elif (row.getValue(inField1) == "0-5") and (row.getValue(inField2) == "Forest"): row.setValue(outField, "24") else: row.setValue(outField, "0") rows.updateRow(row) del row, rows # End of customUpdateCursor function if __name__ == '__main__': featureClass = arcpy.GetParameterAsText(0) # if running from Arc as a script tool, get first (0th) parameter if len(featureClass) == 0: # if not, it comes out as '' - has length 0; use this default path featureClass = "C:\\Temp\\BAL_Mapping.gdb\\INTERFACE" # paths in python need either double slashes or forward slashed arcpy.AddMessage('Starting operation on: %s' % featureClass) infield1 = 'Slope' # you could also make these input paramaters infield2 = 'Veg' outfield = 'BALFZ' result = customUpdateCursor(featureClass, infield1, infield2, outfield)# pass variables to function arcpy.AddMessage('Completed operation on: %s' % featureClass)
do this if that then do this else do this then do this
inGDB = 'C:\data.gdb' inFeatureClass = 'input' # select field = 3, buffer by 5m, export to test_[fieldVal]_[buffersize] Featureclass in input GDB selection = arcpy.selectByAttributes(inGDB + '\\' + inFeatureClass, 'field = 3') bufferedSelection = arcpy.Buffer(selection,'5m') arcpy.Export(bufferedSelection, inGDB + '\\' + 'test_3_5m') # select field = 7, buffer by 7m, export to test_[fieldVal]_[buffersize] Featureclass in input GDB selection = arcpy.selectByAttributes(inGDB + '\\' + inFeatureClass, 'field = 7') bufferedSelection = arcpy.Buffer(selection,'7m') arcpy.Export(bufferedSelection, inGDB + '\\' + 'test_7_7m') # select field = 9, buffer by 1m, export to test_[fieldVal]_[buffersize] Featureclass in input GDB selection = arcpy.selectByAttributes(inGDB + '\\' + inFeatureClass, 'field = 9') bufferedSelection = arcpy.Buffer(selection,'1m') arcpy.Export(bufferedSelection, inGDB + '\\' + 'test_9_1m')
# inputs inGDB = 'C:\data.gdb' inFeatureClass = 'input' # define module (before trying to use it) def selectBufferExport(GDB, FC, fieldName fieldVal, buffersize): '''selects FC (within GDB) entries for fieldName == fieldVal buffers by buffersize exports to new featureclass in GDB with name "test_fieldVal_buffersize" ''' selection = arcpy.selectByAttributes(GDB + '\\' + FC, '%s = %s' % (fieldName, fieldVal)) bufferedSelection = arcpy.Buffer(selection, buffersize) arcpy.Export(bufferedSelection, GDB + '\\' + 'test_%s_%s' % (fieldVal, buffersize)) # now call the module, passing it the variables selectBufferExport(inGDB, inFeatureClass, 3, '5m') selectBufferExport(inGDB, inFeatureClass, 7, '7m') selectBufferExport(inGDB, inFeatureClass, 9, '1m')
# or, getting fancy, replacing the last four lines with a for loop: for (fieldval,buffer) in [(3, '5m'), (7, '7m'), (9, '1m')]: selectBufferExport(inGDB, inFeatureClass, fieldVal, buffer)
import selBuffExp selBuffExp.selectBufferExport('test.gdb', 'test', 3, '5m')
OK, I'll try to explain fully - sorry if you already know some of this stuff...
Essentially you can use Python to code in two ways. The first is just plain scripting, i.e.:do this if that then do this else do this then do this
The code starts at the top of the file, then goes through line by line, does whatever it is told to do then proceeds to the next line. My first post the other day contained a script. It got the input from the user (or defaulted to something), did the calculation, then told the user it was done.
More advanced Python programming makes use of Modules (anything following a def statement is a module). Modules are sometimes also called functions. These allow you to use the same bit of code more than once. For example, if I have a code that selects by attributes, performs a buffer then exports the data, and I want to do it three times while varying a few things, I could do (just making stuff up to explain the example, this code will definitely not run):inGDB = 'C:\data.gdb' inFeatureClass = 'input' # select field = 3, buffer by 5m, export to test_[fieldVal]_[buffersize] Featureclass in input GDB selection = arcpy.selectByAttributes(inGDB + '\\' + inFeatureClass, 'field = 3') bufferedSelection = arcpy.Buffer(selection,'5m') arcpy.Export(bufferedSelection, inGDB + '\\' + 'test_3_5m') # select field = 7, buffer by 7m, export to test_[fieldVal]_[buffersize] Featureclass in input GDB selection = arcpy.selectByAttributes(inGDB + '\\' + inFeatureClass, 'field = 7') bufferedSelection = arcpy.Buffer(selection,'7m') arcpy.Export(bufferedSelection, inGDB + '\\' + 'test_7_7m') # select field = 9, buffer by 1m, export to test_[fieldVal]_[buffersize] Featureclass in input GDB selection = arcpy.selectByAttributes(inGDB + '\\' + inFeatureClass, 'field = 9') bufferedSelection = arcpy.Buffer(selection,'1m') arcpy.Export(bufferedSelection, inGDB + '\\' + 'test_9_1m')
Now, as I am repeating a lot of code, it would be simpler to define a module that takes the things that actually change as inputs and then does the operations. This module must be placed before it is called, so that it is loaded into memory. Adding the module gives:# inputs inGDB = 'C:\data.gdb' inFeatureClass = 'input' # define module (before trying to use it) def selectBufferExport(GDB, FC, fieldName fieldVal, buffersize): '''selects FC (within GDB) entries for fieldName == fieldVal buffers by buffersize exports to new featureclass in GDB with name "test_fieldVal_buffersize" ''' selection = arcpy.selectByAttributes(GDB + '\\' + FC, '%s = %s' % (fieldName, fieldVal)) bufferedSelection = arcpy.Buffer(selection, buffersize) arcpy.Export(bufferedSelection, GDB + '\\' + 'test_%s_%s' % (fieldVal, buffersize)) # now call the module, passing it the variables selectBufferExport(inGDB, inFeatureClass, 3, '5m') selectBufferExport(inGDB, inFeatureClass, 7, '7m') selectBufferExport(inGDB, inFeatureClass, 9, '1m')# or, getting fancy, replacing the last four lines with a for loop: for (fieldval,buffer) in [(3, '5m'), (7, '7m'), (9, '1m')]: selectBufferExport(inGDB, inFeatureClass, fieldVal, buffer)
Not only have we saved a bunch of lines, but if we want to make changes to the method or add a step, we only have to change it in one place.
Now that I have created this module I can use it as above, or I can call it from other scripts by importing the *.py file it lives in; if it was saved as selBuffExp.py I could import it into another script within the same folder and call the module with:import selBuffExp selBuffExp.selectBufferExport('test.gdb', 'test', 3, '5m')
Now, when you import a file it actually runs/loads into memory the contents of the file. if __name__ == "__main__": is a statement that only runs if you are running the script by itself (i.e. from the command line, or as an Arc tool). However, when the file is imported its name is not "__main__", and that bit doesn't get run... If you don't have it, and you try to import it, it will load the module into memory and do all the things within the script (which at least makes a mess, but probably crashes if your paths aren't still valid or both are set to the same paths).
Presumably you are making a script tool (not using it in a Field Calculator)? If you are making a script tool, the reason your code doesn't run is that you don't have the contents of the if __name__ == "__main__": part, so the module is never actually called. Arc tells you it is complete, meaning that the tool completed, but all you have given it to do is load something into memory (you haven't called the module or anything)...
I modified the code from my first post to follow this convention as the original poster had used it; chances are you don't need to bother about it. If you aren't going to be importing it, you could just delete the if __name__ == "__main__": line and un-indent what was in there.
del row, rows
try: del row except: pass del rows
import sys, arcpy try: infc = arcpy.GetParameterAsText(0) # Input feature class inField1 = arcpy.GetParameterAsText(1) # Input data field inField2 = arcpy.GetParameterAsText(2) outfld = arcpy.GetParameterAsText(3) # Output result field except: arcpy.AddError("Cannot parse input arguments") sys.exit("Error reading arguments!") arcpy.AddMessage("Calculating field...") try: rows = arcpy.UpdateCursor(infc) for row in rows: # iterate over the rows if (row.getValue(inField1) == "Sandy") and (row.getValue(inField2) == "0-10"): row.setValue(outField, "poor") elif (row.getValue(inField1) == "Sandy") and (row.getValue(inField2) == ">10"): row.setValue(outField, "medium") else: row.setValue(outField, "none") rows.updateRow(row) del rows arcpy.AddMessage("Completed") except: errMsg = arcpy.GetMessages(2) arcpy.AddError("Unexpected error : " + errMsg)
try: rows = arcpy.UpdateCursor(infc) for row in rows: # iterate over the rows .... .... del rows arcpy.AddMessage("Completed")