2

I am trying to use the python field calculator in ArcMap to do a simple calculation, where:

  • there are two input variables, the numerator and the denominator
  • if the numerator is zero a zero is returned
  • else, the numerator is divided by the denominator and multiplied by 100

The code I tried:

def getScore(num, den):
    if num == 0:
        return 0
    else:
        return (num/den) * 100

when I run the script i get no errors yet the 'else' statement is not getting returned.

there will be no zeros in the denominator, so div/0 will not be an issue. The input fields are all 'long' integers and the target field is a 'double.'

I've attached a couple of images showing a test in python where the same exact code works perfectly, as well as the the field calculator where it does not work.

enter image description here enter image description here

Erica
  • 2,399
  • 5
  • 26
  • 34
Andrew K
  • 23
  • 5
  • Isn't this just what you want? If you do it step by step: `healthy = 1` `total = 10` Of course `healthy` is not `0`, so it returns: `return (healthy / total) * 100` Which is equal to `return (1 / 10) * 100` Which then is equal to: `return (0.1) * 100` Which is `10`, just as you get it in the screenshot. – dv02 May 17 '17 at 15:49

2 Answers2

0

Isn't this just what you want? If you do it step by step:

healthy = 1
total = 10

Of course healthy is not 0, so it goes in the else block:

return (healthy / total) * 100

Which is equal to

return (1 / 10) * 100

Which then is equal to:

return (0.1) * 100

Which is 10, just as you get it in the screenshot.

dv02
  • 333
  • 1
  • 6
  • 17
  • 1
    Yes, it works in python (in the command console), I included the image of the command console to show that the code is correct, but my question is why it does not work in ArcMap. It does NOT work in the ArcMap Field Calculator using python. – Andrew K May 17 '17 at 16:12
  • Okay then I'm sorry, it has to have to do something with ArcMap... Can't help you :( – dv02 May 17 '17 at 16:53
0

The way ArcGIS Desktop divides integers will result in an integer, so percentages will always end up as zero (e.g. 1 / 10 = 0) -- annoying, and counterintuitive, but that's what it's doing.

ArcGIS Pro uses Python 3 and in ArcGIS Desktop, it uses Python 2. Python 2 uses integer math, meaning that dividing two integer values will always produce an integer value (3 / 2 = 1). In Python 3, dividing two integer values will produce a float (3 / 2 = 1.5).

You can instead explicitly cast the variables as float, which will then do float division and give you a float result (1 / 10 = 0.1). The following works for me:

def getScore(num, den):
    if num == 0:
        return 0
    else:
        return (float(num)/float(den)) * 100

One observation: your conditional is basically saying "if the numerator is zero, don't bother dividing, just return zero" -- however, that's what 0 divided by anything is going to be anyway. You can skip the conditional, and the entire codeblock, and just directly calculate -- but still remember to cast the values as float first, or you'll still get a bunch of zeros :)

float(!Healthy!) / float(!Total!)
Erica
  • 2,399
  • 5
  • 26
  • 34
  • thank you so much! I am actually going to expand the equation to be a little more complex, that's why I posted the conditional rather than the simple division. – Andrew K May 20 '17 at 15:58