GEOlson86

Best Way to Calculate Many Fields

Discussion created by GEOlson86 on Sep 19, 2013
Latest reply on Sep 23, 2013 by GEOlson86
Short Explanation: I have 8 fields I need to calculate that uses 2 fields as variables as to designate which of the 8 fields to calculate.

Long Explanation:  I have a streets feature class that I need to be able to update traffic capacity for.  There are 4 intervals (2010, 2019, 2025, and 2045) and the capacity is calculated with directionality, so for each year interval there are 2 capacity fields - 8 fields total.  Each street feature has a field for each year interval that specifies if it's one-way (1 or -1 depending on how the feature was drawn) or two-way.  If it's a two-way street then both fields are calculated and if it's one-way then the direction field dictates which field to calculate for.  Easy enough.  To complicate that a little more I have a field that needs to specify which years street is "valid" for and that dictates which years to calculate capacity for.

So far I have my calculation function working; it's my python field calculator script.  I also have a single year calculating properly.  So the road name, function, area type, and number of lanes are what I'm using to calculate capacity.  I'm using an updateCursor to retrieve data values and assign the calculated values.

Disregarding the function for now, here's what I have:
import arcpy, os, sys

#set map doc and the layer to be used
mxd = arcpy.mapping.MapDocument("Current")
mapLyr = arcpy.mapping.ListLayers(mxd, "CUR_Master_Network_2045")[0]
rows = arcpy.UpdateCursor(mapLyr)

for row in rows:
    row.F2010_AB_C = 0 #clear all capacities to 0
    row.F2010_BA_C = 0
    row.F2019_AB_C = 0
    row.F2019_BA_C = 0
    row.F2025_AB_C = 0
    row.F2025_BA_C = 0
    row.F2045_AB_C = 0
    row.F2045_BA_C = 0
    rows.updateRow(row)
    #find capacity variables
    rnam = row.getValue("ROAD_NAM")
    ffc =  row.getValue("LRTP_FFC")
    at = row.getValue("TYPE_AREA")
    lan = row.getValue("F2010_NUML")
    dic = {"ROAD_NAM": rnam, "LRTP_FFC": ffc, "TYPE_AREA": at}
    #begin capacity calculation
    if row.BUILD_STAT == 10 and row.F2010_DIR == 1:
            row.F2010_AB_C = capacity(**dic) * lan
            rows.updateRow(row)
    elif row.BUILD_STAT == 10 and row.F2010_DIR == -1:
            row.F2010_AB_C = capacity(**dic) * lan
            rows.updateRow(row)
    elif row.BUILD_STAT == 10 and row.F2010_DIR == 0:
            row.F2010_AB_C = capacity(**dic) * lan
            row.F2010_BA_C = capacity(**dic) * lan
            rows.updateRow(row)
    else:
        pass
del row, rows


This is working great, but it's only for a single set of parameters - BUILD_STAT 10 and the three possible directions.  What's the best way to add code to calculate not only BUILD_STAT 10 but also 19, 25, and 45 and follow the directions?  Do I just need to keep nesting if statements for each BUILD_STAT year?

import arcpy, os, sys

#set map doc and the layer to be used
mxd = arcpy.mapping.MapDocument("Current")
mapLyr = arcpy.mapping.ListLayers(mxd, "CUR_Master_Network_2045")[0]
rows = arcpy.UpdateCursor(mapLyr)

for row in rows:
    row.F2010_AB_C = 0 #clear all capacities to 0
    row.F2010_BA_C = 0
    row.F2019_AB_C = 0
    row.F2019_BA_C = 0
    row.F2025_AB_C = 0
    row.F2025_BA_C = 0
    row.F2045_AB_C = 0
    row.F2045_BA_C = 0
    rows.updateRow(row)
    #find capacity variables
    rnam = row.getValue("ROAD_NAM")
    ffc =  row.getValue("LRTP_FFC")
    at = row.getValue("TYPE_AREA")
    lan = row.getValue("F2010_NUML")
    dic = {"ROAD_NAM": rnam, "LRTP_FFC": ffc, "TYPE_AREA": at}
    #begin capacity calculation
    if row.BUILD_STAT == 10 and row.F2010_DIR == 1:
            row.F2010_AB_C = capacity(**dic) * lan
            rows.updateRow(row)
            if row.F2019_DIR == 1:
                row.F2019_AB_C = capacity(**dic) * lan
                rows.updateRow(row)
            elif row.F2019_DIR == -1:
                row.F2019_BA_C = capacity(**dic) * lan
                rows.updateRow(row)
            else:
                row.F2019_AB_C = capacity(**dic) * lan
                row.F2019_BA_C = capacity(**dic) * lan
    elif row.BUILD_STAT == 10 and row.F2010_DIR == -1:
            row.F2010_AB_C = capacity(**dic) * lan
            rows.updateRow(row)
            if row.F2019_DIR == 1:
                row.F2019_AB_C = capacity(**dic) * lan
                rows.updateRow(row)
            elif row.F2019_DIR == -1:
                row.F2019_BA_C = capacity(**dic) * lan
                rows.updateRow(row)
            else:
                row.F2019_AB_C = capacity(**dic) * lan
                row.F2019_BA_C = capacity(**dic) * lan
    elif row.BUILD_STAT == 10 and row.F2010_DIR == 0:
            row.F2010_AB_C = capacity(**dic) * lan
            row.F2010_BA_C = capacity(**dic) * lan
            rows.updateRow(row)
            if row.F2019_DIR == 1:
                row.F2019_AB_C = capacity(**dic) * lan
                rows.updateRow(row)
            elif row.F2019_DIR == -1:
                row.F2019_BA_C = capacity(**dic) * lan
                rows.updateRow(row)
            else:
                row.F2019_AB_C = capacity(**dic) * lan
                row.F2019_BA_C = capacity(**dic) * lan
    else:
        pass
del row, rows


The only problem is each if and elif will need every possible outcome as it goes through the conditions.  Is there a better way?

Outcomes