What am I doing wrong? Cant get type() to return a value.

1902
7
07-15-2016 12:06 PM
RobBlash
Regular Contributor

In field calculator this expression runs without an error, but it doesn't return a value. What am I doing wrong?

type(!MyField!)

0 Kudos
7 Replies
DanPatterson_Retired
MVP Esteemed Contributor

are you using it to calculate a value in a new field? or are you using it within a field calculator expression? And it may actually be returning something but not what you expect.  It is often more useful to use isinstance

a = 5

>>> isinstance(a,(int, float, complex))

True

You can then use it to its full advantage to control what goes into the field based upon its type/class.  For example to make an entry a string, you can check for its type, then do one thing and if it is something else, do another thing.  So to use the field entry (a =5) lets, make it a string if it is a number otherwise do something else

["string already", str(a)][ isinstance(a, (int,float,complex))]

This just uses boolean slicing with the left side  representing [do this if false, do this if true]

and the right side returning a boolean ... [ isinstance check ] since True and False equate to 1 and 0

RobBlash
Regular Contributor

Thanks Dan, I appreciate the detailed response.  I did find isinstance and started playing with it. What I'm really after is flagging non-integer values in a field. I'm parsing out house numbers from an address string and I want to flag any value that is not an integer for further review. Due to the nature of the data it's stored in a string field.

def gettype(LPart):
    return isinstance(LPart,int)


gettype( !LeftPart!)

Result.png

Calling the above function to populate the LType field gives the results shown above, but I would expect the last 3 rows to return 1 since they are integers. Is is returning false because the data is coming from a string field? Also, I see you are passing more arguments than just "int", I can't find any documentation on the classinfo argument, can you elaborate on that?

Thanks,

Rob

0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

ohhhh so for too much detail before, ... it is even simpler than that.... consider the following

>>> a = '630& 670'
>>> a.isalnum()
False
>>> b = '1234'
>>> b.isalnum()
True
>>> c = '1234 567'
>>> c.isalnum()
False
so you can still slice and dice
>>> [0,1][c.isalnum()]
0

just replace 'c' in the above with

    [0,1][ !YourFieldNameHere!.isalnum() ]

With the cavaet that you would have to use an integer field to calculate into

If you want to use a text field then you could use

  [ False, True][ !YourFieldNameHere!.isalnum() ] 
 # note you may have to str(False), str(True) if it doesn't like booleans in a text field
JakeSkinner
Esri Esteemed Contributor

Hi Robert,

I think you will want to use the ListFields function to return the field type.

ListFields—Help | ArcGIS for Desktop

RobBlash
Regular Contributor

Thanks, I'm sure this will be helpful in the future.

0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

A chunk of discussion went missing over the weekend revolving around using 'isdigit() versus 'isalnum()

I will comment here since the intent appears to be to return single addresses at a location and not a list of addresses sharing a location.

Consider the following:

>>> "1234A 1234B".isalnum()
False
>>> "1234A".isalnum()
True
>>> "1234A".isdigit()
False

In the first case, there are two addresses, so isalnum returns false because of the space

>>> " ".isalnum()
False

In the secondd case, isalnum() returns true since all the entries are alphanumeric.

The final case, isdigit() returns false, because of the letter A

Now if you have need to know if there are more than one address, you simply parse the text entry on whatever was used to separate them.  This could be as simple as a space or and & or a combinations.

Though the addendum was important

RobBlash
Regular Contributor

Not sure what happened to the missing post but I did see all of the text via email notifications. Thanks Dan Patterson​ and Freddie Gibson​ for explaining the functions and finding a solution to my problem.

This part by Freddie covered the initial problem. After some more thinking over the weekend I had a small suspicion that this might be the case (not returning int because the data is stored as a string). Thanks for confirming.

Looking at your screenshot I'd assume your LeftPart field is a Text field because it allows you to store values other than numbers and decimals. As a result, even if the value in the field were '1234' the type would always return string because the values are stored as strings and not a numeric type (e.g. int, float, double).
0 Kudos