I am trying to make a custom made Python Script tool which I would like to use in Model builder. I am using the arcpy.Calulate_field_management function (simple reclass function as an example), but it seems not be working properly. Please note that when I run this script on its own through a Python editor (IDLE), the script works fine. After adjusting it to make it work for a custom Python Script tool, the script stops when it is going to calculate the field.
This is the script which I use for my tool with a comment where it stops. The arcpy.GetParameterAsText(0) refers to the table which you can find in the picture below.
import arcpy
try:
fc = arcpy.GetParameterAsText(0)
arcpy.AddMessage("Hi Jelle, your script is starting now...")
def calc_value(orig_field):
if (orig_field == "R<10_min"):
return "1"
elif (orig_field == "R_10-20_min"):
return "2"
elif (orig_field == "R_30+"):
return "3"
def calc_field():
arcpy.AddMessage("Calculating field management has started, Jelle")
reclass_field = "Reclass_SA_All"
##HERE is WHERE PYTHON SCRIPT TOOL STOPS
arcpy.CalculateField_management(fc, reclass_field, "calc_value(!SA_All!)", "PYTHON_9.3")
arcpy.AddMessage("Reclass Field calculation is done, Jelle.")
arcpy.AddMessage("Starting calc_field function, Jelle...")
calc_field()
arcpy.SetParameterAsText(1, fc)
except:
arcpy.GetMessages()
Here is a picture of the table which I am trying to edit together with the customized script tool window when it is finished running. I have added customized messages in my script to find out where the script stops running.
enter image description here
I have the feeling I am doing a basic error which stops the scripts from running the calculate_field_management within my tool. Does anybody know what I am doing wrong? AM i right if I say the calculate_field_management cannot refer to another function within my expression? This does work when I run the script on its own through a Python editor (IDLE).
-
Try sys.argv[1] instead of GetParameterAsText(0)FelixIP– FelixIP2015年03月11日 22:23:06 +00:00Commented Mar 11, 2015 at 22:23
2 Answers 2
In my opinion, the best way to calculate a field using complex logic when you're already using Python is to do it with an UpdateCursor
instead of the Calculate Field tool. (As @FaridCher's answer shows, you end up defining a Python function in a string, which makes it difficult to read, as well as to write.)
In your code, I would replace
arcpy.CalculateField_management(fc, reclass_field, "calc_value(!SA_All!)", "PYTHON_9.3")
with
with arcpy.da.UpdateCursor(fc, [reclass_field, 'SA_All']) as cursor:
for row in cursor:
row[0] = calc_value(row[1])
cursor.updateRow(row)
Note: this method uses the UpdateCursor
from arcpy
's "Data Access" (da
) module. If you have ArcGIS 10.0 or earlier, you will have to use the regular cursors.
-
thank you for this tip. My code is a little more complex than this example I use here and I agree with you that using long strings as codeblocks makes it a little hard to read and write. In my current code, I have more fields within the the calc_value function. How would I call these fields within the for row loop?Jelle– Jelle2015年03月12日 22:26:38 +00:00Commented Mar 12, 2015 at 22:26
-
1In the list of fieldnames being supplied to the
UpdateCursor
, just add the other fieldnames you want from the feature class, then add them as additional parameters forcalc_value
withrow[2]
,row[3]
, etc. The items inrow
are ordered the same as the fieldnames in the list.nmpeterson– nmpeterson2015年03月13日 03:59:39 +00:00Commented Mar 13, 2015 at 3:59
Rather than using if-elif statements, just reclassify using a one-liner expression with a dict:
{"R<10_min": "1", "R_10-20_min": "2", "R_30+": "3"}.get(!SA_All!, "0")
which you can put the CalculateField_management function:
arcpy.CalculateField_management(
fc, reclass_field,
'''{"R<10_min": "1", "R_10-20_min": "2", "R_30+": "3"}.get(!SA_All!, "0")''',
"PYTHON_9.3")
Explore related questions
See similar questions with these tags.