AnsweredAssumed Answered

Best Way to Pass a Function into arcpy.CalculateField_management?

Question asked by rossi45 on Dec 3, 2015
Latest reply on Jan 13, 2016 by rastrauch

I have a function that I use in a script in a couple different ways. One of the ways I would like to use it, is in the codeblock parameter of:

 

arcpy.CalculateField_management

 

 

The function is here and basically does some math and returns a value:

 

def getPercentOverlapValueOfAOI(area_of_overlap, extentarea):
    if round(area_of_overlap/extentarea * 100, 1) < 0.1:
        AOI_Percent_Value = str("<" +  "0.0")
    else:
        AOI_Percent_Value = str(round(area_of_overlap/extentarea * 100,1))
    return AOI_Percent_Value

 

and then further down in my script, I use the calculate field function:

 

arcpy.CalculateField_management(outClipFC, "PERCENTAGE_OF_OVERLAP_OF_LAYER", 
                                   "getPercentOverlapValueOfAOI(!AREA_OF_OVERLAP_HA_OF_LAYER!, {0})".format(extentArea), 
                                   "PYTHON", """getPercentOverlapValueOfAOI""")

 

Consistently, I am receiving the following error

ExecuteError: ERROR 000539: Runtime error

Traceback (most recent call last):

  File "<string>", line 1, in <module>

NameError: name 'getPercentOverlapValueOfAOI' is not defined

Now, I understand that in example #2 in the help menu, They use a variable "codeblock" and wrap the function in triple quotes. I believe calculatefield evaluates the code block string and interprets it as a function. The issue I have with that, is that I have a function that I use inside and outsiide of the arcpy.CalculateField_management function. I initially declare it without the triple quotes becuase the native python interpter will obviously not undertand that the triple quoted string is, in fact, a python function.

 

Now, I've tried a number of things to get this to work. For example, I assign a variable to the triple quote wrapped function:

 

codeblock = """def getPercentOverlapValueOfAOI(area_of_overlap):
               if round(area_of_overlap/extentArea * 100, 1) < 0.1:
                   AOI_Percent_Value = str("<" +  "0.0")
               else:
                   AOI_Percent_Value = str(round(area_of_overlap/extentArea * 100,1))
               return AOI_Percent_Value"""

 

and then pass the codeblock variable into the caluclate field function:

 

arcpy.CalculateField_management(outClipFC, "PERCENTAGE_OF_OVERLAP_OF_LAYER", 
                                "getPercentOverlapValueOfAOI(!AREA_OF_OVERLAP_HA_OF_LAYER!, {0})".format(extentArea), 
                                "PYTHON", codeblock)

 

Now, that seems to work, but it completely defeats the purpose of creating a function. One of the primary purposes of a function is to make the code reusable. It seems like I have to define my variable twice. Once at the beginning of my script and then again so that I can get it wrapped in triple quotes and then pass it to a variable that in turn, gets passed into the caluclate field function.

 

I've also tried to pass the function name into the expression via .format with the same error popping up ( I think I was trying to get creative and silly with this one):

 

arcpy.CalculateField_management(outClipFC, "PERCENTAGE_OF_OVERLAP_OF_LAYER", 
                                "{0}(!AREA_OF_OVERLAP_HA_OF_LAYER!, {1})".format(getPercentOverlapValueOfAOI, extentArea), 
                                "PYTHON", """getPercentOverlapValueOfAOI""")

 

 

 

My question is, what is the best way, to take a custom built function and pass it into the calculate field function as a piece of code block and then have the expression parameter recognize it.

Outcomes