3

If STREETNM value are blank or _ then I want to replace them with the value of ST_DESIG. My code below returned the code value of ST_DESIG but not the description.

How can I get the description value of the ST_DESIG. For example, "Divided Major Highway - Class II" NOT 1.

enter image description here

import arcpy
Streets_Centerlines = r"G:\xStreetNew\Test.gdb\Streets_Centerlines"
expression = "replace(!STREETNM!)"
codeblock = """
def replace(STREETNM,ST_DESIG):
 if STREETNM.lstrip().rstrip() == '' or STREETNM.lstrip().rstrip() ==    '_':
      return ST_DESIG
 else:
      return STREETNM
"""
arcpy.CalculateField_management(Streets_Centerlines, "STREETNM", "replace(!STREETNM!,!ST_DESIG!)", "PYTHON", codeblock)
4

If I'm wrong, I'll give an upvote to whoever corrects me, but I don't think you can do that. Coded-value domains aren't usually very long so here's what I suggest. Since you are using Python, create a dictionary for your coded-value domain.

dict = {'0': 'None', '1': 'Divided Major Highway yada yada', '2': 'Major Highway - Class II'};

Then your if statement won't return ST_DESIG right away. Instead you will have to get the value of it and use it to look up the value in the dictionary.

return dict[ST_DESIG]

If the domain IS long (or for the sake of accuracy), you can use the "domain to table" tool to help you create that dictionary.

| improve this answer | |
  • It's fairly straightforward to pull the domain values from the gdb and use them to populate the field – Midavalo Apr 8 '16 at 4:43
  • That does look like it could be an improvement! – jbchurchill Apr 8 '16 at 16:13
3

You can look up domain values from the geodatabase and query the fields to find the names of the domain they reference. By limiting this lookup to just the field you're interested in (ST_DESIG) you can pull out all the coded domain values into a dictionary.

Once you have this dictionary you can make your arcpy.CalulateField_management code block reference the dictionary to update the value description rather than the coded value.

I have added a check for Null values (None in python) as these are different from an empty string ''.


For Field with Domain:

import arcpy

Streets_Centerlines = r"G:\xStreetNew\Test.gdb\Streets_Centerlines" 

# Get list of fields to find domain name
lfields = arcpy.ListFields(Streets_Centerlines)

for lf in lfields:
    if lf.name == 'ST_DESIG':
        if lf.domain:
            lookupDomain = lf.domain

# Get list of domains to pull out Code and Description
domains = arcpy.da.ListDomains(r'G:\xStreetNew\Test.gdb') 

for domain in domains:
    if domain.name == lookupDomain:
        domainValues = domain.codedValues

# Reference the domainValues dictionary from the code block
# to lookup the coded value and record the text description
expression = "replace(!STREETNM!, !ST_DESIG!)"
codeblock = """
def replace(STREETNM,ST_DESIG):
    dict = {0}
    if STREETNM == None:
        return dict[ST_DESIG]
    elif STREETNM.strip() == '' or STREETNM.strip() == '_':
        return dict[ST_DESIG]
    else:
        return STREETNM
""".format(domainValues)

arcpy.CalculateField_management(Streets_Centerlines, "STREETNM", expression, "PYTHON_9.3", codeblock)

For Field with SubType:

import arcpy

#Streets_Centerlines = r"G:\xStreetNew\Test.gdb\Streets_Centerlines" 
Streets_Centerlines = r'D:\temp\SE\SEData.gdb\MyFC'

# Check for SubType against 'ST_DESIG' and create
# subtypeVals dictionary to store SubType Codes and
# descriptions
subtypeVals = {}

subtypes = arcpy.da.ListSubtypes(Streets_Centerlines)
for stcode, stdict in subtypes.iteritems():
    if stdict['SubtypeField'] == 'ST_DESIG':
        for stkey in stdict.iterkeys():
            if stkey == 'Name':
                subtypeVals[stcode] = stdict[stkey]

# Reference the subtypeVals dictionary from the code block
# to lookup the coded value and record the text description
expression = "replace(!STREETNM!, !ST_DESIG!)"
codeblock = """
def replace(STREETNM,ST_DESIG):
    dict = {0}
    if STREETNM == None:
        return dict[ST_DESIG]
    elif STREETNM.strip() == '' or STREETNM.strip() == '_':
        return dict[ST_DESIG]
    else:
        return STREETNM
""".format(subtypeVals)

arcpy.CalculateField_management(Streets_Centerlines, "STREETNM", expression, "PYTHON_9.3", codeblock)
| improve this answer | |
  • Midavalo, This code looks good but I couldn't get it to run. I got error: "ExecuteError: ...Parameters are not valid..." . I will try to correct it and run it again. Thank you. – sys Apr 12 '16 at 22:29
  • Can you paste the full error message? – Midavalo Apr 12 '16 at 22:31
  • First, it complain about the domainValues and lookupDomain are not defined. Then I added: lookupDomain = r"G:\xStreetNew\Test.gdb\lookupDomain" domainValues = r"G:\xStreetNew\Test.gdb\domainValues". I ran the code again then I got this error: ExecuteError: Failed to execute. Parameters are not valid. ERROR 000989: Python syntax error: Parsing error SyntaxError: invalid syntax (line 3) Failed to execute (CalculateField). – sys Apr 13 '16 at 15:01
  • @sys Does this field have a Domain or a SubType? setting ` lookupDomain = r"G:\xStreetNew\Test.gdb\lookupDomain" ` and domainValues = r"G:\xStreetNew\Test.gdb\domainValues" won't work, these are incorrect values. The lookupDomain and domainValues should be set in the two for loops, so if they're not it means a) it's not finding a domain against your ST_DESIG field, and then b) it's not finding the domain (since it's not against that field). – Midavalo Apr 13 '16 at 18:10
  • @sys I have added code to lookup SubType values instead of Domains – Midavalo Apr 13 '16 at 19:59

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.