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:





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")
        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")
                   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.