Arcpy Script Field Calculator

2346
10
Jump to solution
10-01-2019 07:36 AM
BrianMcNamara2
New Contributor II

I am having issues getting a field calc script in arcpy to run. It's probably my parameters, but I can't seem to find the error. Please see below. I am 'ranking', one shapefile based on multiple columns (with weights applied). My goal is to import it as a script into a toolbox so a user doesn't have to use arcpy.

Thanks in advance!

Edit: format, spelling

#import system modules
import arcpy
import os



#set paramaters - parameters are weights
inFC = arcpy.GetParameter(0)



#fieldName_FinalScore = arcpy.ListFields(inFC)
Parameter_1_p = arcpy.GetParameter(1)
Parameter_2_p = arcpy.GetParameter(2)



#convert GetParamter to floats, I thought 
Parameter_1 = float(Parameter_1_p)
Parameter_2 = float(Parameter_2_p)


#field name
fieldName_FinalScore = "FinalScore"



#lower box
expression_FinalScore = "Value(!Criteria1!,!Criteria2!)"



#code block upper
codeblock_FinalScore = """def Value( Criteria_1, Criteria_2):
FinalScore = !Criteria_1! * Parameter_1 + !Criteria_2! * Parameter_2"""



#Execute CalculateField 
arcpy.CalculateField_management(inFC, fieldName_FinalScore, expression_FinalScore, "PYTHON_9.3", codeblock_FinalScore)
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
MicahBabinski
Occasional Contributor III

That helps! You're really close - we'll get ya sorted out. Assuming Criteria_1 and Criteria_2 are existing fields in your shapefile, I think you could ditch the codeblock parameter altogether and use something like this:

expression_FinalScore = """!Criteria_1! * {} + !Criteria_2! * {}""".format(str(Parameter_1), str(Parameter_2))

arcpy.CalculateField_management(inFC, fieldName_FinalScore, expression_FinalScore, "PYTHON_9.3")

As for your parameters, I believe that if you set the parameter type to "Double" in the script tool properties they will come in as the Python <float> type without any need to modify their types in the script.

Micah

View solution in original post

10 Replies
JoshuaBixby
MVP Esteemed Contributor

Having issues?  It helps to provide specifics about the issues in addition to code.  Are you getting an error message?  if so, what?  Provide error and traceback.  Are you getting unexpected results?  If so, what?

Taking a quick look at the code, there are a couple issues with this line:

