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!

  • I don't believe you can mix/match 4 and 2 spaces. Stick with one or the other. – Paul Jul 14 '14 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. – Stophface Jul 14 '14 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 '14 at 20:18
  • @ Paul thanks for the link. I will keep this in mind. There is still a mistake in the Syntax though. – Stophface Jul 14 '14 at 20:21
  • What's in your parser? And what is the field type? Is it a shapefile, SDE? etc. – GISKid Jul 14 '14 at 20:24
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.)

  • 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? – Stophface Jul 15 '14 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 – GISKid Jul 15 '14 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 '14 at 17:12
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
  • The setting of the ! I tried in my third elif statement. Does not work. – Stophface Jul 14 '14 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 '14 at 20:08
  • Edit my question. With this syntax I added to the post the error is in the third line. – Stophface Jul 14 '14 at 20:10
  • I updated the indentation, looks like I was off by one. – evv_gis Jul 14 '14 at 20:17
  • The intendation is fine. I get a different error message if the intendation is wrong. It is still the syntax – Stophface Jul 14 '14 at 20:19
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.

  • Thats what I tried in my third elif statement. Does not work. Python is defined as parser. – Stophface Jul 14 '14 at 20:07
  • Updated, removed some unnecessary parentheses. – artwork21 Jul 14 '14 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. – GISKid Jul 14 '14 at 20:11
  • Yep GISKid, that what I did – Stophface Jul 14 '14 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!) – Michael Stimson Jul 14 '14 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  
  • 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. – Stophface Jul 15 '14 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. – GISKid Jul 15 '14 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 – Stophface Jul 15 '14 at 15:39
  • OR does not work because it should be or. Alternatively, use elif OldFor_Com in ("OSFH", "OOFH"): – Paul Jul 15 '14 at 16:07
  • Thanks Paul! I'm still a rookie @Stophface See my edit, I just tested it and it worked. – GISKid Jul 15 '14 at 16:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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