Field Calculator Inserts a "u" In My Function

799
6
Jump to solution
06-05-2014 07:01 AM
RussellTaylor
New Contributor
Sometimes when I'm using a Codeblock in Field Calculator, I get an ERROR 000539 which shows something like this:

function_name(u"fieldvalue")

However, that "u" isn't in the Codeblock OR the regular Field Calculator box. Where is it coming from?
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
markdenil
Occasional Contributor III
Yes, it was pretty clear about using a codeblock,
and that python cannot understand how to use the input argument.

It is not helpful to 'generalize' the inputs, or to not bother with being explicit
about the function code or the field values being fed to it.

It is still not clear what the problem might be:
I assume "CARV-000001-000001-B000000" is a value in the field PIN for a particular row...
(if it is not, well, that could be a problem too)

Obviously the function is not expecting that particular string: why?
we don't know; we don't know what the function is trying to do
(beyond that it will try to "format" it).
One does not have a lot to go on here...

Except that, as I wrote before, the prefixed u is not (at least in itself) the problem.

View solution in original post

0 Kudos
6 Replies
markdenil
Occasional Contributor III
The u is a flag that identifies the string as unicode.  it's a python thing.

an ERROR 000539 is a generic Arc code for a python error.
perhaps that function will not accept a string (to wit: "fieldvalue") as an input.

at a guess, fieldvalue looks like you expect it to be a variable, but it is being passed as a string of the variable name
0 Kudos
RussellTaylor
New Contributor
To be a bit clearer, I'm formatting string attributes using a function I've defined in the Codeblock. It has 1 argument, the input field, and outputs to a different field.

I run fix(!PIN!) and get back fix(u"CARV-000001-000001-B000000") in the error.

I generalized to functionname and fieldvalue because I've had this same problem several times before, and while I can usually get it to work after playing with it for a while, I'm curious as to why it happens and the best way to avoid/deal with it.
0 Kudos
markdenil
Occasional Contributor III
Yes, it was pretty clear about using a codeblock,
and that python cannot understand how to use the input argument.

It is not helpful to 'generalize' the inputs, or to not bother with being explicit
about the function code or the field values being fed to it.

It is still not clear what the problem might be:
I assume "CARV-000001-000001-B000000" is a value in the field PIN for a particular row...
(if it is not, well, that could be a problem too)

Obviously the function is not expecting that particular string: why?
we don't know; we don't know what the function is trying to do
(beyond that it will try to "format" it).
One does not have a lot to go on here...

Except that, as I wrote before, the prefixed u is not (at least in itself) the problem.
0 Kudos
RussellTaylor
New Contributor
Here's the whole shebang, then:

def fix(oldApn):
    if '-' not in oldApn:
        newApn = ''
    else:
        apnList = oldApn.split('-')
        if len(apnList) == 3:
            newApn = apnList[0].lstrip() + '-' + apnList[1].lstrip + '-' + apnList[2].zfill(2)
        else:
            newApn = apnList[0].lstrip() + '-' + apnList[1].lstrip
    return newApn


It's supposed to make something like "EBRI-000001-000000-000003" into "1-3" or "EBRI-000001-000000-000004-000001" into "1-4-1".

Instead, I get Error 000539: Error running expression: fix(u"EBRI-000001-000000-000003").
0 Kudos
curtvprice
MVP Esteemed Contributor

Here's how I would do it, using lists and list comprehensions...

def fix(oldApn): 

   # find integer pieces in "-" delimited string, skipping zeros

   pieces = [str(int(p)) for p in oldApn.split("-") if p.isdigit()]

   newApn = "-".join([p for p in pieces if p != "0"])

   return newAPn

0 Kudos
markdenil
Occasional Contributor III
neither apnList[0].lstrip() nor apnList[1].lstrip 
(with or without the ())
will strip off the leading zeros. The default is to strip whitespace.

apnList[0].lstrip('0') will strip zeros, as will
str(int(apnList[0]))
but the second option will preserve a single zero, instead of returning a blank string

I don't know what you want the zfill(2) to do... perhaps it is a typo?

Your logic in the length of apnList test is a little odd.
first off, does a length test of 3-or-else cover all (or any of) your possible use cases?
It does not look like it.

then, your parser takes items 0, 1, & 2  (or 0 & 1) from apnList ...
spliting "EBRI-000001-000000-000003" on the '-' gives ['EBRI', '000001', '000000', '000003']
so the length will be 4, and taking 0, 1 & 2 will give you
EBRI-1-
(if you use your lstrip parsing)

nether of your parsing options will turn  "EBRI-000001-000000-000003" into "1-3"

Try debugging your function in IDLE by just passing it some sample strings.....
0 Kudos