1

I want to perform a simple calculation with the Field Calculator using this piece of script (note that all the elif statements are attempts for another syntax and non of the worked):

def change(OldFor_Com):
    if (OldFor_Com) == "OHWH":
        return shape.area@Hectares / 40
    elif (OldFor_Com) == "OHWH":
        return !shape.area@Hectares / 30!
    elif (OldFor_Com) == "OHWH":
        return (!shape.area@Hectares / 30!)
    elif (OldFor_Com) == "OHWH":
        return !shape.area@Hectares! / 30
    elif (OldFor_Com) == "OHWH":
        return (!shape.area@Hectares! / 30)
    if (OldFor_Com == "OTHH"):
        return !shape.area@hectares! / 40

If the field is populated with OTHH I want another field to be populated with the area of the field, divided by 40, or 30, or... and so on. I modified my syntax a couple of times (as you can see) but it still says Invalid Syntax.

Is a calculation possible with these if statement or do I need a workaround?

Note that the shape.area@Hectares is an expression to calculate the area of the field, and not another field in my attributetable!

screen1

screen2

screen3

screen3

EDIT: 7/15/2014 around 11pm

I modified the script. I added a field to the table and calculate the area of the shape first (with !shape.area@Hectares!) and then I try to run this

def change(OldFor_Com):
    if OldFor_Com == "OTHH":
        return Area_Ha / 40
    if OldFor_Com == "OHWH":
        return Area_Ha / 30
    if OldFor_Com == "OSFH":
        return Area_Ha / 375
    if OldFor_Com == "PINE":
        return Area_Ha / 10
    if OldFor_Com == "OOFH":
        return Area_Ha / 375
    if OldFor_Com == "None":
        return Area_Ha
    else:
        return 0

It bounces back with the following:

ERROR 000539: Error running expression: change(u"OTHH", 7) 
Traceback (most recent call last):
File "<expression>", line 1, in <module>
TypeError: change() takes exactly 1 argument (2 given)

Failed to execute (Calculate Field (10)).

Is it not possible to do any calculations in the if statement?

EDIT: 7/15/14 12:30pm

This how the attributestable looks like before I add the field SizeScore

before

After I add the field SizeScore (FLOAT).

after

And the following screen comes up if I use this code:

def change(OldFor_Com, Area_Ha):
    if OldFor_Com == "OTHH":
        x = Area_Ha / 40
        return x
    if OldFor_Com == "OHWH":
        x =  Area_Ha / 30
        return x
    if OldFor_Com == "OOFH":
        x = Area_Ha / 375
        return x
    if OldFor_Com == "OSFH":
        x = Area_Ha / 375
        return x
    if OldFor_Com == "PINE":
        x =  Area_Ha / 10
        return x
    if OldFor_Com == "None":
        return Area_Ha
    else:
        return 0

screen

It only populates the rows where it does not need to calculate. The only statement that is working is that one.

if OldFor_Com == "None":
     return Area_Ha

But for the others are no error messages coming back!

SOLVED, SEE ACCEPTED ANSWERE Thanks a lot to everybody who went through this with me!

10
  • I don't believe you can mix/match 4 and 2 spaces. Stick with one or the other.
    – Paul
    Jul 14, 2014 at 20:12
  • If I add four spaces (not six) to the third line it says intendent error. If I add six or eight it says error in the syntax. I did this intendation (four and six) in other calculations before and it worked fine.
    – four-eyes
    Jul 14, 2014 at 20:13
  • Try multiples of 2 or multiples of 4. First indent block is 2, then 4, then 6, etc. OR it should be 4 -> 8 -> 12 -> etc. See here, first bullet point under Note.
    – Paul
    Jul 14, 2014 at 20:18
  • @ Paul thanks for the link. I will keep this in mind. There is still a mistake in the Syntax though.
    – four-eyes
    Jul 14, 2014 at 20:21
  • What's in your parser? And what is the field type? Is it a shapefile, SDE? etc.
    – GISHuman
    Jul 14, 2014 at 20:24

4 Answers 4

2

You need to send your area field into your calculation as a parameter.

Expression: change(!OldFor_Com!, !shape.area@hectares!)

Code Block:

def change(OldFor_Com, area):
    if OldFor_Com == "OTHH":
        return area / 40
    elif OldFor_Com == "OHWH":
        return area / 30
