Select to view content in your preferred language

Defined function not working but code works in an IF statement

1998
5
01-13-2011 06:05 PM
MarkPeacey
Deactivated User
Apologies for the lack of comments and notes in the scripts, they're a copy paste from large one. The attached Scipt_working.py works fine and updates the fields as I require.

As I have several fields which require the same conversion and there's many more values to convert I thought I'd create a function with a couple of variables for the fields. However, I can't get the function to work. The attached script Scipt_function_not_working.py doesn't work and I'm not sure why.

Any ideas where I've gone wrong?

Thanks in advance.
0 Kudos
5 Replies
by Anonymous User
Not applicable
Original User: Hornbydd

Mark,

If I've understood your code correctly you are trying to access the row object within the renamefld procedure.  The section of code below is still part of that procedure.

    ##rows.updateRow(row)
    if a == row.LUC_ID:
        print "LUC ID = " + str(a)
    else:    
        print "Previous LUC ID = " + str(a)
    if b == row.LUC_NAME:
        print "LUC Name = " + b
    else:
        print "Previous LUC N = " + b


But you are creating your row objects in the main body of your program. You need to either pass the row object as an argument into your procedure or get it's value and pass that if you want to do the test as shown above in that procedure.

Duncan
0 Kudos
by Anonymous User
Not applicable
Original User: mpc

Thanks for your reply Duncan. The piece of code highlighted in your post isn't actually needed, it's just some print statements so I can check if it's done what it should of. I manually checked the table and it hadn't changed the values.

I think I understand the error in the print statements, as like you say I need to use GetValue for LUC_ID and LUC_NAME to pass it's value.

Should the row object be in the procedure, as well as the for statement? The crux of the script that isn't working is below.

def renamefld(a, b):            
    if a == 71:
        b = "Natural Forest"
    elif a == 72:                
        b = "Planted Forest - Pre-1990"
    else:
        print "Error with converting subtype to text"

for row in rows:
    renamefld (row.LUC_ID, row.LUC_NAME)
    renamefld (row.PREV_LUC_ID, row.PREV_LUC_N)
    rows.updateRow(row)
0 Kudos
DuncanHornby
MVP Notable Contributor
Mark,

I don't have ArcGIS 10 so I've had to do this in 9.3 python, so the code is a little different. My knowledge of Python ain't great but I realised you are not actually returning a value and what was getting passed to the function was is a string and you were not writing the new string back to the row. So below is some code that worked on a table I knocked up, hope you understand it?

Duncan


import arcgisscripting
gp =arcgisscripting.create(9.3)
gp.workspace= r"C:\temp"

def renamefld(a):
    
    if a == 1:
        return "Natural Forest"
    elif a == 2:                
        return "Planted Forest - Pre-1990"
    else:
        # Return an ! so we know not to attempt to update row       
        print "Error with converting subtype to text"
        return "!"

# Create update cursor
rows = gp.UpdateCursor("test.dbf")
row = rows.Next()

while row:
    # Get row information
    id = row.id
    type = row.type

    # Call function to change type 
    type = renamefld (id)
    
    # update row object    
    if type != "!":
        row.type = type
        rows.updateRow(row)
    
    row = rows.Next()

# release cursor
del row
del rows
0 Kudos
by Anonymous User
Not applicable
Original User: mpc

Hi Duncan,

Thanks for your input on this, you were spot on. With a couple of changes I managed to get the result I needed. The code for Arc10 is slightly different so I've copied it below. The "global" variable option I used is very useful! Unfortunately I couldn't get row.x to work and had to hard code the fields.

Mark

def renamefld(a):
    try:        
        if a == 71:
            return "Natural Forest"
        elif a == 72:                
            return"Planted Forest - Pre-1990"
        elif a == 73:
            return "Post 1989 Forest"
        elif a == 74:
            return "Grassland - With woody biomass"
        elif a == 75:
            return "Grassland - High producing"
        elif a == 76:
            return "Grassland - Low producing"
        elif a == 77:
            return "Cropland - Perennial"
        elif a == 78:
            return "Cropland - Annual"
        elif a == 79:
            return "Wetland - Open water"
        elif a == 80:
            return "Wetland - Vegetated non forest"
        elif a == 81:
            return "Settlements"
        elif a == 82:            
            return "Other"
        else:
            print "Error with converting subtype to text"
            return "!"
    except:
        print arcpy.GetMessages()

def region(a):
    try:        
        if a == 1:
            return "Northland"
        elif a == 2:
            return "Auckland"
        elif a == 3:            
            return "Waikato"
        elif a == 4:            
            return "Bay of Plenty"
        elif a == 5:            
            return "Gisborne"
        elif a == 6:            
            return "Hawkes Bay"
        elif a == 7:            
            return "Taranaki"
        elif a == 8:            
            return "Manawatu-Wanganui"
        elif a == 9:            
            return "Wellington"
        elif a == 12:            
            return "West Coast"
        elif a == 13:
            return "Canterbury"           
        elif a == 14:            
            return "Otago"
        elif a == 15:            
            return "Southland"
        elif a == 16:            
            return "Tasman"
        elif a == 17:            
            return "Nelson"            
        elif a == 18:            
            return "Marlborough"
        else:
            print "Error with converting region to text"
            return "!"
    except:
        print arcpy.GetMessages()

global row, cur

cur = arcpy.UpdateCursor(inMemFc)

for row in cur:

    LUM_Region = row.LUM_REG_ID    
    regvalue = region(LUM_Region)

    if regvalue != "!":
        row.LUM_REGION = regvalue
        cur.updateRow(row)
        
    LUC_ID = row.LUC_ID

    fldvalue = renamefld(LUC_ID)
 
    if fldvalue != "!":
        row.LUC_NAME = fldvalue
        cur.updateRow(row)

    PREV_LUC_ID = row.PREV_LUC_ID

    fldvalue = renamefld(PREV_LUC_ID)
 
    if fldvalue != "!":
        row.PREV_LUC_N = fldvalue
        cur.updateRow(row)

    IMPR_LUC_I = row.IMPR_LUC_I

    fldvalue = renamefld(IMPR_LUC_I)
 
    if fldvalue != "!":
        row.IMPR_LUC_N = fldvalue
        cur.updateRow(row)
0 Kudos
NiklasNorrthon
Frequent Contributor
Just a couple general code review comments:

Your renamefld function is a perfect candidate for a dictionary lookup, and errors should be handled as errors.

field_map = { 
    71 : "Natural Forest",
    72 : "Planted Forest - Pre-1990",
    73 : "Post 1989 Forest",
    # et cetera
    }

class SubtypeConversionError(Exception):
    pass 

def renamefld(a):
    try:
        return field_map
    except KeyError:
        raise SubtypeConversionError("Error with converting subtype %d to text...
0 Kudos