Field calculation, concatenation

1430
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
ChrisSnyder
Regular Contributor III
There would be a difference if the "unit" field was Null or simply a blank string of ''.

Your code should work as is when unit is a Null, however, a blank string of '' is considered a valid value.

Something like this should take care of both cases:

def fulladdress(num, prefix, street, sttype, suffix, unit):
    if unit not in [None, '']:
        fulladd = num +' '+ prefix+' '+street+' '+sttype+' '+suffix+' #'+unit
    else:
        fulladd = num +' '+ prefix+' '+street+' '+sttype+' '+suffix
    fulladd = fulladd.strip()
    fulladd = fulladd.replace('  ',' ')
    return fulladd


A tip for you: It is much easier to deal with and format complex conditional expresions in an UpdateCursor than in the "code block" of the CalculateField tool.
0 Kudos
CFrate
by
Occasional Contributor
Thanks, Chris, but it didn't yield a different result. The results still end in '#' even when there's no unit present.

My reason for going about it in the calculator is that I'm saving it as a .cal file so that my end-users can just load the expression when they need to calculate. It's the easiest option I could think of, since they're familiar enough with the field calculator.

Just so we're clear on the desired results,
Given these values:
num= 101
prefix= N
street=Main
sttype=St
suffix=''
unit=1A
The calculation should return "101 N Main St #1A"

But if the Unit value were not present, then it should just be "101 N Main St"
With my expression and the one you provided, the result is instead "101 N Main St #"

Thanks!
0 Kudos
ChrisSnyder
Regular Contributor III
In your database, what is the field value when there is "no unit field value"?

Is it Null, '', ' ', or ?
0 Kudos
CFrate
by
Occasional Contributor
In your database, what is the field value when there is "no unit field value"?

Is it Null, '', ' ', or ?


In such a case, it's blank. No space and no nulls (though the field is nullable).
0 Kudos
BruceNielsen
Occasional Contributor III
what if you try
if len(unit) < 1:
0 Kudos
CFrate
by
Occasional Contributor
what if you try
if len(unit) < 1:


Well, that almost worked. Now I have the opposite problem.
Using len(), the field calculates correctly for records with no value in UNIT, but not those with a value in UNIT.
0 Kudos
BruceBacia
Occasional Contributor
Here's to trying a different approach:

def fulladd(num, prefix, street, sttype, suffix, unit):
    fulladd = (num + ' ' + prefix).strip()
    fulladd = (fulladd + ' ' + street).strip()
    fulladd = (fulladd + ' ' + sttype).strip()
    fulladd = (fulladd + ' ' + suffix).strip()
    if unit.strip() not in ['None','',' ']:
        fulladd = fulladd + ' #' + unit
    return fulladd
0 Kudos
BruceBacia
Occasional Contributor
This version should work for you.  It will take care of unwanted leading or trailing spaces

def fulladd(num, prefix, street, sttype, suffix, unit):
    fulladd = ''
    for add in [num,prefix,street,sttype,suffix]:
        fulladd = ''.join([fulladd,' ',add.strip()]).strip()
    if unit.strip() not in ['None','']:
        fulladd = ''.join([fulladd,' #',unit.strip()])
    return fulladd
0 Kudos
BruceBacia
Occasional Contributor
Here's an even shorter, quicker version.  You might want to test this one a little before implementing.  I did test it, but not as extensively as the previous one.   

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