FinalScore = !Criteria_1! * Parameter_1 + !Criteria_2! * Parameter_2"""

First, you don't put exclamation marks around the variables within a code block.  Second, you are defining a FinalScore variable but you are never returning it.  You have to return the value in order for the cursor to do anything with it.

BrianMcNamara2
New Contributor II

Update below original thread, thank you so much for your reply!

0 Kudos
JoeBorgione
MVP Emeritus

Presenting your code in a more readable format is really helpful.  Below I've taken the liberty of clicking on the on the 'More' context menu in the expanded tool bar, and selecting Syntax Highlighter/Python and pasting your code there....  Joshua Bixby‌'s comment is directed to line #35.

#import system modules
import arcpy
import os

 

#set paramaters - parameters are weights
inFC = arcpy.GetParameter(0)

 

#fieldName_FinalScore = arcpy.ListFields(inFC)
Parameter_1_p = arcpy.GetParameter(1)
Parameter_2_p = arcpy.GetParameter(2)

 

#convert GetParamter to floats, I thought 
Parameter_1 = float(Parameter_1_p)
Parameter_2 = float(Parameter_2_p)


#field name
fieldName_FinalScore = "FinalScore"

 

#lower box
expression_FinalScore = "Value(!Criteria1!,!Criteria2!)"

 

#code block upper
codeblock_FinalScore = """def Value( Criteria_1, Criteria_2):
FinalScore = !Criteria_1! * Parameter_1 + !Criteria_2! * Parameter_2"""

 

#Execute CalculateField
arcpy.CalculateField_management(inFC, fieldName_FinalScore, expression_FinalScore, "PYTHON_9.3", codeblock_FinalScore)
That should just about do it....
BrianMcNamara2
New Contributor II

Thank you for the reply and information, updated to make code more readable

MicahBabinski
Occasional Contributor III

What happens when you run the script, Brian McNamara‌? That will help pinpoint the answer.

As Joshua pointed out, you'll need to return the result of our Value() function. Put something like:

    return FinalScore

inside of those triple quotes.

Micah

BrianMcNamara2
New Contributor II

Thank you for all the replies, I tried a few things that helped some, but not there. A new code is below that includes...

-Added return FinalScore (originally I had a syntax error, this seemed to solve that).

Notes:

-I'm not sure if the Parameter to float is needed, I read get parameter comes in as an object, does that mean a blob? That's why converted it (still investigating) .

-The error says 'not defined', so I assume its a scope issue. I'm trying to get the structure right for arcpy field calc. I think that's where my error is (still investigating)

#Geonet V2
#import system modules
import arcpy
import os

#set paramaters - parameters are weights
inFC = arcpy.GetParameter(0)

#fieldName_FinalScore = arcpy.ListFields(inFC)
Parameter_1_p = arcpy.GetParameter(1)
Parameter_2_p = arcpy.GetParameter(2)

#set to float, not sure if GetParameter comes in as float, double or what. I read it comes in as an object (blob?)
Parameter_1 = float(Parameter_1_p)
Parameter_2 = float(Parameter_2_p)


#field name
fieldName_FinalScore = "FinalScore"

#lower box
expression_FinalScore = "Value(!Criteria_1!,!Criteria_2!,Parameter_1,Parameter_2)"

#code block upper
codeblock_FinalScore = """def Value( Criteria_1, Criteria_2, Parameter_1, Parameter_2):
    FinalScore = Criteria_1 * Parameter_1 + Criteria_2 * Parameter_2
    return FinalScore""" 

#Execute CalculateField 
arcpy.CalculateField_management(inFC, fieldName_FinalScore, expression_FinalScore, "PYTHON_9.3", codeblock_FinalScore)

‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Error:

Traceback (most recent call last):
  File "W:\Citrix\35000s\35217\GIS\ExamplePropData\Rank\GeoNet.py", line 29, in <module>
    arcpy.CalculateField_management(inFC, fieldName_FinalScore, expression_FinalScore, "PYTHON_9.3", codeblock_FinalScore)
  File "c:\program files (x86)\arcgis\desktop10.5\arcpy\arcpy\management.py", line 3661, in CalculateField
    raise e
ExecuteError: ERROR 000539: Error running expression: Value(5.0,2.0,Parameter_1,Parameter_2) 
Traceback (most recent call last):
  File "<expression>", line 1, in <module>
NameError: name 'Parameter_1' is not defined

Failed to execute (CalculateField).


Failed to execute (RankWeight2).
Failed at Tue Oct 01 12:51:12 2019 (Elapsed Time: 0.33 seconds)
0 Kudos
MicahBabinski
Occasional Contributor III

That helps! You're really close - we'll get ya sorted out. Assuming Criteria_1 and Criteria_2 are existing fields in your shapefile, I think you could ditch the codeblock parameter altogether and use something like this:

expression_FinalScore = """!Criteria_1! * {} + !Criteria_2! * {}""".format(str(Parameter_1), str(Parameter_2))

arcpy.CalculateField_management(inFC, fieldName_FinalScore, expression_FinalScore, "PYTHON_9.3")

As for your parameters, I believe that if you set the parameter type to "Double" in the script tool properties they will come in as the Python <float> type without any need to modify their types in the script.

Micah

BrianMcNamara2
New Contributor II

That did it! Yes, Criteria_1 etc are existing fields. The format string did the trick, thank you so much for your help. I forgot about just using .format instead of the code block, I need to use python more consistently. Thanks again for your help.

final code is below

#import system modules
import arcpy
import os

#set paramaters - parameters are weights
inFC = arcpy.GetParameter(0)

#fieldName_FinalScore = arcpy.ListFields(inFC)
Parameter_1 = arcpy.GetParameter(1)
Parameter_2 = arcpy.GetParameter(2)

#deleted set to float, no need as parameter comes in as double/float, via script properties

#field name
fieldName_FinalScore = "FinalScore"

#lower box
expression_FinalScore = """!Criteria_1! * {} + !Criteria_2! * {}""".format(str(Parameter_1), str(Parameter_2))

#deleted code block 

#Execute CalculateField 
arcpy.CalculateField_management(inFC, fieldName_FinalScore, expression_FinalScore, "PYTHON_9.3")‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
MicahBabinski
Occasional Contributor III

Glad to have helped, Brian McNamara. Happy scripting.