Select to view content in your preferred language

Why is my if/elif/else statement failing?

444
5
Jump to solution
02-24-2025 05:30 PM
BarrettLewis1
Occasional Contributor

I have a rudimentary knowledge of python, so it is possible that my understanding correct, but for the life of me I cannot get my if/elif/else statement to work. I will post it here and then explain what it is trying to do, and what it is actually doing:

Expression:

 

LandFcv_Adjusted = AdjustFCV(!PptDesc!,!LandFcv!,!ImpFcv!)

 

Code Block:

 

def AdjustFCV(PropType,Land,Imp):
    homestead = ("500","501","502")
    if Land == "NULL" or Imp == "NULL":
        return 0
    elif PropType == "Vacant Land" and Imp in homestead and Land not in homestead:
        return Land
    elif Land in homestead or Imp in homestead:
        return 0
    else:
        return Land

 

Basically what this code is supposed to do is that it is running through parcel data, and the order is this:

  • If either the land value or improvement value is null, then the field (land adjusted) is given 0.
  • Then, if Imp is in one of the 500 codes, but land is not AND the property type is vacant, the land value should be returned.
  • Then, for the remaining land that was not coded above, if either Land or Imp is in a 500 code, the adjusted land value should be 0.
  • Finally, anything that did not fall under the conditions above has its original land value returned.

Except what happens is that the second elif statement which completely overrides the first elif statement. So under the first elif statement, where a parcel may have had its original land value returned because it is a vacant land, the land value is not in a 500 code, but the improvement value is a 500 code, the second elif statement seems to start the condition over again and completely ignores that elif statement, so then I am left with a parcel that has a 0 value returned even though it meets the first elif condition. 

If I remove the second elif statement, the first elif statement runs as it should. If I make all elifs into if statements, it runs like it should. If I try a nested if statement like below (this is what ChatGPT recommended) it runs as it should:

 

    if Land == "NULL" or Imp == "NULL":
        return 0
    if Imp in homestead:
        if PropType == "Vacant Land" and Land not in homestead:
            return Land
        else:
            return 0
    else:
        return Land

 

but if I change that second if statement to an elif instead of an if, it again returns a 0 where the vacant land condition is actually true.

Like I said, I have a rudimentary knowledge of python, but my understanding is that an elif section is supposed to move and ignore any previous record that was affected by an earlier condition statement. Instead, elif is ignoring all previous condition statements. Am I wrong in my understanding? What am I not getting?

Tags (3)
0 Kudos
1 Solution

Accepted Solutions
BarrettLewis1
Occasional Contributor

I finally figured it out. he string that contains "Vacant Land" had a bunch of hidden spaces to its right, so it wasn't being completely grabbed the first elif statement. Once I removed those spaces with .rstrip(), the condition fully triggered and was not overridden by the second elif.

View solution in original post

5 Replies
BarrettLewis1
Occasional Contributor

The land and improvement values are strings by the way. The data came like that.

0 Kudos
BarrettLewis1
Occasional Contributor

Now I'm really stumped. Here I tried a very simple if/elif/else and it worked. I simply converted all and values into integers in the the LandFcv_Adjusted field. Then I used a new field to do this:

Expression:

reclass(!LandFcv_Adjusted!)

Code:

def reclass(Land):
    if Land < 1000:
        return 1
    elif Land < 50000:
        return 2
    elif Land < 10000:
        return 3
    elif Land < 500000:
        return 4
    else:
        return 5

 

This time it worked as I would expect. The order of the integers returned matches what they should have been if each elif statement was continuing on from the previous one, ignoring those records which had already been given an integer by a previous condition statement. What am I not getting about the code I posted then?

 

0 Kudos
DavidSolari
MVP Regular Contributor

Without access to some data I can't say for sure what's going on here. That said, using early returns with else/if chains is an odd coding pattern, you usually either do early return like this:

def AdjustFCV(PropType,Land,Imp):
    homestead = ("500","501","502")
    if Land == "NULL" or Imp == "NULL":
        return 0
    if PropType == "Vacant Land" and Imp in homestead and Land not in homestead:
        return Land
    if Land in homestead or Imp in homestead:
        return 0
    return Land

Or use a return value like this:

def AdjustFCV(PropType,Land,Imp):
    homestead = ("500","501","502")
    retval = Land
    if Land == "NULL" or Imp == "NULL":
        retval = 0
    elif PropType == "Vacant Land" and Imp in homestead and Land not in homestead:
        retval = Land
    elif Land in homestead or Imp in homestead:
        retval = 0
    return retval

I know this doesn't answer why the code isn't behaving right but you should have another working code block at the very least.

One last thing: does your data store null values as the string value "NULL"? If not, you'll want to compare your data to the None object, otherwise you won't catch those nulls. Here's that one line adjusted to check for nulls:

if Land is None or Imp is None:

 

0 Kudos
BarrettLewis1
Occasional Contributor

Thanks for the response. That second code block doesn't work either. And the fields aren't actually Null values, they are literally strings that say NULL. Its a pretty ridiculous dataset.

BarrettLewis1
Occasional Contributor

I finally figured it out. he string that contains "Vacant Land" had a bunch of hidden spaces to its right, so it wasn't being completely grabbed the first elif statement. Once I removed those spaces with .rstrip(), the condition fully triggered and was not overridden by the second elif.