Field calculation, concatenation

1398
16
08-24-2012 08:36 AM
CFrate
by
Occasional Contributor
I've hit a wall with a field calculation.
I'm writing a calculation for a full address field formed by the values of several other string fields. This is what I have:

Expression = fulladdress(!AddNum!, !Prefix! , !Street! , !Type! , !Suffix! , !Unit!)

def fulladdress(num, prefix, street, sttype, suffix, unit):

# Concatenate fields
    # for addresses without unit
    if unit:
        fulladd = num +' '+ prefix+' '+street+' '+sttype+' '+suffix+' #'+unit
    # for addresses with unit    
    else:
        fulladd = num +' '+ prefix+' '+street+' '+sttype+' '+suffix

# Remove unwanted spaces
    fulladd = fulladd.strip()
    fulladd = fulladd.replace('  ',' ')
    return fulladd


It works exactly as I expect... except that it ignores the IF statement completely. I've tried several different ways of forming the IF, but none work as expected. My calculated result is always what it should be if there's a value in the unit field.

I think I've missed something very basic...
Tags (2)
0 Kudos
16 Replies
BruceBacia
Occasional Contributor
Ok, I promise this will be the last revision 😄  I tend to obsess about these things sometimes.  Also, you might be able to change the little exclude list from ['#None','','#'] to ['','#']...... I'm not entirely sure of what a null value will return in this context (i.e. 'None' vs. '' vs. ' ').  You should mess around with it.  Cheers to working with structure data!  


def fulladd(num, prefix, street, sttype, suffix, unit):
    add = [num,prefix,street,sttype,suffix,''.join(["#",unit.strip()])]
    fulladd = ''.join([''.join([a.strip()," "]) for a in add if a.strip() not in ['#None','','#']]).strip()
    return fulladd

0 Kudos
CFrate
by
Occasional Contributor
Ok, I promise this will be the last revision 😄  I tend to obsess about these things sometimes.  Also, you might be able to change the little exclude list from ['#None','','#'] to ['','#']...... I'm not entirely sure of what a null value will return in this context (i.e. 'None' vs. '' vs. ' ').  You should mess around with it.  Cheers to working with structure data!  


def fulladd(num, prefix, street, sttype, suffix, unit):
    add = [num,prefix,street,sttype,suffix,''.join(["#",unit.strip()])]
    fulladd = ''.join([''.join([a.strip()," "]) for a in add if a.strip() not in ['#None','','#']]).strip()
    return fulladd



That last one works perfectly on the ones I've tested so far.
Thanks, Bruce!

**EDIT**
Spoke too soon...

Using a set of 4 records, I was testing this and it worked perfectly on records with or without Unit #s. But then I removed the values from UNIT for ones on which I'd already run the expression, and when I attempted to run the expression again, the calculation failed, with only a generic 999999 error.
0 Kudos
CFrate
by
Occasional Contributor
There appears to be some issue related to running a calculation on a field more than once.
I ran the expression once, and it worked. I ran again without changing anything, and got the 999999 error again. Subsequent tests yield the same results.
0 Kudos
BruceBacia
Occasional Contributor
Carlo,

The problem is probably null values.  Apparently you have to pass the field as a string (str(field)) to the function for field calculator to deal with these values.  Also, the field calculator window seems to always want to switch the little radio button at the top from "Python" to "VB", which will make it fail right off the bat.  This happened to me several times when testing. The solution below worked well with test structure data i used.

def fulladd(num,prefix,street,sttype,suffix,unit):
    add = [num,prefix,street,sttype,suffix,''.join(['#',unit])]
    fulladd = ''.join([''.join([a.strip()," "]) for a in add if a.strip() not in ['','#']]).strip()
    return fulladd


 fulladdress(str(!AddNum!), str(!Prefix!) , str(!Street!) , str(!Type!) , str(!Suffix!) , str(!Unit!))
0 Kudos
BruceBacia
Occasional Contributor
Heck, why not make it a one-liner


def fulladd(num,prefix,street,sttype,suffix,unit):
    fulladd = ''.join([''.join([a.strip()," "]) for a in [num,prefix,street,sttype,suffix,''.join(['#',unit])]  if a.strip() not in ['','#']]).strip()
    return fulladd



 fulladdress(str(!AddNum!), str(!Prefix!) , str(!Street!) , str(!Type!) , str(!Suffix!) , str(!Unit!)).
0 Kudos
CFrate
by
Occasional Contributor
Now I get this error:
"A field name was not found or there were unbalanced quotation marks"

The fields are all there and correct, and the syntax is checking out in Python.
And, again, the expression works correctly at first, but after multiple tests on the same features it suddenly stops working. This latest attempt, the calculation ran correctly a few times, and then I tried to calculate another field and got the 999999 error. Then the expression would no longer function and would return 999999 and the above message.
I'm about to scrap this plan and just have this calculation run externally after scheduled post/reconcile tasks run.


Thanks for your help!
0 Kudos
BruceBacia
Occasional Contributor
That's strange, I haven't run into any issues like that. I ran it several times on the same dataset and it worked each time. Field calculator does seem pretty shady in 10. I added one fix below ---- will strip the unit value before joining it with "#" (will take care of any potential leading spaces on the unit value.


def fulladd(num,prefix,street,sttype,suffix,unit):
    fulladd = ''.join([''.join([a.strip()," "]) for a in [num,prefix,street,sttype,suffix,''.join(['#',unit.strip()])]  if a.strip() not in ['','#']]).strip()
    return fulladd
0 Kudos