-1

I have a script and sometimes when you run it it says newTract is undefined and if I declare newTract globally then it will say objID is undefined.

Do I need to clear these variables?

The error only happens after successive runs of the script without closing ArcMap in between runs.


import arcpy


##Set map, df
mxd=arcpy.mapping.MapDocument("CURRENT")
df=arcpy.mapping.ListDataFrames(mxd,"Layers")[0]
## Starting OID will be declared by selection made by user before running script

## Establish starting OID based on initial selection by user
with arcpy.da.SearchCursor("LD_SECTION_POLY","OBJECTID") as cursor:
    for row in cursor:
        objID=row[0]
arcpy.SelectLayerByAttribute_management("LD_SECTION_POLY", "CLEAR_SELECTION")

## Get pipe attributes so script cann follow subject pipe
with arcpy.da.SearchCursor("PL_PIPELINE_LN",["CENTERLINE_NAME","PIPE_SEG_NML_DIAM_D"]) as cursor:
    for row in cursor:
        cenName=row[0]
        dia=row[1]


##Query to return the subject pipe so subject tracts can be identified
thisPipe="""CENTERLINE_NAME = '{0}' AND PIPE_SEG_NML_DIAM_D = {1}""".format(cenName,dia)

## clear initial selection
arcpy.SelectLayerByAttribute_management("PL_PIPELINE_LN", "CLEAR_SELECTION")
## Select tracts without pipe in them to control excess iteration
## First select tracts with pipeline intersect and invert selection
arcpy.SelectLayerByAttribute_management("PL_PIPELINE_LN","NEW_SELECTION",thisPipe)
arcpy.SelectLayerByLocation_management("LD_SECTION_POLY","INTERSECT","PL_PIPELINE_LN","","NEW_SELECTION","INVERT")
## Get count of tracts with no pipe and subtract from tract total
noPipeCount=arcpy.GetCount_management("LD_SECTION_POLY")
noPipeResult=int(noPipeCount.getOutput(0))

## Clear selection
arcpy.SelectLayerByAttribute_management("LD_SECTION_POLY", "CLEAR_SELECTION")

## Declare dictionary to hold subject oid and an entry of all rows
tractDict={}
# List to accumulate and remove tracts that already have their adjoiner established
tractList=[]
# Get tract count to start iteration
count=arcpy.GetCount_management("LD_SECTION_POLY")
result = int(count.getOutput(0))

resultNew=result-noPipeResult



## for loop to iterate through subject tracts
for x in range(resultNew):
    ## condition to double back on the last tract and declare adjoiner and add info
    ## to the dictionary
    if x==resultNew-1:
        print "X={0}".format(x)
        arcpy.SelectLayerByAttribute_management("LD_SECTION_POLY", "CLEAR_SELECTION")
        arcpy.SelectLayerByAttribute_management("PL_PIPELINE_LN", "CLEAR_SELECTION")
        #print "X= {0}".format(x)
        ## Add current selected tract to list of tracts to be removed from selection
        ## to reveal the forward adjoiner
        tractList.append(objID)
        ## First where clause to make initial selection based on OID provided by
        ## the last iteration
        where="""OBJECTID = {0}""".format(objID)
        ## Remove clause to remove subject tract from adjoiner selection

        whereNot="""OBJECTID <> {0}""".format(objID)
         ## make initial selection based on the last tract OID
        arcpy.SelectLayerByAttribute_management("LD_SECTION_POLY","NEW_SELECTION",where)

        ## Select pipe within .5 feet from subject tract, pipe is always segmented so
        ## this leaves a stub into the direct adjoiner and not a corner adjacent
        ## tract
        arcpy.SelectLayerByLocation_management("PL_PIPELINE_LN","WITHIN_A_DISTANCE","LD_SECTION_POLY",".5 feet","NEW_SELECTION")

        ## Select pipeline with intersection with selected pipeline stubs, unless this
        ## is the first or last tract there will be 3 selected tracts after this
        ## selection

        arcpy.SelectLayerByLocation_management("LD_SECTION_POLY","INTERSECT","PL_PIPELINE_LN","","NEW_SELECTION")


        ## This selection removes the subject OID revealing the last adjoiner
        arcpy.SelectLayerByAttribute_management("LD_SECTION_POLY","SUBSET_SELECTION",whereNot)
        ## search cursor to populate tractDict
        with arcpy.da.SearchCursor("LD_SECTION_POLY",["OBJECTID","DEED_SURFACE_OWNER","STD_TAX_ID","ABSTRACT_SURVEY"]) as cursor:
            for row in cursor:
                newTract=row[0]
                print "The subject OID is {0} and the adjoiner is OID {1}".format(objID,newTract)
                tractDict[objID]=row
        ## Swap oid with newTract to move iteration forward
        objID=newTract



    else:


        print "X= {0}".format(x)
        ## Add tract OID to running tract list, to be removed in selection later
        tractList.append(objID)
        ## Where clause to add origin OID to new selection
        where="""OBJECTID = {0}""".format(objID)
        ## Where clause to remove origin OID from Selection
        whereNot="""OBJECTID <> {0}""".format(objID)



         ## make initial selection based on the last tract OID
        arcpy.SelectLayerByAttribute_management("LD_SECTION_POLY","NEW_SELECTION",where)

        ## Select all subject pipe
        arcpy.SelectLayerByAttribute_management("PL_PIPELINE_LN","NEW_SELECTION",thisPipe)

        ## Select pipe within .5 feet from subject tract, pipe is always segmented so
        ## this leaves a stub into the direct adjoiner and not a corner adjacent
        ## tract
        arcpy.SelectLayerByLocation_management("PL_PIPELINE_LN","WITHIN_A_DISTANCE","LD_SECTION_POLY",".5 feet","SUBSET_SELECTION")

        ## Select pipeline with intersection with selected pipeline stubs, unless this
        ## is the first or last tract there will be 3 selected tracts after this
        ## selection


        arcpy.SelectLayerByLocation_management("LD_SECTION_POLY","CONTAINS","PL_PIPELINE_LN","","NEW_SELECTION")


        ## Remove tacts with OID in tractList, this removes previous adjoiners
        ## revealing the most forward adjoiner
        for tract in tractList:
            whereRemove="""OBJECTID = {0}""".format(tract)
            arcpy.SelectLayerByAttribute_management("LD_SECTION_POLY","REMOVE_FROM_SELECTION",whereRemove)
        ## Search cursor to remove tracts with OID in the tractList
        with arcpy.da.SearchCursor("LD_SECTION_POLY",["OBJECTID","DEED_SURFACE_OWNER","STD_TAX_ID","ABSTRACT_SURVEY"]) as cursor:
            for row in cursor:
                newTract=row[0]
                print row

        ##Populate the dictionary with tract attributes the key is the subject tract
        ## the row  is adjoiner information
        tractDict[objID]=row

        print "The subject OID is {0} and the adjoiner is OID {1}".format(objID,newTract)
        objID=newTract