7
  • The setting of the ! I tried in my third elif statement. Does not work.
    – four-eyes
    Jul 14, 2014 at 20:08
  • Is the invalid syntax being reported before the third line? If so, the calculation never gets there to attempt that syntax.
    – evv_gis
    Jul 14, 2014 at 20:08
  • Edit my question. With this syntax I added to the post the error is in the third line.
    – four-eyes
    Jul 14, 2014 at 20:10
  • I updated the indentation, looks like I was off by one.
    – evv_gis
    Jul 14, 2014 at 20:17
  • The intendation is fine. I get a different error message if the intendation is wrong. It is still the syntax
    – four-eyes
    Jul 14, 2014 at 20:19
1

After your newest updates to the question, this should work:

def change(OldFor_Com, Area_Ha):
    if OldFor_Com == "OTHH":
        return Area_Ha / 40.0
    elif OldFor_Com == "OHWH":
        return Area_Ha / 30.0
    elif OldFor_Com == "OOFH":
        return Area_Ha / 375.0
    elif OldFor_Com == "OSFH":
        return Area_Ha / 375.0
    elif OldFor_Com == "PINE":
        return Area_Ha / 10.0
    elif OldFor_Com == "None":
        return Area_Ha
    else:
        return 0

The reason you were seeing all 0s (except for the "None" case) was not that the function wasn't working, but rather that you were dividing integers by integers. The results were always less than 1, and Python always rounds down for integer math. Adding .0 to each of the denominators forces decimal math, and the results will be decimals.

(Alternatively -- and this is probably better -- is to make the "Area_Ha" field a float/double instead of an integer. Then your function would work exactly as you've written it.)

3
  • Awesome dude. Thats working now! Thanks a lot for the explanation! Now I am a little bit more pythionic again :) Till he next problem which is probably just waiting around the corner. Could you explain why I need the variable x though?
    – four-eyes
    Jul 15, 2014 at 17:05
  • You don't, I added that in there to see what was going on in the original cod. it should work if you take out the x and just use return area / 10.0
    – GISHuman
    Jul 15, 2014 at 17:09
  • Yeah, you don't need an intermediate variable. I cleaned up the code in the answer and added the elifs back in to make the code more efficient.
    – nmpeterson
    Jul 15, 2014 at 17:12
1

Your exclamation marks need to be wrapped around the field name:

def change(OldFor_Com):
    if OldFor_Com == "OTHH":
       return !shape.area@Hectares! / 40
    elif OldFor_Com == "OHWH":
       return !shape.area@Hectares! / 30

Also, make sure Python is the defined Parser.

9
  • Thats what I tried in my third elif statement. Does not work. Python is defined as parser.
    – four-eyes
    Jul 14, 2014 at 20:07
  • Updated, removed some unnecessary parentheses.
    – artwork21
    Jul 14, 2014 at 20:09
  • @artwork21 you only need one if statement for "OHWH" as well. I think OP was just testing multiple formattings to see if it would work.
    – GISHuman
    Jul 14, 2014 at 20:11
  • Yep GISKid, that what I did
    – four-eyes
    Jul 14, 2014 at 20:11
  • 2
    In the python code block the !shape.area! is out of scope this is a very common misconception. See this page resources.arcgis.com/en/help/main/10.2/index.html#//… for explanation. The exclamation marks go in the expression not the code block. the answer by @ew_gis is correct except the expression should be change(OldFor_Com!, !shape.area@Hectares!) Jul 14, 2014 at 22:15
0

Going off of your latest edit and ew_GIS try this:

Expression: change(!OldFor_Com!, !Area_Ha!)

Code Block:

def change(OldFor_Com, area):
  if OldFor_Com == "OTHH":
     return area / 40
  elif OldFor_Com == "OHWH":
     return area / 30
  elif OldFor_Com in ("OOFH", "OSFH", "OOFH"):
    return area / 375
  elif OldFor_Com == "PINE":
    return  area / 10
  elif OldFor_Com == "None":
    return area
  else:
    return 0  
7
  • Thanks for your effort. I edited my post! The OR statement does not work, Field Calculator does not like the syntax so I made it an extra elif argument.
    – four-eyes
    Jul 15, 2014 at 15:30
  • Strange, could you try running it as a stand-alone script instead of in the field calculator? I'm out of touch with ArcGIS 9.3. It's been some time.
    – GISHuman
    Jul 15, 2014 at 15:35
  • It should work in the Field Calculator shouldnt it? I could try running it as a standalone script but it needs to be included in the modelbuilder. Its ArcGis 10.2 I am working with
    – four-eyes
    Jul 15, 2014 at 15:39
  • OR does not work because it should be or. Alternatively, use elif OldFor_Com in ("OSFH", "OOFH"):
    – Paul
    Jul 15, 2014 at 16:07
  • Thanks Paul! I'm still a rookie @Stophface See my edit, I just tested it and it worked.
    – GISHuman
    Jul 15, 2014 at 16:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.