'IF' Python Script Tool

2167
16
09-08-2010 09:37 AM
Corey_C_Denninger
New Contributor
I need to mimic an Excel formula as an ArcGIS script tool (I will run many times on similar fields).  It includes the following:
-1 feature class:   'gp.GetParameterAsText(0)'
-3 input fields:   (Z, AF, T)   'gp.GetParameterAsText(1), (2), & (3)'
-1 output field:   'gp.GetParameterAsText(4)'

In Excel, the formula looks like this:
=IF(AND(Z>0,AF>0),SUM(T+Z+AF),IF(AND(Z>0,AF<0),SUM(T+Z),IF(AND(Z<0,AF>0),SUM(T+AF),T)))

In plain words, it is saying:
If the first condition is met, sum these 3 fields together and populate output field
If the second condition is met, sum these 2 fields together and populate output field
If the third condition is met, sum these 2 fields together and populate output field
If none are met, populate output field with field 'T' value.


I am somewhat familiar with Python, but I am struggling with this one.  Any help is appreciated.  Thank you.
0 Kudos
16 Replies
DanPatterson_Retired
MVP Emeritus
Logan I think you have nailed it...one of the problems in not seeing a whole script. 
Since the parameters are field names, then obviously you have to get the value from the field as indicated in the example scripts
http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//002z0000001q000000.htm
which means that the T, Z and AF need to be defined as "getValue" lines right after the while statement
0 Kudos
Corey_C_Denninger
New Contributor
Hey Dan - Yea, sorry about that.  I assumed the error would be in my revised script and not related to my version, etc.  Seems like a string vs. text issue (perhaps), but all field types in the layer are correct (double).  Thank you for your efforts.

ArcGIS 9.3.1
Python 2.5

ERROR:
<type 'exceptions.RuntimeError'>: ERROR 999999: Error executing function.
The value type is incompatible with the field type. [TOTFUNC_09]
Failed to execute (PopTool)


As far as not seeing the whole script, all I have so far for a script is what I pasted in my previous posts.  If you look at my original (1st) post, it should help clairify my goals.  Essentially the final script tool should compare 3 fields in each row of a feature class table and place a value in the output field based on those conditions placed within the script.  Z, AF, T, are essentially numeric (double) fields to be compared to each other.
0 Kudos
Corey_C_Denninger
New Contributor
Revised script.  Still errors, but from the advice posted, it seems a bit closer.
import sys, string, os, math, arcgisscripting
gp = arcgisscripting.create(9.3)
gp.OverWriteOutput = 1


FC = gp.GetParameterAsText(0)
Z = gp.GetParameterAsText(1)
AF = gp.GetParameterAsText(2)
T = gp.GetParameterAsText(3)
Outfield = gp.GetParameterAsText(4)

cur = gp.UpdateCursor(FC)
row = cur.Next()


while row:
      if row.GetValue == (Z > 0) and (AF > 0):
            row.SetValue(Outfield, T + Z + AF)  #or = sum( [T, Z, AF] )
      elif row.GetValue == (Z > 0) and (AF < 0):
            row.SetValue(Outfield, T + Z)         #or = sum( [T, Z ] )
      elif row.GetValue == (Z < 0) and (AF > 0):
            row.SetValue(Outfield, T + AF)        #or = sum( [T, AF] )
      else:
            row.SetValue(Outfield, T)
            
      cur.UpdateRow(row)
      row = cur.Next()
del cur


ERROR:  <type 'exceptions.RuntimeError'>: ERROR 999999: Error executing function.
The value type is incompatible with the field type. [TOTFUNC_09]
Failed to execute (PopTool).
0 Kudos
LoganPugh
Occasional Contributor III
Try the following code. I changed the names of the variables you're using to read in the parameters, from what I understand these are the field names, not the field values.

Also when you use GetValue() you have to specify which field you're getting the value from. And since we want to read in all three values for each row I put three GetValue statements at the top of the while loop, storing each in a variable (T, Z, and AF).

Finally, as I mentioned before I used a variable named "val" to store the results of the calculation before using it in SetValue. Some ESRI commands don't like in-line expression evaluation for some reason -- may not be the case here but it's better programming/debugging practice to do it this way anyways.

import sys, string, os, math, arcgisscripting
gp = arcgisscripting.create(9.3)
gp.OverWriteOutput = 1


FC = gp.GetParameterAsText(0)
Z_fld = gp.GetParameterAsText(1)
AF_fld = gp.GetParameterAsText(2)
T_fld = gp.GetParameterAsText(3)
Outfield = gp.GetParameterAsText(4)

cur = gp.UpdateCursor(FC)
row = cur.Next()


while row:
    Z = row.GetValue(Z_fld)
    AF = row.GetValue(AF_fld)
    T = row.GetValue(T_fld)
    if (Z > 0) and (AF > 0):
        val = T + Z + AF    #or = sum( [T, Z, AF] )
    elif (Z > 0) and (AF < 0):
        val = T + Z         #or = sum( [T, Z ] )
    elif (Z < 0) and (AF > 0):
        val = T + AF        #or = sum( [T, AF] )
    else:
        val = T
    row.SetValue(Outfield, val)
    cur.UpdateRow(row)
    row = cur.Next()
del row
del cur
0 Kudos
Corey_C_Denninger
New Contributor
Logan - So far so good.  I have been testing on a small sample and it is good so far.  Thanks for all the assistance.  I realized after I posted my previous, that the GetValue needed an object in the ().  I see how you used 'val' and it makes sense and runs pretty quickly.  I really do appreciate the help. 

So no way to 'credit' posts or award points anymore?  Mark as answered or complete?
0 Kudos
LoganPugh
Occasional Contributor III
Logan - So far so good.  I have been testing on a small sample and it is good so far.  Thanks for all the assistance.  I realized after I posted my previous, that the GetValue needed an object in the ().  I see how you used 'val' and it makes sense and runs pretty quickly.  I really do appreciate the help. 

So no way to 'credit' posts or award points anymore?  Mark as answered or complete?


Good to hear it works! And yeah, I think they omitted the "mark as answered" stuff when they launched the new forums. No biggie. I like the way StackOverflow/Stack Exchange does it better anyway. Check out http://gis.stackexchange.com/
0 Kudos
IbraheemKhan1
New Contributor III
Hi Logan and Dan,

I have found this post very helpful to get IF statements work in python script. Tried to use almost similar approach as used in the thread but each time computation fails. Unable to write files in the same loop. Any help would be deeply appreciative to fix my code below:

try:
for k in range(0,11):
     for l in range(0,11):
         str_fin="oc_lyr"+str(l+1)
             if (t(l)<=nt(k)) and (b(l)>=nb(k)):
                val = oc_lyr(l)*(nb(k)-nt(k))
             elif (t(l)<=nt(k)) and (b(l)>nt(k)):
                val = oc_lyr(l)*(b(l)-nt(k))
             elif (t(l)>nt(k)) and (b(l)<nb(k)):
                val = oc_lyr(l)*(b(l)-t(l))
             elif (t(l)<nb(k)) and (b(l)>=nb(k)):
                val = oc_lyr(l)*(nb(k)-t(l))

except:
print "failed"
0 Kudos