Can't seem to figure out what is wrong with this create fields from a calculation. The code creates the new field in the shapefile as selected by the user but I keep getting a 9999 error on every attempt I have to go further. I am rather new to Python and ArcPy, if anyone has any suggestions they would be greatly appreciated. The code is to work as a tool from an exported route from a network analysis and provide a fuel cost which changes slightly in relation to the speed limit of the road. Thanks.
import arcpy
from arcpy import env
import os
inputFC = arcpy.GetParameterAsText(0) # Input feature class
distanceField = arcpy.GetParameterAsText(1) # Name of distance field in input fc
speedField = arcpy.GetParameterAsText(2) # Name of speed field in input feature class
price = float(arcpy.GetParameterAsText(3)) # Input the current price of gas in $/Liter
mpg = float(arcpy.GetParameterAsText(4)) # Input vehicle mpg in MPG
arcpy.AddField_management(inputFC, 'Cost', 'DOUBLE') #create cost field
rows = arcpy.SearchCursor(inputFC)
#row = rows.NextRow()
#arcpy.AddMessage(row.GetValue(distanceField))
for row in rows:
arcpy.AddMessage(row.length_12)
distance = row.getValue(distanceField)
arcpy.AddMessage(distance)
lperkm = row.getValue(mpg)
milageupdate = lperkm * 2.35214 #convert mpg to liters per kilometer
if speedField <= 30:
cost =(price * 0.07 * distance)/ milageupdate -(milageupdate * (0.07))
elif speedField >30 and speedField <50:
cost =(price * distance)/ milageupdate -(milageupdate * (0.03))
elif speedField >50 and speedField <90:
cost =(price * distance)/ milageupdate
row.setValue('Cost', cost)
rows.updateRow(row)
del row, rows
4 Answers 4
As a starting point, your search cursor should be an update cursor if you are attempting to update the values of anything. Here's some information on the various cursors available to you in ArcPy: http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//002z0000001q000000
rows = arcpy.UpdateCursor(inputFC)
-
AHight, PolyGeo Thanks a lot for the quick answers, really appreciate the help.Haywood– Haywood2012年07月26日 00:27:40 +00:00Commented Jul 26, 2012 at 0:27
-
If by chance you have have 10.1 you should try the new cursors in the data access module. They are significantly faster. resources.arcgis.com/en/help/main/10.1/index.html#/UpdateCursor/…TurboGus– TurboGus2012年07月27日 15:00:56 +00:00Commented Jul 27, 2012 at 15:00
From what I can tell the variable speedField is set to a field name (i.e. text string) and then tested to see whether it is less than a number (30).
Try changing
if speedField <= 30:
cost =(price * 0.07 * distance)/ milageupdate -(milageupdate * (0.07))
elif speedField >30 and speedField <50:
cost =(price * distance)/ milageupdate -(milageupdate * (0.03))
elif speedField >50 and speedField <90:
cost =(price * distance)/ milageupdate
to
if row.getValue(speedField) <= 30:
cost =(price * 0.07 * distance)/ milageupdate -(milageupdate * (0.07))
elif 30 < row.getValue(speedField) <50:
cost =(price * distance)/ milageupdate -(milageupdate * (0.03))
elif 50 < row.getValue(speedField) <90:
cost =(price * distance)/ milageupdate
and, as @AHigh says, you will need an UpdateCursor rather than a SearchCursor
You should also double check whether the upper ranges should all be "less than" or "less than or equal to". You use the latter for 30 but the former for 50 and 90.
A trick to success that I have found is use the shell to test bits and pieces of your code and then integrate it back into the total package this way you can check the output. Incremental development is a good way to isolate errors quickly rather than having to sort through the whole code. Another useful free Python reference is How to Think Like a Computer Scientist: http://www.openbookproject.net/thinkcs/python/english2e/
-
+1 That's a good strategy and good advice, thanks. Welcome to our site!whuber– whuber2012年07月27日 13:51:21 +00:00Commented Jul 27, 2012 at 13:51
Are arcpy.AddMessage(row.length_12)
and arcpy.AddMessage(distance)
coming through fine? If not, try casting the parameters to strings, e.g. arcpy.AddMessage(str(row.length_12))
.
In lperkm = row.getValue(mpg)
you're passing a float
data type to row.getValue(field_name)
which is expecting a str
. Maybe you meant lperkm = row.getValue('mpg')
. PolyGeo and AHigh are right as well, so fix those issues too.
9999
generally means that a function inside arcpy
has failed (otherwise you'll get a TypeError
, IOError
or something else along those lines). Not very useful, I know, but at least you know you have to look for the error in the function parameters (and by the way, make sure you're using the right functions while you're at it as well).
If you're new to python but haven't done so already, check out the tutorial in the python docs.
-
Thank you for the feedback. After changing the UpdateCurser The row length messages are coming through alright, that is the last thing I get. I have determined that the error is on the line: lperkm = row.getValue(mpg) I've converted the float to a string with the same function parameter error in the result mpgx = str(mpg) lperkm = row.getValue(mpgx) I'll check out tutorials as recommended.Haywood– Haywood2012年07月26日 18:27:52 +00:00Commented Jul 26, 2012 at 18:27
-
What are you trying to do with that line? Do you have a field named
mpg
in your table whose value for this row you're trying to find out? If so, you want to replacelperkm = row.getValue(mpg)
withlperkm = row.getValue('mpg')
(verbatim).alcedine– alcedine2012年07月26日 18:49:26 +00:00Commented Jul 26, 2012 at 18:49 -
There is no mpg row in the table, the mpg is a user input that is to be used as a parameter. After the mpg is converted to liters per km it is used as one of the inputs to calculate the "cost" field.Haywood– Haywood2012年07月26日 19:59:06 +00:00Commented Jul 26, 2012 at 19:59
-
Okay, I think I see what you're trying to do now. There are many strange things going on in your script, though, and I suggest taking the time to think through it again. Remove the row
lperkm = row.getValue(mpg)
entirely, then change the next row tolperkm = mpg * 2.35214
. Then rewrite the math bit usinglperkm
(PolyGeo gave you the right if conditions, but the formula is wrong). Work it out on paper if you have to.alcedine– alcedine2012年07月26日 20:25:45 +00:00Commented Jul 26, 2012 at 20:25 -
Thanks Phillip, script is working. Learned a lot and I'm quite thrilled. As you suggested it was a couple pieces of messy syntax and a lot of bad math. Will be more careful in the future.Haywood– Haywood2012年07月27日 01:43:35 +00:00Commented Jul 27, 2012 at 1:43