python in ArcGIS, need help!

897
4
04-25-2017 01:28 PM
JohnMcoy
New Contributor III

Hello everyone,


So I started to work with ArcGis and Python. And I got a task.

This is what I have to do:

Check that all the objects have filled Glb_Cpy field. If found empty object, then this field has to be filled by Glb_ID value.

So I did it. But now I have to create statement, if fc doesn`t have Glb_ID or Glb_Cpy fields, then arcpy.AddError("Invalid Data") ->return and script stops.  else arcpy.AddMessage("Valid Data") and complete the script. I know that I`m thinknig that i need to use arcpy.Exists , arcpy.ListFields or arcpy.Describe ... I hope someone understood me.

Waiting any suggestions! Thanks!

 

import arcpy

def main(fc):
 
    desc = arcpy.Describe(fc)

    if desc:
        arcpy.AddError("Invalid Data")
        return
 
    else:
        arcpy.AddMessage("Valid Data")
        with arcpy.da.UpdateCursor(fc, ['Glb_ID', 'Glb_Cpy'], 'Glb_Cpy IS NULL') as cursor:
        for row in cursor:
            row[1] = row[0]
            # Update the cursor with the updated list
            cursor.updateRow(row)

if __name__ == "__main__":
    main(arcpy.GetParameter(0))‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
Tags (1)
0 Kudos
4 Replies
RebeccaStrauch__GISP
MVP Esteemed Contributor

Please edit your post and use https://community.esri.com/people/curtvprice/blog/2014/09/25/posting-code-blocks-in-the-new-geonet?s...‌ so and spacing errors can be removed, and those responding can respond to a line number if needed.  Thanks. 

curtvprice
MVP Esteemed Contributor

The usual Pythonic approach is to use exception handling with things like that (try first, rather than ask for permission) rather than spend a lot of effort coding for specific error conditions. The error message you will get here if the fields are missing should point you toward the "fix". Also, we almost always use GetParameterAsText as text is easier to handle.

import arcpy

def main(fc):
 
    try:
        with arcpy.da.UpdateCursor(fc, ['Glb_ID', 'Glb_Cpy'], 
                                   'Glb_Cpy IS NULL') as cursor:
            for row in cursor:
                row[1] = row[0]
                cursor.updateRow(row)
    except Exception as e:
         arcpy.AddError(e)

if __name__ == "__main__":
    main(arcpy.GetParameterAsText(0))‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
JoshuaBixby
MVP Esteemed Contributor

If you want to take a classic look-before-you-leap (LBYL) approach, the following is a fairly Pythonic away to approach it:

import arcpy

def main(fc):
 
    field_checks = ['Glb_ID', 'Glb_Cpy']
    fields = set(field.name.upper() for field in arcpy.ListFields(fc))
    
    if all(field.upper() in fields for field in field_checks):
        arcpy.AddMessage("Valid Data")
        with arcpy.da.UpdateCursor(fc, ['Glb_ID', 'Glb_Cpy'], 'Glb_Cpy IS NULL') as cursor:
        for row in cursor:
            row[1] = row[0]
            # Update the cursor with the updated list
            cursor.updateRow(row)
    else:
        arcpy.AddError("Invalid Data")
        return


if __name__ == "__main__":
    main(arcpy.GetParameter(0))

Since text is involved, you will want to force either all uppercase or lowercase or you membership tests might fail when the field is really present.  Python sets have very performant membership tests, which is why I went with creating a set instead of a list.  In reality, the user would not notice a timing difference between either given the small number of fields and checks involved.

Of course, you can take the easier-to-ask-forgiveness-than-permission (EAFP) approach proposed by curtvprice‌.

XanderBakker
Esri Esteemed Contributor

A small variation based on the options provided above. See (untested) code below.

In this case it will add the ouput field if it does not exist

import arcpy

def main(fc):

    fld_in = 'Glb_ID'
    fld_out = 'Glb_Cpy'

    if FieldExists(fc, fld_in):
        arcpy.AddMessage("Valid input field...")
        if FieldExists(fc, fld_out) == False:
            arcpy.AddMessage("Output field does not exist, add output field...")
            fld_info = GetFieldInfo(fc, fld_in)

        with arcpy.da.UpdateCursor(fc, (fld_in, fld_out), '{0} IS NULL'.format(fld_out)) as cursor:
            for row in cursor:
                row[1] = row[0]
                # Update the cursor with the updated list
                cursor.updateRow(row)
    else:
        arcpy.AddError("Input field does not exist...")

def FieldExists(fc, fld_name):
    return len(arcpy.ListFields(fc, fld_name)) == 1

def AddField(fc, fld_info):
        arcpy.AddField_management(fc_out, *fld_info)

def GetFieldInfo(fc, fld_name):
    fld = arcpy.ListFields(fc, fld_name)[0]
    fld_info = [fld.name, mapField(fld), fld.precision, fld.scale,
                fld.length, fld.aliasName, fld.isNullable, fld.required,
                fld.domain]
    return fld_info

if __name__ == "__main__":
    main(arcpy.GetParameter(0))