Select to view content in your preferred language

How to get variables into Python code block of arcpy.management.CalculateField

1082
5
12-01-2022 06:02 AM
TomGeo
by
Frequent Contributor

I have one calculation where it works great getting a variable in:

 

 

arcpy.management.CalculateField(sector_angle, 'Buffer', "getBuffer(!Area!)", "PYTHON3", 
                                f"""def getBuffer(area):
                                    if area < {median_area}:
                                            return 1
                                    if area > {median_area}:
                                            return 2""", 
                                "TEXT", "NO_ENFORCE_DOMAINS")

 

 

And I have another calculation on the same feature class where it does not work.

 

 

arcpy.management.CalculateField(sector_angle, 'Buffer_Radius', "setDistance(!Buffer!)", "PYTHON3", 
                                f"""def setDistance(buffer):
                                    if buffer == 1:
                                            return {pnt[2]}
                                    elif buffer == 2:
                                            return {pnt[3]}""", "FLOAT")

 

 

Some example on how the variables look:

pnt[2] = 2043.8900146484375

pnt[3] = 4087.780029296875

The type of both variables is float, but the resulting 'Buffer_Radius' field contains only NaN.

 

TomGeo_1-1669903249036.png

I tried all sorts of stuff on how to get the variables into the code block, but while it was so easy in the first function, I don't have luck with the second one. How do I get my variables into the 'Buffer_radius' field?

 

- We are living in the 21st century.
GIS moved on and nobody needs a format consisting out of at least three files! No, nobody needs shapefiles, not even for the sake of an exchange format. Folks, use GeoPackage to exchange data with other GIS!
0 Kudos
5 Replies
DanPatterson
MVP Esteemed Contributor
pnt[2]

can't be a variable it is a slice of pnt, so where is pnt defined? and maybe if it is somewhere try

p2 = pnt[2]

p3 = pnt[3]

assuming of course that the values are slices of pnt


... sort of retired...
0 Kudos
RogerDunnGIS
Frequent Contributor

I think it has to do with the properties of the buffer_radius field.  Maybe there's something amiss with regards to scale and precision that won't let numbers like 2043.8900146484375 and 4087.780029296875 fit inside it.  Or, if buffer_radius is a text field, maybe it's not long enough.  What can you tell us about that field?

0 Kudos
DavidAnderson_1701
Frequent Contributor

Throwing a few thoughts out here.  How about using a lambda function?  Also I wonder about the use of the {}.  In't that the syntax for defining a dictionary?  I think the NAN might be because the return value is a NULL dictionary.

0 Kudos
DanPatterson
MVP Esteemed Contributor

{} is also used in python format strings.

 

median_area = 5
area = 2

func = f"""
def getBuffer(area):
    if area < {median_area}:
        return 1
     if area > {median_area}:
        return 2
"""

print(func)

def getBuffer(area):
    if area < 5:
        return 1
     if area > 5:
        return 2

 


... sort of retired...
0 Kudos
TomGeo
by
Frequent Contributor

Thanks for all the valuable thoughts and inputs. In the end, since I had all the logic anyway in Python, I ended up using an update cursor. Time wise, it is almost the same if I run those two CalculateField runs, slightly slower...

I tried the whole thing of course straight in ArcGIS Pro and there my code block works. However, I think @RogerDunnGIS has a fair point talking about the format of fields. The first CalculateField run is creating the buffer field, as 'TEXT'! But my second CalculateField run is using integers in the if-statement...

I haven't had time to try it, but 1 should not be '1', and thereby the error source is once more found about 40 cm in front of the screen. 😅

- We are living in the 21st century.
GIS moved on and nobody needs a format consisting out of at least three files! No, nobody needs shapefiles, not even for the sake of an exchange format. Folks, use GeoPackage to exchange data with other GIS!
0 Kudos