concatenation of fields using python

1996
11
Jump to solution
12-07-2012 07:04 AM
JessicaKirby
New Contributor III
Hi Python Guru's
I need help figuring out how to populate an attribute field using python

I need to create a label field that is a concatenation of 4 fields in my dataset; Quad, Township, Range and Section

My problem is that the Quad is a numeric field that represents the direct or text label

for example
Quad = 3 (where 1= NW, 2 = NE, 3 = SW, 4 = SE)
Township = 16
Range = 42
Section = 36

the output label field needs to be a text field that reads like this:  T16S R42W Sec36 
Where the S in township  and W in range come from the quad = 3 for SW

I have no idea where to start this one. Any help is truly appreciated!
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
JessicaKirby
New Contributor III
Ok got it fixed.  Your field names being different from mine definitely caused some problems.  Also, the range and township fields were of float type, which was causing problems as well.  I copied those fields as short ints to fix the problem. This now works perfectly for me.  Here is the solution, all that you will need to change is the path to the Owner_Surface feature class. 

import arcpy, sys, traceback  sections = r'C:\TESTING\TestData\TestData.gdb\Owner_Surface' def Quads(sections):     urows = arcpy.UpdateCursor(sections)     for row in urows:         if row.quad == 1:             row.setValue('QUAD_LBL','N W')             urows.updateRow(row)         elif row.quad == 2:             row.setValue('QUAD_LBL','N E')             urows.updateRow(row)         elif row.quad == 3:             row.setValue('QUAD_LBL','S W')             urows.updateRow(row)         elif row.quad == 4:             row.setValue('QUAD_LBL','S E')             urows.updateRow(row)     del row, urows  try:     # add fields     arcpy.AddField_management(sections, 'QUAD_LBL', 'TEXT','','', 3)     arcpy.AddField_management(sections, 'LABEL', 'TEXT','','', 15)     arcpy.AddField_management(sections, 'townshp2', 'SHORT')     arcpy.AddField_management(sections, 'range2', 'SHORT')      # update new field for quads label     Quads(sections)      # Generate full label field     urows = arcpy.UpdateCursor(sections)     for row in urows:         row.townshp2 = row.township         row.range2 = row.range         quad = row.QUAD_LBL  # splits by space in new quad field         twp = row.townshp2         rng = row.range2         sec = row.section_         row.LABEL = 'T%s%s R%s%s Sec%s' %(twp, quad.split(' ')[0], rng, quad.split(' ')[-1], sec)          urows.updateRow(row)     del row, urows     print 'Done'  except:     # Get the traceback object     tb = sys.exc_info()[2]     tbinfo = traceback.format_tb(tb)[0]      # Concatenate information together concerning the error into a message string     pymsg = "PYTHON ERRORS:\nTraceback info:\n" + tbinfo + "\nError Info:\n" + str(sys.exc_info()[1])     msgs = "ArcPy ERRORS:\n" + arcpy.GetMessages(2) + "\n"      # Return python error messages for use in script tool or Python Window     arcpy.AddError(pymsg)     arcpy.AddError(msgs)      # Print Python error messages for use in Python / Python Window     print pymsg + "\n"     print msgs


I also used a print statement to show the labels being populated:

T21S R7E Sec36
T30S R12W Sec34
T14N R2E Sec18
T2N R25W Sec2
Done


This is awsome! Works like a charm, Thank you so very much!

View solution in original post

0 Kudos
11 Replies
DarrenWiens2
MVP Honored Contributor
Probably the simplest thing to do is make two new columns - northsouth and eastwest. If Quad = 1 or 2, northsouth = N. If Quad = 3 or 4, northsouth = S. And so on. Use those fields in your label.

edit: once you have "northsouth" and "eastwest" populated with the proper letters, you can make your label expression to be:
 "T" & [Township] & [northsouth] & " R" & [Range] & [eastwest] & " Sec" & [Section]
0 Kudos
by Anonymous User
Not applicable
This is meant for a stand alone script, would need to be modified as code block for field calculator.  Completely untested, but maybe something like this would work:

import arcpy

