0

I recognize similar questions have been asked but I have yet to see what my code is lacking in any of their answers.

I am trying to use the code below to periodically update attributes in a Feature Class that is often added to during our survey. The goal is every time the 'SBP Anomaly' or 'BS Anomaly' is present in the 'Target_Typ' column a sequential integer will be marked in the 'SBP_Num' and 'BCKSCTR_Nu'(Better name forthcoming) columns respectively.

The first two 'for loops' under my Update Cursor are operating correctly, however, the third doesn't update/populate its target fields when the conditions are met.

import arcpy

fc =  arcpy.GetParameterAsText(0)

fields = ['Target_num','Target_Typ','WCA_Label', 'BCKSCTR_Nu', 'SBP_Num' ]

i = 1
x = 1
s = 1

with arcpy.da.UpdateCursor(fc,fields) as rows:
    for y in rows:
        y[0] = x
        x+=1
        rows.updateRow(y)

    for row in rows:
        if row[2] != None and row[1] != 'SBP Anomaly':
            row[1] = "WC Anomaly"
        else:
            row[1] = "BS Anomaly"
        rows.updateRow(row)

    for TypeCount in rows:
        if row[1] == 'SBP Anomaly':
            row[4] = int(s)
            s += 1
        elif row[1] == 'BS Anomaly':
            row[3] = int(i) 
            i += 1
        else:
            pass
        rows.updateRow(TypeCount)

del rows

An image of the attribute table I am trying to manipulate is included also for reference. I have made sure the Target fields for third 'for loop' are set up as the correct object type: short integers (at least I think that's appropriate ) and not strings so they should take the integers i/s. I have tried them as strings and Long integers, and even float one time.

enter image description here

Update based on some suggestions from various users. Tried this code and still no luck.

import arcpy

fc =  arcpy.GetParameterAsText(0)

fields = ['Target_num','Target_Typ','WCA_Label', 'BCKSCTR_Nu', 'SBP_Num' ]

i = 1
x = 1
s = 1

with arcpy.da.UpdateCursor(fc,fields) as rows:
    for row in rows:
        row[0] = x
        x+=1

        if row[2] != None and row[1] != 'SBP Anomaly':
            row[1] = "WC Anomaly"
        else:
            row[1] = "BS Anomaly"

        if row[1] == 'SBP Anomaly':
            row[4] = s
            s += 1
        elif row[1] == 'BS Anomaly':
            row[3] = i
            i += 1
        else:
            pass
        rows.updateRow(row)

Also per one users comment, A more detailed description of what I want to acheive. Entries in this feature class are usually manually entered via creating features, i.e. picking them based on data available. When that happens several attributes need to be update manually.

-The Target_Num or Target number needs to be entered in sequential order. That hasn't been a problem so much.

-The 'BS' and 'SBP' anomalies will have be populated in the Target Type column, however, the WS anomalies need to be manually input in that column. These are added from another software program so that particular attribute needs to be populated. The idea with this code is that it takes another column attribute, one that only exists for the WC anomaly, and when there is data present, set the Target type to 'WC Anomaly'. Elsewise, Make it a Backscatter Anomaly. The only prohibitive condition with this is if there if Target Type is already listed as a 'SBP Anomaly', which should be left alone.

-Lastly, if the Target type is equal to SBP or BS anomaly, then it should populate the SBP/BSCKTR_Num column. This is to keep a running tally of how many of each targets there is.

4
  • Your third code blocks continues to use row, even though it was last defined in the second block, and the TypeCount variable was never modified.
    – Vince
    Apr 21, 2019 at 1:10
  • Jesus... that's embarrassing. Thanks Vince. Unfortunately fixing that didn't quite help. I'll upload the update code. Apr 21, 2019 at 1:49
  • 1
    What do you mean by "no luck"
    – BERA
    Apr 21, 2019 at 17:05
  • 1
    Bera, Im not sure where your answer went, but that put me on the right track. I had been testing this code on an exported geodatabase feature class that had been exported to a shapefile for testing. When I made a test geodatabase and exported it to a FC instead of a SHP, its all of a sudden working a lot better. I'm not sure why that would be, any insight would be great. There are still some bugs but I am definitely on the right track. thanks for your help. Apr 21, 2019 at 17:17

1 Answer 1

1

Not sure what you are trying to do, your table filled in with your expected values would help.

But your first for loop will exhaust your cursor. Example:

import arcpy

fc = r"X:\Testdata\polys.shp"
field = "id"

with arcpy.da.UpdateCursor(fc,field) as cursor:
    for row in cursor:
        print(f'First loop at {field} {row[0]}')
    print('Im empty')

    for row2 in cursor:
        print(f'Second loop at {field} {row2[0]}')

When first for loop is done the cursor is empty and will not enter second loop:

First loop at id 4
First loop at id 5
First loop at id 2
First loop at id 3
First loop at id 1
Im empty

You have to reset it using cursor.reset() or recreate it to loop over all rows a second time. I have never had to do this since one updatecursor can be used to update multiple fields in a row.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.