Open fiendskrah opened 1 year ago
Original code:
# Adds a standardized version of the input field
# to the input feature attribute table
# standardization scale [0.0, 1.0]
# AUTHOR: Arika Ligmann-Zielinska
# LAST UPDATED: July 21 2011
#--- IMPORTS ----------------------------------------------------------
import sys, arcpy
#------------- INPUTS -------------------------------------------------
inFC = sys.argv[1]
infield = sys.argv[2]
outfield = sys.argv[3] # output field name
benefit = sys.argv[4] # treat as benefit or cost?
method = sys.argv[5] # standardization method
#------------- APPLICATION --------------------------------------------
try:
# [1] Check input field - must be "numeric"
fields = arcpy.ListFields(inFC, infield)
for fld in fields:
if fld.type not in ["SmallInteger","Integer","Single","Double"]:
arcpy.AddError(infield+" is not numeric.")
sys.exit(1)
# [2] add field
arcpy.AddField_management(inFC, outfield, "FLOAT", 6, 3)
arcpy.AddMessage("Field "+outfield+" created.")
# [3] Get a list of input field values to standardize
rows = arcpy.SearchCursor(inFC)
fieldVals = []
for row in rows:
aval = row.getValue(infield)
fieldVals.append(aval)
del row; del rows
# Get min & max
minVal = min(fieldVals)
maxVal = max(fieldVals)
# [4] standardize
if benefit == "BENEFIT":
if method == "RATIO (LINEAR SCALE)":
rows = arcpy.UpdateCursor(inFC)
for row in rows:
sval = float(row.getValue(infield))/maxVal
row.setValue(outfield,sval)
rows.updateRow(row)
del row; del rows
else: # 'SCORE RANGE' selected
arange = float(maxVal - minVal)
rows = arcpy.UpdateCursor(inFC)
for row in rows:
sval = float(row.getValue(infield)) - minVal
sval = sval/arange
row.setValue(outfield,sval)
rows.updateRow(row)
del row; del rows
else: # 'COST'
if method == "RATIO (LINEAR SCALE)":
rows = arcpy.UpdateCursor(inFC)
for row in rows:
sval = minVal/float(row.getValue(infield))
row.setValue(outfield,sval)
rows.updateRow(row)
del row; del rows
else: # 'SCORE RANGE' selected
arange = float(maxVal - minVal)
rows = arcpy.UpdateCursor(inFC)
for row in rows:
sval = maxVal - float(row.getValue(infield))
sval = sval/arange
row.setValue(outfield,sval)
rows.updateRow(row)
del row; del rows
# display the information
info = infield+ " of "+inFC+" standardized to "+outfield
arcpy.AddMessage(info)
except:
arcpy.AddError("Script run error: "+arcpy.GetMessages(2))
current pyt:
class StandardizeRatiosScore(object):
def __init__(self):
"""Define the tool (tool name is the name of the class)."""
self.label = "Standardize Ratios/Score"
self.description = "Takes numerical data from a user-provided field in a data layer in the current ArcGIS Pro project, as well as a user-provided cost/benefit binary value, and returns the data as a standardized ratio or score."
self.canRunInBackground = False
def getParameterInfo(self):
"""Define parameter definitions"""
input_table = arcpy.Parameter(
displayName="Input Table",
name="input_table",
datatype="GPTableView",
parameterType="Required",
direction="Input")
fields_to_standardize = arcpy.Parameter(
displayName="Field with Numerical Data",
name="fields_to_standardize",
datatype="Field",
parameterType="Required",
direction="Input",
enabled=False,
multiValue=True)
fields_to_standardize.parameterDependencies = [input_table.name]
standardization_method = arcpy.Parameter(
displayName="Standardization Method",
name="standardization_method",
datatype="GPString",
parameterType="Required",
direction="Input")
standardization_method.filter.type = "ValueList"
standardization_method.filter.list = ['Score Range', 'Ratio (Linear Scale)']
cost_benefit = arcpy.Parameter(
displayName="Cost/Benefit",
name="cost_benefit",
datatype="GPString",
parameterType="Required",
direction="Input",
multiValue=False)
cost_benefit.filter.type = "ValueList"
cost_benefit.filter.list = ['Cost', 'Benefit']
# define the derived output parameter
outfield_name = arcpy.Parameter(
displayName="Output Field Name",
name="outfield_name",
datatype="GPString",
parameterType="Required",
direction="Input",
enabled=True)
cost_benefit.filter.type = "Value"
outfield = arcpy.Parameter(
displayName="Output Field",
name="outfield",
datatype="Field",
parameterType="Derived",
direction="Output")
parameters = [input_table, fields_to_standardize, standardization_method, cost_benefit, outfield, outfield_name]
return parameters
def updateParameters(self, parameters):
"""Modify the values and properties of parameters before internal
validation is performed. This method is called whenever a parameter
has been changed."""
if parameters[0].altered:
parameters[1].enabled = True
def execute(self, parameters, messages):
"""The source code of the tool."""
input_table = arcpy.GetParameterAsText(0)
fields_to_standardize = arcpy.GetParameterAsText(1)
# Get the minimum and maximum values of the user-provided field
with arcpy.da.SearchCursor(input_table, [fields_to_standardize]) as cursor:
max_value = None
min_value = None
for row in cursor:
if max_value is None or row[0] > max_value:
max_value = row[0]
if min_value is None or row[0] < min_value:
min_value = row[0]
# create a dictionary to store the max and min values
result_dict = {'maximum': max_value, 'minimum': min_value}
outfield_name = parameters[5].valueAsText
# Add the new field to the input layer
arcpy.AddField_management(input_table, outfield_name, "DOUBLE")
# set parameters for standardization loop
result_dict = eval(parameters[4].valueAsText)
method = parameters[2].valueAsText
benefit = parameters[3].valueAsText
maxVal = result_dict['maximum']
minVal = result_dict['minimum']
outfield = parameters[5]
# standardize the score of each row using the min and max values
if benefit == "Benefit":
if method == "Ratio (Linear Scale)":
rows = arcpy.UpdateCursor(input_table)
for row in rows:
sval = float(row.getValue(row))/maxVal
row.setValue(outfield,sval)
rows.updateRow(row)
del row; del rows
else: # 'Score Range' selected
arange = float(maxVal - minVal)
rows = arcpy.UpdateCursor(input_table)
for row in rows:
sval = float(row.getValue(row)) - minVal
sval = sval/arange
row.setValue(outfield,sval)
rows.updateRow(row)
del row; del rows
else: # 'Cost'
if method == "Ratio (Linear Scale)":
rows = arcpy.UpdateCursor(input_table)
for row in rows:
sval = minVal/float(row.getValue(row))
row.setValue(outfield,sval)
rows.updateRow(row)
del row; del rows
else: # 'Score Range' selected
arange = float(maxVal - minVal)
This tool allows the user to provide specific criteria in a data layer that will be standardized for later analysis
This tool is optional for the current assignment but I still would like to include it because other arcgis tools I can find don't add the standardized scores to the attribute table for use in later tools.