sections = r'G:\PLSS\PLSS.mdb\Sections'
def Quads(sections):
    urows = arcpy.UpdateCursor(sections)
    for row in urows:
        if row.Quad == '1': #  if string type
            row.QUAD_LBL = 'N W'
            urows.updateRow(row)
        elif row.Quad == '2':
            row.QUAD_LBL = 'N E'
            urows.updateRow(row)
        elif row.Quad == '3':
            row.QUAD_LBL = 'S W'
            urows.updateRow(row)
        elif row.Quad == '4':
            row.QUAD_LBL = 'S E'
            urows.updateRow(row)
    del row, urows

try:
    # add fields
    arcpy.AddField_management(sections, 'QUAD_LBL', 'TEXT','','', 3)
    arcpy.AddField_management(sections, 'LABEL', 'TEXT','','', 15)

    # update new field for quads label
    Quads(sections)

    # Generate full label field
    urows = arcpy.UpdateCursor(sections)
    for row in urows:
        quad1 = row.QUAD_LBL.split(' ')[0]  # splits by space in new quad field
        quad2 = row.QUAD_LBL.split(' ')[-1]
        twp = row.Township
        rng = row.Range
        sec = row.Section
        row.LABEL = 'T%s%s R%s%s Sec%s' %(twp, quad1, rng, quad2, sec)
        urows.updateRow(row)
    del row, urows

except Exception as e:
    print e.message
    
    # If using this code within a script tool, AddError can be used to return messages 
    #   back to a script tool.  If not, AddError will have no effect.
    arcpy.AddError(e.message)
0 Kudos
JessicaKirby
New Contributor III
Hi Caleb
Thanks for the code, this seems to be the trick
but.... I am recieving the following error

ERROR 999999: Error executing function.
The value type is incompatible with the field type. [Quad]

My Quad field type is short int
do I need to change it to a text to accept the  row.quad = 'N W' ect,?
any thoughts

-----------------------------Please disreguard this post, I just realized what i did
0 Kudos
by Anonymous User
Not applicable
Ah that is an easy fix.  I had it set up for if your quad field was of text type. All you need to do is remove the single quotes wrapping around the value:

for row in urows:
        if row.Quad == 1:
            row.QUAD_LBL = 'N W'
            urows.updateRow(row)
        elif row.Quad == 2:
            row.QUAD_LBL = 'N E'
            urows.updateRow(row)
        elif row.Quad == 3:
            row.QUAD_LBL = 'S W'
            urows.updateRow(row)
        elif row.Quad == 4:
            row.QUAD_LBL = 'S E'
            urows.updateRow(row)
    del row, urows


Did it work with this change?
0 Kudos
JessicaKirby
New Contributor III
Ah that is an easy fix.  I had it set up for if your quad field was of text type. All you need to do is remove the single quotes wrapping around the value:

for row in urows:
        if row.Quad == 1:
            row.QUAD_LBL = 'N W'
            urows.updateRow(row)
        elif row.Quad == 2:
            row.QUAD_LBL = 'N E'
            urows.updateRow(row)
        elif row.Quad == 3:
            row.QUAD_LBL = 'S W'
            urows.updateRow(row)
        elif row.Quad == 4:
            row.QUAD_LBL = 'S E'
            urows.updateRow(row)
    del row, urows


Did it work with this change?


when I remove the ' ' i get syntax error at row
row.QUAD_LBL = N E
0 Kudos
by Anonymous User
Not applicable
hmmm, perhaps the row.setValue may work here:

import arcpy

sections = r'G:\PLSS\PLSS.mdb\Sections'
def Quads(sections):
    urows = arcpy.UpdateCursor(sections)
    for row in urows:
        if row.Quad == 1:
            row.setValue('QUAD_LBL','N W')
            urows.updateRow(row)
        elif row.Quad == 2:
            row.setValue('QUAD_LBL','N E')
            urows.updateRow(row)
        elif row.Quad == 3:
            row.setValue('QUAD_LBL','S W')
            urows.updateRow(row)
        elif row.Quad == 4:
            row.setValue('QUAD_LBL','S E')
            urows.updateRow(row)
    del row, urows

