Running nested if then statements on selected features in a Python addin button

258
4
Jump to solution
05-10-2021 12:49 PM
kad37_pns
New Contributor II

Hello! 

I'm currently trying to create a button within arcmap that runs a set of if-then rules to fill in a blank field within the layer's attribute table. I've been able to do this in the field calculator with no problem, but in order to speed up the process, I would like to be able to run the process in one click rather than manually labeling. 

My issue is that I don't know how to get it so that the button takes the already selected features and then proceeds to run the nested statements. 

 

import arcpy
import pythonaddins

class BlockAnno(object):
    """Implementation for Test_addin.button (Button)"""
    def __init__(self):
        self.enabled = True
        self.checked = False
    def onClick(self):
		lyr = pythonaddins.GetSelectedTOCLayerOrDataFrame()
        with arcpy.da.UpdateCursor(lyr,["block", "sub_code"]) as blockanno:
			if sub_code != '0000': 
				if sub_code != '0780':
					if block[0:3].isdigit():
						blockanno = str(block[0:3].lstrip('0'))
					elif block[2].isalpha():
						if block[0:2] == '00':
							blockanno = str(block[0:].strip('0'))
		cursor.updateRow()
return(BlockAnno)

 

I'm hoping this is feasible, but would appreciate any guidance or advice. 

0 Kudos
1 Solution

Accepted Solutions
JeffK
by
Occasional Contributor III

Edited to fix indexes.

First look at it, I think you are missing some things for the cursor.  It looks like you are missing the iteration part:

 

for row in blockanno:
    if row[1] != '0000' and row[1] != '0780':
     ...

 

and

 

cursor.updateRow()

 

should be

 

blockanno.updateRow(row)

 

You need to include the field that you are updating.  As written, blockanno is the cursor object, so include the field that you want to update after the "sub_code" in the list of fields there so its index is row[2].

 

row[2] = str(row[0:].strip('0'))

 

 

Hopefully this will get you going.

View solution in original post

4 Replies
JeffK
by
Occasional Contributor III

Edited to fix indexes.

First look at it, I think you are missing some things for the cursor.  It looks like you are missing the iteration part:

 

for row in blockanno:
    if row[1] != '0000' and row[1] != '0780':
     ...

 

and

 

cursor.updateRow()

 

should be

 

blockanno.updateRow(row)

 

You need to include the field that you are updating.  As written, blockanno is the cursor object, so include the field that you want to update after the "sub_code" in the list of fields there so its index is row[2].

 

row[2] = str(row[0:].strip('0'))

 

 

Hopefully this will get you going.

View solution in original post

JeffK
by
Occasional Contributor III

And you need to indent the .updateRow(row) to be within the  ' with arcpy.da.UpdateCursor() ' call.

kad37_pns
New Contributor II

Thank you! That definitely changed my button from it's missing state. Unfortunately, however, even after the alterations to the script, it will not change those null values from the blockanno column to a product following the nested statements. Any thoughts? I suspect it's stemming from trying to grab the manually grabbed selected features, because if I run that function in the python window of my project, lyr comes up with "none".

 

 

import arcpy
import pythonaddins

class ButtonClass1(object):
    """Implementation for Test2_addin.button (Button)"""
    def __init__(self):
        self.enabled = True
        self.checked = False
    def onClick(self):
        ## if editing:
		## elif msg -- put on edit  and then exit
		lyr = pythonaddins.GetSelectedTOCLayerOrDataFrame()
		with arcpy.da.UpdateCursor(lyr,["block", "sub_code", "blockanno"]) as blockanno:
			for row in blockanno:
				if row[1] != '0000' and row[1] != '0780':
					if row[0][0:3].isdigit():
						row[2] = str(row[0:3].lstrip('0'))
					elif row[0].isalpha():
						if row[0][0:2] == '00':
							row[2] = str(row[0:].strip('0'))
			blockanno.updateRow(row)

 

 

 

0 Kudos
JeffK
by
Occasional Contributor III

Looking at the lines where you are assigning values to row[2], it looks like you are not selecting specific row index to slice.  you will need to reference that index position

row[2] = str(row[0][0:3].lstrip('0'))

and
row[2] = str(row[0][0:].strip('0'))

if you wanted to concatenate row index 0 and 1, you'll have to add each row index like

 

row[2] = f'{row[0]}{row[1]}'.lstrip('0')

and 

row[2] = f'{row[0]}{row[1]}'.strip('0')

 

0 Kudos