Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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
share|improve this question
add comment

4 Answers

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/

share|improve this answer
    
+1 That's a good strategy and good advice, thanks. Welcome to our site! –  whuber Jul 27 '12 at 13:51
add comment

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.

share|improve this answer
    
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 Jul 26 '12 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 replace lperkm = row.getValue(mpg) with lperkm = row.getValue('mpg') (verbatim). –  Philip Amy Wright Jul 26 '12 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 Jul 26 '12 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 to lperkm = mpg * 2.35214. Then rewrite the math bit using lperkm (PolyGeo gave you the right if conditions, but the formula is wrong). Work it out on paper if you have to. –  Philip Amy Wright Jul 26 '12 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 Jul 27 '12 at 1:43
add comment

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.

share|improve this answer
add comment

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)
share|improve this answer
    
AHight, PolyGeo Thanks a lot for the quick answers, really appreciate the help. –  Haywood Jul 26 '12 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 Jul 27 '12 at 15:00
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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