try:
    # add fields
    arcpy.AddField_management(sections, 'QUAD_LBL', 'TEXT','','', 3)
    arcpy.AddField_management(sections, 'LABEL', 'TEXT','','', 15)

    # update new field for quads label
    Quads(sections)

    # Generate full label field
    urows = arcpy.UpdateCursor(sections)
    for row in urows:
        quad1 = row.getValue('QUAD_LBL').split(' ')[0]  # splits by space in new quad field
        quad2 = row.getValue('QUAD_LBL).split(' ')[-1]
        twp = row.getValue('Township')
        rng = row.getValue('Range')
        sec = row.getValue('Section')
        row.setValue('LABEL','T%s%s R%s%s Sec%s' %(twp, quad1, rng, quad2, sec))
        urows.updateRow(row)
    del row, urows

except Exception as e:
    print e.message
    
    # If using this code within a script tool, AddError can be used to return messages 
    #   back to a script tool.  If not, AddError will have no effect.
    arcpy.AddError(e.message)


If this doesnt work, would you mind posting just a subset of your data so I could test and figure out what is going wrong?

PS I just had to fix something else in this
0 Kudos
JessicaKirby
New Contributor III
hmmm, perhaps the row.setValue may work here:

import arcpy

sections = r'G:\PLSS\PLSS.mdb\Sections'
def Quads(sections):
    urows = arcpy.UpdateCursor(sections)
    for row in urows:
        if row.Quad == 1:
            row.setValue('QUAD_LBL','N W')
            urows.updateRow(row)
        elif row.Quad == 2:
            row.setValue('QUAD_LBL','N E')
            urows.updateRow(row)
        elif row.Quad == 3:
            row.setValue('QUAD_LBL','S W')
            urows.updateRow(row)
        elif row.Quad == 4:
            row.setValue('QUAD_LBL','S E')
            urows.updateRow(row)
    del row, urows

try:
    # add fields
    arcpy.AddField_management(sections, 'QUAD_LBL', 'TEXT','','', 3)
    arcpy.AddField_management(sections, 'LABEL', 'TEXT','','', 15)

    # update new field for quads label
    Quads(sections)

    # Generate full label field
    urows = arcpy.UpdateCursor(sections)
    for row in urows:
        quad1 = row.getValue('QUAD_LBL').split(' ')[0]  # splits by space in new quad field
        quad2 = row.getValue('QUAD_LBL).split(' ')[-1]
        twp = row.getValue('Township')
        rng = row.getValue('Range')
        sec = row.getValue('Section')
        row.setValue('LABEL','T%s%s R%s%s Sec%s' %(twp, quad1, rng, quad2, sec))
        urows.updateRow(row)
    del row, urows

except Exception as e:
    print e.message
    
    # If using this code within a script tool, AddError can be used to return messages 
    #   back to a script tool.  If not, AddError will have no effect.
    arcpy.AddError(e.message)


If this doesnt work, would you mind posting just a subset of your data so I could test and figure out what is going wrong?

PS I just had to fix something else in this


Still getting error
'NoneType' object has no attribute 'split'

attached is some test data (10.0 GDB), Thank you so much for helping me out with this!!!
p.s.  field names need editing (no capital letters and there is an underscore on section)
quad
township
range
section_
0 Kudos
by Anonymous User
Not applicable
Ok got it fixed.  Your field names being different from mine definitely caused some problems.  Also, the range and township fields were of float type, which was causing problems as well.  I copied those fields as short ints to fix the problem. This now works perfectly for me.  Here is the solution, all that you will need to change is the path to the Owner_Surface feature class. 

import arcpy, sys, traceback

sections = r'C:\TESTING\TestData\TestData.gdb\Owner_Surface'
def Quads(sections):
    urows = arcpy.UpdateCursor(sections)
    for row in urows:
        if row.quad == 1:
            row.setValue('QUAD_LBL','N W')
            urows.updateRow(row)
        elif row.quad == 2:
            row.setValue('QUAD_LBL','N E')
            urows.updateRow(row)
        elif row.quad == 3:
            row.setValue('QUAD_LBL','S W')
            urows.updateRow(row)
        elif row.quad == 4:
            row.setValue('QUAD_LBL','S E')
            urows.updateRow(row)
    del row, urows

try:
    # add fields
    arcpy.AddField_management(sections, 'QUAD_LBL', 'TEXT','','', 3)
    arcpy.AddField_management(sections, 'LABEL', 'TEXT','','', 15)
    arcpy.AddField_management(sections, 'townshp2', 'SHORT')
    arcpy.AddField_management(sections, 'range2', 'SHORT')

    # update new field for quads label
    Quads(sections)

    # Generate full label field
    urows = arcpy.UpdateCursor(sections)
    for row in urows:
        row.townshp2 = row.township
        row.range2 = row.range
        quad = row.QUAD_LBL  # splits by space in new quad field
        twp = row.townshp2
        rng = row.range2
        sec = row.section_
        row.LABEL = 'T%s%s R%s%s Sec%s' %(twp, quad.split(' ')[0], rng, quad.split(' ')[-1], sec)

        urows.updateRow(row)
    del row, urows
    print 'Done'

except:
    # Get the traceback object
    tb = sys.exc_info()[2]
    tbinfo = traceback.format_tb(tb)[0]

    # Concatenate information together concerning the error into a message string
    pymsg = "PYTHON ERRORS:\nTraceback info:\n" + tbinfo + "\nError Info:\n" + str(sys.exc_info()[1])
    msgs = "ArcPy ERRORS:\n" + arcpy.GetMessages(2) + "\n"

    # Return python error messages for use in script tool or Python Window
    arcpy.AddError(pymsg)
    arcpy.AddError(msgs)

    # Print Python error messages for use in Python / Python Window
    print pymsg + "\n"
    print msgs


I also used a print statement to show the labels being populated:

T21S R7E Sec36
T30S R12W Sec34
T14N R2E Sec18
T2N R25W Sec2
Done
0 Kudos
JessicaKirby
New Contributor III
Ok got it fixed.  Your field names being different from mine definitely caused some problems.  Also, the range and township fields were of float type, which was causing problems as well.  I copied those fields as short ints to fix the problem. This now works perfectly for me.  Here is the solution, all that you will need to change is the path to the Owner_Surface feature class. 

import arcpy, sys, traceback  sections = r'C:\TESTING\TestData\TestData.gdb\Owner_Surface' def Quads(sections):     urows = arcpy.UpdateCursor(sections)     for row in urows:         if row.quad == 1:             row.setValue('QUAD_LBL','N W')             urows.updateRow(row)         elif row.quad == 2:             row.setValue('QUAD_LBL','N E')             urows.updateRow(row)         elif row.quad == 3:             row.setValue('QUAD_LBL','S W')             urows.updateRow(row)         elif row.quad == 4:             row.setValue('QUAD_LBL','S E')             urows.updateRow(row)     del row, urows  try:     # add fields     arcpy.AddField_management(sections, 'QUAD_LBL', 'TEXT','','', 3)     arcpy.AddField_management(sections, 'LABEL', 'TEXT','','', 15)     arcpy.AddField_management(sections, 'townshp2', 'SHORT')     arcpy.AddField_management(sections, 'range2', 'SHORT')      # update new field for quads label     Quads(sections)      # Generate full label field     urows = arcpy.UpdateCursor(sections)     for row in urows:         row.townshp2 = row.township         row.range2 = row.range         quad = row.QUAD_LBL  # splits by space in new quad field         twp = row.townshp2         rng = row.range2         sec = row.section_         row.LABEL = 'T%s%s R%s%s Sec%s' %(twp, quad.split(' ')[0], rng, quad.split(' ')[-1], sec)          urows.updateRow(row)     del row, urows     print 'Done'  except:     # Get the traceback object     tb = sys.exc_info()[2]     tbinfo = traceback.format_tb(tb)[0]      # Concatenate information together concerning the error into a message string     pymsg = "PYTHON ERRORS:\nTraceback info:\n" + tbinfo + "\nError Info:\n" + str(sys.exc_info()[1])     msgs = "ArcPy ERRORS:\n" + arcpy.GetMessages(2) + "\n"      # Return python error messages for use in script tool or Python Window     arcpy.AddError(pymsg)     arcpy.AddError(msgs)      # Print Python error messages for use in Python / Python Window     print pymsg + "\n"     print msgs


I also used a print statement to show the labels being populated:

T21S R7E Sec36
T30S R12W Sec34
T14N R2E Sec18
T2N R25W Sec2
Done


This is awsome! Works like a charm, Thank you so very much!
0 Kudos