if then statement in field calculator, string to integer

1389
8
03-04-2014 05:16 AM
DavidKoch1
New Contributor
I am having a heck of a time trying to write an if elif script in the field calculator. I've read numerous threads but can't figure out how to do it right. I have a field called route_ty_1 that is a string field, with possible attributes of "Bus," "Rail," "LightRail," etc. For a given attribute, I want a code number to be returned for the site_code field, which is short integer. Here is the code I have been tinkering with:

Pre-logic script code:
def Reclass(site_code):
  if route_ty_1 == 'Bus':
    return 338
  elif route_ty_1 == 'LIGHT RAIL':
    return 281
  elif route_ty_1 == 'METRO':
    return 335
  elif route_ty_1 == 'Rail':
    return 282
  elif route_ty_1 == 'Commuter Bus':
    return 336


site_code =
Reclass(!site_code!)


If there is a better way to do this than if statements I am very open to suggestions! Thanks!
Tags (2)
0 Kudos
8 Replies
JamesCrandall
MVP Frequent Contributor
I am terrible with the field calculator myself, but shouldn't it be (emphasis in bold):


def Reclass(route_ty_1):
  if route_ty_1 == 'Bus':
    return 338
  elif route_ty_1 == 'LIGHT RAIL':
    return 281
  elif route_ty_1 == 'METRO':
    return 335
  elif route_ty_1 == 'Rail':
    return 282
  elif route_ty_1 == 'Commuter Bus':
    return 336



Also, maybe have an 'else' in the statement as well to pickup anything that doesn't evaluate in your if statement.

edit: upvoted Joshua's solution v:  a  more complete answer.  Mine was lazy 🙂
0 Kudos
JoshuaChisholm
Occasional Contributor III
Hello David,

There are some interesting options here.

That being said, I often use the else if method. If I may suggest a few things, I would add a .lower() (makes it case insensitive) and a .strip() (gets rid of any leading or trailing whitespace) to make sure you are matching as many of the cases as possible. I'd also add a else to catch any records that don't match at all.

def Reclass(site_code):
  site_code=site_code.lower().strip()
  if site_code == 'bus':
    return 338
  elif site_code == 'light rail':
    return 281
  elif site_code == 'metro':
    return 335
  elif site_code == 'rail':
    return 282
  elif site_code == 'commuter bus':
    return 336
  else:
    return 0


Good luck!
0 Kudos
DavidKoch1
New Contributor
Thanks Joshua--should there be anything in the .lower and .strip parentheses?

Hello David,

There are some interesting options here.

That being said, I often use the else if method. If I may suggest a few things, I would add a .lower() (makes it case insensitive) and a .strip() (gets rid of any leading or trailing whitespace) to make sure you are matching as many of the cases as possible. I'd also add a else to catch any records that don't match at all.

def Reclass(site_code):
  site_code=site_code.lower().strip()
  if site_code == 'bus':
    return 338
  elif site_code == 'light rail':
    return 281
  elif site_code == 'metro':
    return 335
  elif site_code == 'rail':
    return 282
  elif site_code == 'commuter bus':
    return 336
  else:
    return 0


Good luck!
0 Kudos
JoshuaChisholm
Occasional Contributor III
Thanks Joshua--should there be anything in the .lower and .strip parentheses?

Nope!

If you want, you can specify characters you want removed from the front and end of a string with the strip() function, but leaving it empty will remove whitespace by default.
0 Kudos
DavidKoch1
New Contributor
Thanks--I am getting the following errors:

ERROR 000539: Error running expression: Reclass(0) 
Traceback (most recent call last):
  File "<expression>", line 1, in <module>
  File "<string>", line 2, in Reclass
AttributeError: 'int' object has no attribute 'lower'

Failed to execute (CalculateField).



Nope!

If you want, you can specify characters you want removed from the front and end of a string with the strip() function, but leaving it empty will remove whitespace by default.
0 Kudos
JoshuaChisholm
Occasional Contributor III
Thanks--I am getting the following errors:

ERROR 000539: Error running expression: Reclass(0) 
Traceback (most recent call last):
  File "<expression>", line 1, in <module>
  File "<string>", line 2, in Reclass
AttributeError: 'int' object has no attribute 'lower'

Failed to execute (CalculateField).

I think you're calculating on the wrong field. Based on the strings you're looking for (in the if statements), the input should be a string (not an integer/number).

Make sure the expression reads something like Reclass(!inputTansitType!) .

It might actually be less confusing if you changed the variable name in the code book:

def Reclass(inputTansitType):
  inputTansitType=inputTansitType.lower().strip()
  if inputTansitType== 'bus':
    return 338
  elif inputTansitType== 'light rail':
    return 281
  elif inputTansitType== 'metro':
    return 335
  elif inputTansitType== 'rail':
    return 282
  elif inputTansitType== 'commuter bus':
    return 336
  else:
    return 0

Sorry if I caused any confusion!
0 Kudos
MathewCoyle
Frequent Contributor
As an aside, I find it much easier to use a dictionary in these cases.

reclass_dict = {'bus': 338,
        'light rail': 281,
        'metro': 335,
        'rail': 282,
        'commuter bus': 336,
        }

def Reclass(inputTansitType):
    inputTansitType = inputTansitType.lower().strip()
    try:
        return reclass_dict[inputTansitType]
    except:
        return 0
0 Kudos
DavidKoch1
New Contributor
Thanks everyone for your help! Joshua, you were right about calculating on the wrong field. Mathew's method also worked great.
0 Kudos