##Select and populate attributes based on dict values
fcAdjoinerList=[u'CH_NGS_DATA_PT', u'CH_CHECKSHOT_PT', u'ES_PT', u'ES_LN', u'ES_POLY', u'EC_WATTLE_LN', u'EC_EROSION_MAT_POLY', u'EC_DRAIN_LN', u'EC_BALE_LN', u'EC_RIPRAP_POLY', u'EC_SILT_FENCE_LN', u'EC_GABION_POLY', u'EC_EROSION_BLANKET_POLY', u'FA_FIELD_POLY', u'FA_FIELD_LN', u'HY_PT', u'HY_POLY', u'HY_LN', u'LD_TEMP_WORKSPACE_POLY', u'LD_PROPERTY_CORNER_PT', u'LD_DISTURBANCE_PT', u'LD_ROW_LN', u'LD_BOUNDARY_PT', u'LD_ROW_POLY', u'LD_BOUNDARY_LN', u'LD_SURFACE_LEASE_POLY', u'LD_DISTURBANCE_POLY', u'LD_BOUNDARY_POLY', u'PL_PUMP_STATION_PT', u'PL_METER_STATION_PT', u'PL_VENT_PIPE_PT', u'PL_TRENCH_BREAKER_LN', u'PL_TEE_PT', u'PL_PIPELINE_LN', u'PL_ELBOW_PT', u'PL_CASING_LN', u'PL_ANODE_PT', u'PL_TAP_PT', u'PL_SLEEVE_LN', u'PL_ROCK_SHIELD_LN', u'PL_PIPE_BEND_LN', u'PL_INJECTOR_PT', u'PL_GIRTH_WELD_PT', u'PL_COMPRESSOR_STATION_PT', u'PL_TEST_LEAD_PT', u'PL_NAT_GROUND_PT', u'PL_REDUCER_PT', u'PL_PIG_SIGNAL_PT', u'PL_DRIP_PT', u'PL_DEPTH_OF_COVER_PT', u'PL_BOND_LEAD_PT', u'PL_ROUTING_NOTE_PT', u'PL_PI_EXCAVATION_PT', u'PL_JOIN_PT', u'PL_FLANGE_PT', u'RC_HYDROMULCH_POLY', u'RC_MULCH_POLY', u'RC_RECLAMATION_OTHER_LN', u'RC_RECLAMATION_OTHER_PT', u'RC_SEEDBED_PREPARATION_POLY', u'RC_SOIL_AMENDMENT_POLY', u'RC_SOILBED_PREPARATION_POLY', u'RC_WETLANDS_POLY', u'RC_SOIL_SAMPLE_PT', u'SI_FACILITY_OTHER_POLY', u'SI_FACILITY_PERIMETER_POLY', u'ST_OTHER_LN', u'ST_OTHER_POLY', u'ST_OTHER_PT', u'TR_TRANS_OTHER_POLY', u'WE_PAD_POLY', u'WE_PT']
listLayers=arcpy.mapping.ListLayers(mxd,"*",df)
for lyr in listLayers:
    if lyr.isFeatureLayer==True:

        if lyr.visible==True:
            lyrPath=lyr.workspacePath
            if lyrPath[-4:]==".gdb":
                arcpy.SelectLayerByAttribute_management("LD_SECTION_POLY", "CLEAR_SELECTION")

