2

I'm trying to find and update a list of all the field values for alternate pin numbers (syntax being: XX-XX-XXX-XXX). I want to cycle through the pin numbers to find all of the pins beginning with 14 and 34 (14-XX-XXX-XXX, 34-XX-XXX-XXX).

I am needing to update those parcel pins to have a township number in front of the pins. (EX: 01-14-XX-XXX-XXX and 01-34-XX-XXX-XXX)

This is what I have so far:

import arcpy
#Set workspace
arcpy.env.workspace = "C:\prj\IL\Bond\geodb\Bond_Master.mdb"

#Define input features and shapefile tables
ParcelPolygon = r"C:\prj\IL\Bond\geodb\Bond_Master.mdb\Cadastral\Parcel_Poly"

#Define field for cursor
altpin = "ALTPin"

#Create update cursor
with arcpy.da.SearchCursor(ParcelPolygon, (altpin)) as cursor:
for row in cursor:
    try:
        first_index_value = int(row[0].split("-")[0])

        if first_index_value == 14:
            print "{0} - This parcel is in Tamalco township".format(row[0])
        else:
            print "{0} - This parcel is NOT in Tamalco township.".format(row[0])

    except Exception as error:
        print "Value: {0} is invalid\nError: {1}".format(row[0], error)
1

Give this a try:

import arcpy

arcpy.env.workspace = "C:\prj\IL\Bond\geodb\Bond_Master.mdb"

ParcelPolygon = r"C:\prj\IL\Bond\geodb\Bond_Master.mdb\Cadastral\Parcel_Poly"

altpin = arcpy.AddFieldDelimiters(ParcelPolygon, "ALTPin")
where = """{0} IS NOT NULL""".format(altpin)

with arcpy.da.SearchCursor(ParcelPolygon, (altpin), where) as cursor:
    for row in cursor:
        first_index_value = str(row[0].split("-")[0])

        if first_index_value == "14":
            print "{0} - This parcel is in Tamalco township".format(row[0])
        else:
            print "{0} - This parcel is NOT in Tamalco township.".format(row[0])
  • 1
    You should first check if row[0] is None before splitting it. Your current snippet will still always be an error on None, because you do something with it e.g. split before checking for None – GeoSharp Dec 13 '16 at 18:02
  • 1
    You have changed the code since I left that comment. Being None should not be an exception but more of a flow control in this snippet, e.g. if it is None it does not fit his criteria, continue working, that is not really an exception. – GeoSharp Dec 13 '16 at 18:04
  • 1
    This worked! Thank you so much. I'm new to python and coding in GIS so thank you so much for the help! – Misure Dec 13 '16 at 20:23
  • Instead of using try/except, I often find it cleaner to use if and continue. So, if row[0] is None: (or perhaps just if not row[0]:) continue. This will just skip to the next iteration in the cursor. For example. It's a nice way of "filtering" the iterations without adding escalating indents. – mr.adam Dec 13 '16 at 20:42
  • I used row[0] is None: continue and that helped clear the None values. I have polygons that have no values for other purposes. Thanks for the help. – Misure Dec 13 '16 at 21:13
7

Rather than using .startswith() which will return anything that starts with 14, even '14gis_analysts', to also respect the criteria of what the pin looks like. I suggest to use regular expressions. A regular expression to match pins beginning with 14 or 34 (14-XX-XXX-XXX, 34-XX-XXX-XXX) would look something like this:

^((?:14|34)-\d{2}-\d{3}-\d{3})$

In your code you would then use it like this:

import re
pattern = r'^((?:14|34)-\d{2}-\d{3}-\d{3})$'
#omitting code before loop
for row in rows:
    altpinValue = row.getValue(altpin)
    match = re.findall(pattern, altpinValue)
    if len(match) == 1:
        #do what you need with the value

Although it may taking a bit of getting used to the power of regular expressions is incredible and is very useful for many GIS tasks. By respecting the whole pattern of what you are matching, rather than just a portion of it you will develop potentially permanent and reusable solutions.

  • A superior approach! – Hornbydd Dec 14 '16 at 0:04
1

You have created a list over the fields in your parcel polygon dataset, this is unnecessary, your code needs to be this:

import arcpy
#Set workspace
arcpy.env.workspace = "C:\prj\IL\Bond\geodb\Bond_Master.mdb"

#Define input features and shapefile tables
ParcelPolygon = r"C:\prj\IL\Bond\geodb\Bond_Master.mdb\Cadastral\Parcel_Poly"

#Define field for cursor
altpin = "ALTPin"

#Create update cursor
rows = arcpy.UpdateCursor(ParcelPolygon)
for row in rows:
    altpinValue = row.getValue(altpin)
    if altpinValue.startswith("14"):
        print("this parcel is in tamalco township")
    else:
        print(altpinValue)
  • Hi, thanks for helping clean up my code. However, it still is not returning the values that begin with the 14 township number. – Misure Dec 13 '16 at 17:00
  • So what is it returning? Suggest you amend your question and show an example of the input data. – Hornbydd Dec 13 '16 at 17:04
  • It's returning all of the altpinValue's for example: a parcel pin 12-13-402-001. I am wanting it to return "this parcel is in tamalco township" for every parcel that its Pin number has a 14 for the first 2 digits. – Misure Dec 13 '16 at 17:25
  • I could me missing something here, but it almost sounds like you only want it to return "this parcel is in tamalco township" for those where it is starts with a 14, and you want it to do NOTHING with the others? If you want it to skip all the others entirely, then use the above code and under else: replace print(altpinValue) with pass. Maybe I'm missing the point though? – John Dec 13 '16 at 17:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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