#arcpy.SelectLayerByAttribute_management("LD_SECTION_POLY", "CLEAR_SELECTION")
# Fill in the fields
for key in tractDict:
    whereNow="""OBJECTID={0}""".format(key)
    arcpy.SelectLayerByAttribute_management("LD_SECTION_POLY","NEW_SELECTION",whereNow)
    listLayers=arcpy.mapping.ListLayers(mxd,"*",df)
    for lyr in listLayers:
        if lyr.isFeatureLayer==True:

            if lyr.visible==True:
                lyrPath=lyr.workspacePath
                if lyrPath[-4:]==".gdb":
                    if not lyr.name=="LD_SECTION_POLY":

                        arcpy.SelectLayerByLocation_management(lyr.name,"HAVE_THEIR_CENTER_IN","LD_SECTION_POLY","","NEW_SELECTION")
                        if lyr.name in fcAdjoinerList:

                            listfields=arcpy.ListFields(str(lyr.name))
                            for field in listfields:
                                if field.name=="STD_TAX_ID_ADJOINER":
                                    print "Calculating {0} field in the {1} feature class".format(field.name,lyr.name)
                                    arcpy.CalculateField_management(lyr.name,field.name,"'{0}'".format(tractDict[key][2]),"PYTHON")

                                if field.name=="ADJOINER_SURFACE_OWNER":
                                    print "Calculating {0} field in the {1} feature class".format(field.name,lyr.name)
                                    arcpy.CalculateField_management(lyr.name,field.name,"'{0}'".format(tractDict[key][1]),"PYTHON")

                                if field.name=="ADJOINER_NAME":
                                    print "Calculating {0} field in the {1} feature class".format(field.name,lyr.name)
                                    arcpy.CalculateField_management(lyr.name,field.name,"'{0}'".format(tractDict[key][3]),"PYTHON")

for lyr in listLayers:
        if lyr.isFeatureLayer==True:

            if lyr.visible==True:
                lyrPath=lyr.workspacePath
                if lyrPath[-4:]==".gdb":
                    arcpy.SelectLayerByAttribute_management(lyr.name, "CLEAR_SELECTION")

Link to project gdb

Instructions

Run the script and it fills in adjoiner attributes for features.

The problem is that I get an error of newTract undefined or objID undefined after successive script runs without closing arcmap.

2
  • 4
    You don't seem to initialize variables outside of loop scope, so it's not surprising you get undefined errors. You've provided a huge chunk of uncommented code, but no indication of what it's supposed to do, or what the data is, or what happens when you start adding diagnostic print statements every time your variable is assigned, so I don't think there's anything we can do for you.
    – Vince
    May 13, 2017 at 11:57
  • 1
    Welcome to GIS SE! As a new user please take the tour to learn about our focused Q&A format. I have voted to close this question as there too much code and no explanation about what it's supposed to do. Please edit your question to include your error messages in full, and some detail about your script. As per the close reason above, try to make a Minimal, Complete, and Verifiable example - a test script - that reproduces your error, rather than pasting in your complete code. Potential answerers are unlikely to actually test code that requires them to reproduce your scenario first.
    – Midavalo
    May 13, 2017 at 13:41

1 Answer 1

2

To fix this problem I had to declare the variables that were undefined outside the loop, as suggested, and reference them with global key word inside the loops. I also changed the name of the row variable for each cursor. This is working so far.

objID=0
dia=0.0
cenName=""
newTract=0
##Set map, df
mxd=arcpy.mapping.MapDocument("CURRENT")
df=arcpy.mapping.ListDataFrames(mxd,"Layers")[0]
## Starting OID will be declared by selection made by user before running script

## Establish starting OID based on initial selection by user
with arcpy.da.SearchCursor("LD_SECTION_POLY","OBJECTID") as cursor:
    for row1 in cursor:
        global objID
        objID=row1[0]
arcpy.SelectLayerByAttribute_management("LD_SECTION_POLY", "CLEAR_SELECTION")

## Get pipe attributes so script cann follow subject pipe
with arcpy.da.SearchCursor("PL_PIPELINE_LN",["CENTERLINE_NAME","PIPE_SEG_NML_DIAM_D"]) as cursor:
    for row2 in cursor:
        global dia
        global cenName
        cenName=row2[0]
        dia=row2[1]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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