3
\$\begingroup\$

We have written a Python script using arcpy modules. It is was written by Python beginners and many parts of the code are written in 'unpythonic way'. The goal is to re-write or address 'unpythonic' code. The software used for this script are ArcMap 10.4 and written in Python 2.7. The complete script is available on GitHub.

The main directory is "C:/A__P6_GIS4/" and contains twelve sub-dirs the sub directories are actually names of counties, and each county sub-dir contains all relevant inputs inside the geodatabase or gdb file. First, the script loops and creates a .txt file with names of all the sub-dirs then uses this to loop through each sub-dir and execute set of functions for each county using set of if-else statements. The functions can be broadly broken by turf grass (TG) model, fractional (Frac) model, forest model and final model. The final model utilizes outputs from the aforementioned models and then creates the final model.

Only contains main() due to character limitation:

def main():

    ALL_start_time = time.time()
    #ALL_start_time = timeit.default_timer()

    if arcpy.CheckExtension("Spatial") == "Available":
        arcpy.AddMessage("Checking out Spatial")
        arcpy.CheckOutExtension("Spatial")
    else:
        arcpy.AddError("Unable to get spatial analyst extension")
        arcpy.AddMessage(arcpy.GetMessages(0))
        sys.exit(0)

    # Create List of Counties for Loop
    arcpy.Delete_management("C:/GIS_temp/county_list.txt")
    co_list = "C:/GIS_temp/county_list.txt"
    county_list = open(co_list,"a") #Open the list
    MainDIR = "C:/A__P6_GIS4/"  #Directory where LAND USE geodatabases are located

    for i in os.listdir(MainDIR):
        i_base = os.path.basename(i)
        county_list.write(i_base + "\n")
    county_list.close()

    # Start Looping Through County List
    county_list = open(co_list,"r")
    for i in county_list:  #A text file is needed to ensure looping works!
        CoName = i.strip("\n")
        print CoName + " started"
        # Setup Directories
        MainDIR = "C:/A__P6_GIS4/"  #Directory where LAND USE geodatabases are located
        CntyDIR = os.path.join(MainDIR, CoName + "/")
        OutputDIR = os.path.join(CntyDIR, "Outputs/")
        TiffDIR = os.path.join(OutputDIR, CoName + "_FINAL/") # Former FinalDirectory
        if not arcpy.Exists(OutputDIR):
            arcpy.CreateFolder_management(CntyDIR, "Outputs")
        if not arcpy.Exists(TiffDIR):
            arcpy.CreateFolder_management(OutputDIR, CoName + "_FINAL")
        Inputs = os.path.join(CntyDIR, CoName + "_Inputs.gdb/") # Former CoGDB
        Temp_1m = os.path.join(OutputDIR, "Temp_1m.gdb/") # Former TempGDB
        Temp_10m = os.path.join(OutputDIR, "Temp_10m.gdb/") # Former Temp10GDB
        Final_10m = os.path.join(OutputDIR, "Final_10m.gdb/") # Former Final_10m
        Final_1m = os.path.join(OutputDIR, "Final_1m.gdb/") # Former LuGDB

        if not arcpy.Exists(Temp_1m):
            arcpy.CreateFileGDB_management(OutputDIR, "Temp_1m.gdb")
        if not arcpy.Exists(Temp_10m):
            arcpy.CreateFileGDB_management(OutputDIR, "Temp_10m.gdb")
        if not arcpy.Exists(Final_10m):
            arcpy.CreateFileGDB_management(OutputDIR, "Final_10m.gdb")
        if not arcpy.Exists(Final_1m):
            arcpy.CreateFileGDB_management(OutputDIR, "Final_1m.gdb")
            arcpy.Copy_management(Inputs + CoName + "_IR_1m", Final_1m + CoName + "_IR_1m")
            arcpy.Copy_management(Inputs + CoName + "_INR_1m", Final_1m + CoName + "_INR_1m")
            arcpy.Copy_management(Inputs + CoName + "_TCoI_1m", Final_1m + CoName + "_TCoI_1m")
            arcpy.Copy_management(Inputs + CoName + "_WAT_1m", Final_1m + CoName + "_WAT_1m")
            arcpy.Copy_management(Inputs + CoName + "_LC", Final_1m + CoName + "_LandCover")

        arcpy.env.overwriteOutput = True
        coord_data = Inputs + CoName + "_Snap"
        arcpy.env.outputCoordinateSystem = arcpy.Describe(coord_data).spatialReference
        arcpy.env.workspace = Temp_1m
        arcpy.env.scratchWorkspace = Temp_1m
        arcpy.env.extent = os.path.join(str(Final_1m) + str(CoName) + "_IR_1m")
        arcpy.env.parallelProcessingFactor = "100%"
        arcpy.env.snapRaster = str(Final_1m) + str(CoName) + "_IR_1m" #location of the default snap raster

        # Local variables:
        BAR = os.path.join(str(Inputs) + str(CoName) + "_Barren")
        BEACH = os.path.join(str(Inputs) + str(Inputs),str(CoName) + "_MOBeach")
        cc_wetlands = os.path.join(str(Inputs), str(CoName) +"_WL")
        crpCDL = os.path.join(str(Inputs) + str(CoName) + "_crpCDL")
        DEMstrm = os.path.join(str(Inputs) + str(CoName) + "_Stream")
        DEV_UAC = os.path.join(str(Inputs) + str(CoName) + "_DEV_UAC")
        DEV113 = os.path.join(str(Inputs) + str(CoName) + "_DEV113")
        DEV37 = os.path.join(str(Inputs) + str(CoName) + "_DEV37")
        DEV27 = os.path.join(str(Inputs) + str(CoName) + "_DEV27")
        DEV18 = os.path.join(str(Inputs) + str(CoName) + "_DEV18")
        fc_Tidal = os.path.join(str(Inputs), str(CoName) +"_mask_tidal")
        fc_FPlain = os.path.join(str(Inputs), str(CoName) +"_mask_fplain")
        fc_OTHWL = os.path.join(str(Inputs), str(CoName) +"_mask_oth_wl")
        FEDS_sm = os.path.join(str(Inputs) + str(CoName) + "_FedPark_small")
        FEDS_med = os.path.join(str(Inputs) + str(CoName) + "_FedPark_medium")
        FEDS_lrg = os.path.join(str(Inputs) + str(CoName) + "_FedPark_large")
        FINR_LU = os.path.join(str(Inputs) + str(CoName) + "_FracINR")
        FTG_LU = os.path.join(str(Inputs) + str(CoName) + "_FracTG")
        INST = os.path.join(str(Inputs) + str(CoName) + "_TurfNT")
        T_LANDUSE = os.path.join(str(Inputs) + str(CoName) + "_TgLU")
        M_LANDUSE = os.path.join(str(Inputs) + str(CoName) + "_MoLU")
        LV = os.path.join(str(Inputs) + str(CoName) + "_LV")
        MINE = os.path.join(str(Inputs) + str(CoName) + "_ExtLFill")
        nwi_Tidal = os.path.join(str(Inputs), str(CoName) +"_Tidal")
        nwi_FPlain = os.path.join(str(Inputs), str(CoName) +"_NTFPW")
        nwi_OTHWL = os.path.join(str(Inputs), str(CoName) +"_OtherWL")
        PARCELS = os.path.join(str(Inputs) + str(CoName) + "_Parcels")
        pa_wetlands = os.path.join(str(Inputs), str(CoName) +"_PA_wet")
        pasCDL = os.path.join(str(Inputs) + str(CoName) + "_pasCDL")
        ROW = os.path.join(str(Inputs) + str(CoName) + "_RoW")
        SS = os.path.join(str(Inputs),str(CoName) + "_SS")
        TC = os.path.join(str(Inputs) + str(CoName) + "_TC")
        Snap = os.path.join(str(Inputs) + str(CoName) + "_Snap")

        # 1 meter LU Rasters - Listed in Hierarchical Order:
        IR = os.path.join(str(Final_1m) + str(CoName) + "_IR_1m")
        INR = os.path.join(str(Final_1m) + str(CoName) + "_INR_1m")
        TCI = os.path.join(str(Final_1m) + str(CoName) + "_TCoI_1m")
        WAT = os.path.join(str(Final_1m) + str(CoName) + "_WAT_1m")
        WLT = os.path.join(str(Final_1m) + str(CoName) + "_WLT_1m")
        WLF = os.path.join(str(Final_1m) + str(CoName) + "_WLF_1m")
        WLO = os.path.join(str(Final_1m) + str(CoName) + "_WLO_1m")
        FOR = os.path.join(str(Final_1m) + str(CoName) + "_FOR_1m")
        TCT = os.path.join(str(Final_1m) + str(CoName) + "_TCT_1m")
        MO = os.path.join(str(Final_1m) + str(CoName) + "_MO_1m")
        FTG1 = os.path.join(str(Final_1m) + str(CoName) + "_FTG1_1m")
        FTG2 = os.path.join(str(Final_1m) + str(CoName) + "_FTG2_1m")
        FTG3 = os.path.join(str(Final_1m) + str(CoName) + "_FTG3_1m")
        FINR = os.path.join(str(Final_1m) + str(CoName) + "_FINR_1m")
        TG = os.path.join(str(Final_1m) + str(CoName) + "_TG_1m")

        # Temporary Datasets
        CDEdge = os.path.join(str(Temp_1m) + str(CoName) + "_EDGE")
        EDGE = os.path.join(str(Temp_1m) + str(CoName) + "_EDGE")
        FINRtemp = os.path.join(str(Temp_1m) + str(CoName) + "_FINRtemp")
        FTGMask = os.path.join(str(Temp_1m) + str(CoName) + "_FTGmask")
        FTGparcels = os.path.join(str(Temp_1m),str(CoName) + "_FTG_parcels")
        FTGtemp = os.path.join(str(Temp_1m) + str(CoName) + "_FTGtemp")
        FTGtemp2 = os.path.join(str(Temp_1m) + str(CoName) + "_FTGtemp2")
        FTGtemp3 = os.path.join(str(Temp_1m) + str(CoName) + "_FTGtemp3")
        HERB = os.path.join(str(Temp_1m) + str(CoName) + "_Herb")
        INRmask = os.path.join(str(Temp_1m),str(CoName) + "_INRmask")
        MOherb = os.path.join(str(Temp_1m) + str(CoName) + "_MOherb")
        POT_FOR = os.path.join(str(Temp_1m),str(CoName) + "_potFOR")
        RLTCP = os.path.join(str(Temp_1m) + str(CoName) + "_RLTCP")
        RTmask = os.path.join(str(Temp_1m) + str(CoName) + "_RTmask")
        RURmask = os.path.join(str(Temp_1m) + str(CoName) + "_RURmask")
        TGMask = os.path.join(str(Temp_1m) + str(CoName) + "_TGmask")
        TURFparcels = os.path.join(str(Temp_1m),str(CoName) + "_TURF_parcels")
        TURFtemp = os.path.join(str(Temp_1m) + str(CoName) + "_TURFtemp")
        TREES = os.path.join(str(Temp_1m) + str(CoName) + "_MOTrees")
        URBmask = os.path.join(str(Temp_1m) + str(CoName) + "_URBmask")
        WAT_FOR = os.path.join(str(Temp_1m),str(CoName) + "_watFOR")

        print ("IR", arcpy.Exists(IR))
        print ("INR", arcpy.Exists(INR))
        print ("TCI", arcpy.Exists(TCI))
        print("WAT", arcpy.Exists(WAT))
        print("BAR", arcpy.Exists(BAR))
        print("LV", arcpy.Exists(LV))
        print("SS", arcpy.Exists(SS))
        print("TC", arcpy.Exists(TC))
        print("BAR", arcpy.Exists(BAR))
        print("DEV_UAC", arcpy.Exists(DEV_UAC))
        print("DEV113", arcpy.Exists(DEV113))
        print("DEV37", arcpy.Exists(DEV37))
        print("DEV27", arcpy.Exists(DEV27))
        print("DEV18", arcpy.Exists(DEV18))
        print("FEDS_sm", arcpy.Exists(FEDS_sm))
        print("FEDS_med", arcpy.Exists(FEDS_med))
        print("FEDS_lrg", arcpy.Exists(FEDS_lrg))
        print("BEACH", arcpy.Exists(BEACH))
        print("MINE", arcpy.Exists(MINE))
        print("T_LANDUSE", arcpy.Exists(T_LANDUSE))
        print("M_LANDUSE", arcpy.Exists(M_LANDUSE))
        print("FINR_LU", arcpy.Exists(FINR_LU))
        print("FTG_LU", arcpy.Exists(FTG_LU))
        print("INST", arcpy.Exists(INST))
        print("PARCELS", arcpy.Exists(PARCELS))
        print("ROW", arcpy.Exists(ROW))

        ########################## START ALL MODELS ####################################
        #ALL_start_time = time.time()

        #------------------------- TURF & FRACTIONAL MODELS -----------------------------
        start_time = time.time()
        arcpy.Delete_management(str(Temp_1m) + "Parcel_IMP")
        arcpy.Delete_management(str(Temp_1m) + "Parcel_IMP2")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_INRmask")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_RTmask")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_Parcels_TURFtemp")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_Parcels_TURF")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_TURF_parcels")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_Parcels_FTGtemp")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_Parcels_FTG")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_FTG_parcels")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_TGmask")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_FTGmask")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_TURFtemp")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_FTGtemp")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_FTGtemp2")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_FTGtemp3")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_FINRtemp")
        arcpy.Delete_management(str(Final_1m) + str(CoName) + "_TG_1m")
        arcpy.Delete_management(str(Final_1m) + str(CoName) + "_TCI_1m")
        arcpy.Delete_management(str(Final_1m) + str(CoName) + "_FTG1_1m")
        arcpy.Delete_management(str(Final_1m) + str(CoName) + "_FTG2_1m")
        arcpy.Delete_management(str(Final_1m) + str(CoName) + "_FTG3_1m")
        arcpy.Delete_management(str(Final_1m) + str(CoName) + "_FINR_1m")
        print("--- Removal of TURF & FRAC Duplicate Files Complete %s seconds ---" % (time.time() - start_time))

        # Call each function, passing the necessary variables...
        turf_1(CoName, Temp_1m, INR, IR, INRmask, TCI)
        turf_2(CoName, Temp_1m, HERB, BAR, LV)
        turf_3(CoName, Temp_1m, DEV18, DEV27)

        # # TURF 4: Create Parcel-based Turf and Fractional Turf Masks
        if arcpy.Exists(PARCELS):
            turf_4a(CoName, Temp_1m, PARCELS, IR)
            turf_4b(CoName, Temp_1m, PARCELS)
            turf_4c(CoName, Temp_1m, PARCELS)
            turf_4d(CoName, Temp_1m, DEV_UAC, RTmask, ROW, INST, T_LANDUSE, TURFparcels)
            turf_4e(CoName, Temp_1m, FTG_LU, FEDS_sm, FTGparcels)
        else:
            turf_5a(CoName, Temp_1m, DEV_UAC, RTmask, ROW, INST, T_LANDUSE)
            turf_5b(CoName, Temp_1m, FTG_LU, FEDS_sm)
        turf_6(CoName, Temp_1m, Final_1m, HERB, TGMask, TURFtemp)
        frac_1(CoName, Final_1m, HERB, FTGMask, FTGtemp)
        frac_2(CoName, Final_1m, HERB, FEDS_med, FTGtemp2)
        frac_3(CoName, Final_1m, HERB, FEDS_lrg, FTGtemp3)
        frac_4(CoName, Final_1m, FINR_LU, HERB, FINRtemp)

        # TURF & FRACTIONAL Clean up
        start_time = time.time()
        arcpy.Delete_management(str(Temp_1m) + "Parcel_IMP")
        arcpy.Delete_management(str(Temp_1m) + "Parcel_IMP2")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_RTmask")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_Parcels_TURFtemp")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_Parcels_TURF")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_TURF_parcels")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_Parcels_FTGtemp")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_Parcels_FTG")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_FTG_parcels")
        #arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_TGmask")
        #arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_FTGmask")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_TURFtemp")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_FTGtemp")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_FTGtemp2")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_FTGtemp3")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_FINRtemp")
        print("--- TURF & FRAC Clean Up Complete %s seconds ---" % (time.time() - start_time))

        #--------------------------------FOREST MODEL----------------------------------------
        start_time = time.time()
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_RLTCP")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_EDGE")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_CDEdge")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_URBmask")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_RURmask")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_CDEdge")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_URB_TCT")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_RUR_TCT")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_TCT1")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_nonTCT")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_potFOR")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_NATnhbrs")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_ForRG")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_MOtemp")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_MOspace")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_MOherb")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_MOTrees")
        arcpy.Delete_management(str(Final_1m) + str(CoName) + "_FOR_1m")
        arcpy.Delete_management(str(Final_1m) + str(CoName) + "_MO_1m")

        for_1(CoName, DEV113, TC)
        for_2(CoName, TC, DEV27)
        for_3(CoName, Temp_1m, RLTCP, EDGE)
        for_4(CoName, DEV37, CDEdge)
        for_5(CoName, DEV18, TC)
        for_6(CoName, Temp_1m, Final_1m)
        for_7(CoName, TCT, TC)
        for_8(CoName, Temp_1m, Final_1m, TC, WAT, WLF, WLO, WLT, WAT_FOR, POT_FOR)

        #---------------------------MIXED OPEN MODEL-----------------------------------------------------
        # MO 1: Create Mixed Open with just MOtrees and Scrub-shrub (no ancillary data)
        inrasListMO = [ ]
        if arcpy.Exists(BEACH):
            inrasListMO.append(BEACH)
        if arcpy.Exists(M_LANDUSE):
            inrasListMO.append(M_LANDUSE)
        if arcpy.Exists(MINE):
            inrasListMO.append(MINE)

        if not inrasListMO:

            mo_1(CoName, Temp_1m, Final_1m, TREES, SS)

        else:

            mo_2a(CoName, Temp_1m, inrasListMO)
            mo_2b(CoName, Temp_1m, BAR, HERB, LV)
            mo_2c(CoName, Temp_1m, HERB, MOherb)
            mo_2d(CoName, Temp_1m, Final_1m, MOherb, TREES, SS)

        # FOREST & MIXED OPEN Clean up
        start_time = time.time()
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_RLTCP")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_EDGE")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_CDEdge")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_URBmask")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_RURmask")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_CDEdge")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_URB_TCT")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_RUR_TCT")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_TCT1")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_nonTCT")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_potFOR")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_NATnhbrs")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_ForRG")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_MOtemp")
        #arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_MOspace")
        arcpy.Delete_management(str(Temp_1m) + str(CoName) + "_MOherb")
        print("--- FOREST & MIXED OPEN Clean Up Complete %s seconds ---" % (time.time() - start_time))

        #----------------------FINAL AGGREGATION MODEL-----------------------------------------
        print ("IR", arcpy.Exists(IR))
        print ("INR", arcpy.Exists(INR))
        print ("TCI", arcpy.Exists(TCI))
        print ("WAT", arcpy.Exists(WAT))
        print ("WLT", arcpy.Exists(WLT))
        print ("WLF", arcpy.Exists(WLF))
        print ("WLO", arcpy.Exists(WLO))
        print ("FOR", arcpy.Exists(FOR))
        print ("TCT", arcpy.Exists(TCT))
        print ("MO", arcpy.Exists(MO))
        print ("FTG1", arcpy.Exists(FTG1))
        print ("FTG2", arcpy.Exists(FTG2))
        print ("FTG3", arcpy.Exists(FTG3))
        print ("FINR", arcpy.Exists(FINR))
        print ("TG", arcpy.Exists(TG))

        final_1(CoName, Temp_1m, IR, INR, TCI, WAT, WLT, WLF, WLO, FOR, TCT, MO, FTG1, FTG2, FTG3, FINR, TG)

        final_2(CoName, Temp_1m, Temp_10m, Final_1m, Snap, CntyDIR)

        final_3(CoName, Temp_10m, DEMstrm, crpCDL, pasCDL, Snap)

        final_4(CoName, Temp_10m, FTG1, FTG2, FTG3, FINR, WLT, WLF, WLO, Snap)

        final_5(CoName, Temp_10m, Final_10m, TiffDIR, WLT, WLF, Snap)

        print("--- All Models Complete %s seconds ---" % (time.time() - ALL_start_time))
## #############################################################################
##  <<< END MAIN >>>
## #############################################################################

# Need this to execute main()
if __name__ == "__main__":
    main()
\$\endgroup\$
2
\$\begingroup\$

Main

Use an helper function to separate unit of work. Namely, I would use a function performing the required operations on a county and call it from main.

def main(main_directory="C:/A__P6_GIS4/"):
    if arcpy.CheckExtension("Spatial") != "Available":
        arcpy.AddError("Unable to get spatial analyst extension")
        arcpy.AddMessage(arcpy.GetMessages(0))
        sys.exit(1)
    arcpy.AddMessage("Checking out Spatial")
    arcpy.CheckOutExtension("Spatial")

    for county in os.listdir(main_directory):
        manage_county(main_directory, county)

And that's all you need in your main. Separating this manage_county function into turf, forest, mixed and final subfunctions could be a good thing to do too.

A few things to note:

  • sys.exit(0) means there was no error, so better use an exit status of 1 to indicate an error;
  • os.listdir can be used directly to iterate over county directory, there in no need in using a file as buffer;
  • using a parameter with default value can help with reusability/maintenance as the function can easily be tested and such value is not burried within the code;
  • timing and debug printing can be delegated to helper functions/decorators, more on that later.

Manage_county

The main issue with the rest of the code, is the amount of redundant line of code one can read. Once again helper function can help reduce the amount of repetition. Loops are also a great way to perform the same operation on copious amount of filenames.

You should also take some time to remove useless variables, such as BEACH which is defined, printed, tested for existence, but nothing usefull is done with it.

You should also read PEP 8 and the official naming conventions to make the code look like Python code; and avoid needless abreviations in your variable names.

Strings management is also a mess: there is a lot of useless call to str as the variables it is applied to are already strings; os.path.join is mainly applied to a single string, thus it is just noise; and str.format should be prefered to string concatenation.

FEATURE_NAME_PATTERN = '{}/{}_{}'
FEATURE_1M_PATTERN = '{}/{}_{}_1m'


def create_directory(root, directory_name):
    directory = os.path.join(root, directory_name)
    if not arcpy.Exists(directory):
        arcpy.CreateFolder_management(root, directory_name)
    return directory


def create_geodatabase(root, filename):
    file_name = os.path.join(root, filename)
    created = False
    if not arcpy.Exists(file_name):
        arcpy.CreateFileGDB_management(root, filename)
        created = True
    return file_name


def manage_county(root, county_name):
    county_directory = os.path.join(root, county_name)
    output_directory = create_directory(county_directory, 'Outputs')
    tiff_directory = create_directory(output_directory, county_name + '_FINAL')

    imputs = os.path.join(county_directory, county_name + '_Inputs.gdb') # Former CoGDB
    temp_1m, _ = create_geodatabase(output_directory, 'Temp_1m.gdb') # Former TempGDB
    temp_10m, _ = create_geodatabase(output_directory, 'Temp_10m.gdb') # Former Temp10GDB
    final_10m, _ = create_geodatabase(output_directory, 'Final_10m.gdb') # Former Final_10m
    final_1m, created = create_geodatabase(output_directory, 'Final_1m.gdb') # Former LuGDB
    if created:
        for feature in ['IR', 'INR', 'TCoI', 'WAT']:
            feature_in = FEATURE_1M_PATTERN.format(inputs, county_name, feature)
            feature_out = FEATURE_1M_PATTERN.format(final_1m, county_name, feature)
            arcpy.Copy_management(feature_in, feature_out)
        arcpy.Copy_management(
            FEATURE_NAME_PATTERN.format(inputs, county_name, 'LC'),
            FEATURE_NAME_PATTERN.format(final_1m, county_name, 'LandCover'))

    arcpy.env.overwriteOutput = True
    coord_data = FEATURE_NAME_PATTERN.format(inputs, county_name, 'Snap')
    ir_1m_path = FEATURE_1M_PATTERN.format(final_1m, county_name, 'IR')
    arcpy.env.outputCoordinateSystem = arcpy.Describe(coord_data).spatialReference
    arcpy.env.workspace = temp_1m
    arcpy.env.scratchWorkspace = temp_1m
    arcpy.env.extent = ir_1m_path
    arcpy.env.parallelProcessingFactor = "100%"
    arcpy.env.snapRaster = ir_1m_path  #location of the default snap raster

    #------------------------- TURF & FRACTIONAL MODELS -----------------------------
    for parcel in ['IMP', 'IMP2']:
        arcpy.Delete_management('{}/Parcel_{}'.format(temp_1m, parcel))
    for feature in ['INRmask', 'RTmask', 'Parcels_TURFtemp', 'Parcels_TURF', 'TURF_parcels', 'Parcels_FTGtemp', 'Parcels_FTG', 'FTG_parcels', 'TGmask', 'FTGmask', 'TURFtemp', 'FTGtemp', 'FTGtemp2', 'FTGtemp3', 'FINRtemp']:
        arcpy.Delete_management(FEATURE_NAME_PATTERN.format(temp_1m, county_name, feature))
    for feature in ['TG', 'TCI', 'FTG1', 'FTG2', 'FTG3', 'FINR']:
        arcpy.Delete_management(FEATURE_1M_PATTERN.format(final_1m, county_name, feature))

    # Call each function, passing the necessary variables...
    turf_1(final_1m, county_name, temp_1m)
    turf_2(inputs, county_name, temp_1m)
    turf_3(inputs, county_name, temp_1m)
    # # TURF 4: Create Parcel-based Turf and Fractional Turf Masks
    if arcpy.Exists('{}/{}_Parcels'.format(inputs, county_name)):
        turf_4a(inputs, county_name, temp_1m, final_1m)
        turf_4b(inputs, county_name, temp_1m)
        turf_4c(inputs, county_name, temp_1m)
        turf_4d(inputs, county_name, temp_1m)
        turf_4e(inputs, county_name, temp_1m)
    else:
        turf_5a(inputs, county_name, temp_1m)
        turf_5b(inputs, county_name, temp_1m)
    turf_6(inputs, county_name, temp_1m, final_1m)
    frac_1(inputs, county_name, final_1m)
    frac_2(inputs, county_name, final_1m)
    frac_3(inputs, county_name, final_1m)
    frac_4(inputs, county_name, final_1m)

    # TURF & FRACTIONAL Clean up
    for parcel in ['IMP', 'IMP2']:
        arcpy.Delete_management('{}/Parcel_{}'.format(temp_1m, parcel))
    for feature in ['INRmask', 'RTmask', 'Parcels_TURFtemp', 'Parcels_TURF', 'TURF_parcels', 'Parcels_FTGtemp', 'Parcels_FTG', 'FTG_parcels', 'TGmask', 'FTGmask', 'TURFtemp', 'FTGtemp', 'FTGtemp2', 'FTGtemp3', 'FINRtemp']:
        arcpy.Delete_management(FEATURE_NAME_PATTERN.format(temp_1m, county_name, feature))

    #--------------------------------FOREST MODEL----------------------------------------
    for feature in ['RLTCP', 'EDGE', 'CDEdge', 'URBmask', 'RURmask', 'URB_TCT', 'RUR_TCT', 'TCT1', 'nonTCT', 'potFor', 'NATnhbrs', 'ForRG', 'MOtemp', 'MOspace', 'MOherb', 'MOTrees']:
        arcpy.Delete_management(FEATURE_NAME_PATTERN.format(temp_1m, county_name, feature))
    for feature in ['FOR', 'MO']:
        arcpy.Delete_management(FEATURE_1M_PATTERN.format(final_1m, county_name, feature))

    for_1(inputs, county_name)
    for_2(inputs, county_name)
    for_3(inputs, county_name)
    for_4(inputs, county_name)
    for_5(inputs, county_name)
    for_6(inputs, county_name, temp_1m, final_1m)
    for_7(inputs, county_name)
    for_8(inputs, county_name, temp_1m, final_1m)

    #---------------------------MIXED OPEN MODEL-----------------------------------------------------
    # MO 1: Create Mixed Open with just MOtrees and Scrub-shrub (no ancillary data)
    inras_list_MO = [
        name for name in ['MOBeach', 'MoLU', 'ExtLFill']
        if arcpy.Exists(FEATURE_NAME_PATTERN.format(inputs, county_name, name))
    ]

    if not inrasListMO:
        mo_1(inputs, county_name, temp_1m, final_1m)
    else:
        mo_2a(inputs, county_name, temp_1m, inras_list_MO)
        mo_2b(inputs, county_name, temp_1m)
        mo_2c(inputs, county_name, temp_1m)
        mo_2d(inputs, county_name, temp_1m, final_1m)

    # FOREST & MIXED OPEN Clean up
    for feature in ['RLTCP', 'EDGE', 'CDEdge', 'URBmask', 'RURmask', 'URB_TCT', 'RUR_TCT', 'TCT1', 'nonTCT', 'potFor', 'NATnhbrs', 'ForRG', 'MOtemp', 'MOspace', 'MOherb', 'MOTrees']:
        arcpy.Delete_management(FEATURE_NAME_PATTERN.format(temp_1m, county_name, feature))

    #----------------------FINAL AGGREGATION MODEL-----------------------------------------
    final_1(inputs, county_name, temp_1m)
    final_2(inputs, county_name, temp_1m, temp_10m, final_1m, county_directory)
    final_3(inputs, county_name, temp_10m)
    final_4(inputs, county_name, temp_10m)
    final_5(inputs, county_name, temp_10m, final_10m)

You’ll see that there is still some repetitions, especially when deleting features from temp_1m before and after computations. But they are handled with less verbosity. However, I don't find any advantage in removing them both before and after. Either you let the file clean for the next computation, or you clean it before your own, but doing both is counter productive as one of them will yield no results. Instead, I recommend only deleting before your computation to start from a clean state and let the next computation perform its own cleanup when necessary.

You’ll also note that I removed most of the parameters from each intermediate calls. This is because they are variable that are unnecessary for this function. Instead, it is better to define them at the beginning of each of your helper functions. This is also the reason I added inputs and final_1m (but I might have missed some) as first parameter for each of the calls. For instance, the first lines of turf_1 can become:

def turf_1(final_1m, county_name, temp_1m):
    INRmask = FEATURE_NAME_PATTERN.format(temp_1m, county_name, 'INRmask')
    IR = FEATURE_1M_PATTERN.format(final_1m, county_name, 'IR')
    INR = FEATURE_1M_PATTERN.format(final_1m, county_name, 'INR')
    TCI = FEATURE_1M_PATTERN.format(final_1m, county_name, 'TCoI')
    ...

Timing and debug prints

Even though debug prints inform the user that something is going on, they disturb for development and maintenance purpose. Instead, you could reduce the amount of information printed and rely on an helper function to time the execution:

import time
from functools import wraps


def timer(func):
    @wraps(func)
    def wrapper(*args):
        start = time.time()  # or time.perf_counter() in Python 3
        print 'Starting', func.__name__, args
        func(*args)
        end = time.time()  # or time.perf_counter()
        print 'Computation time:', end - start

Usage being:

@timer
def manage_county(root, county_name):
    # rest of the code

And you can decorate other functions as well to get outputs more often.

\$\endgroup\$
  • \$\begingroup\$ This is pretty comprehensive. I will be working on your edits this week. Are we allowed to share our edited/modified code after review to make sure I'm going in the right direction? \$\endgroup\$ – cptpython Dec 13 '16 at 13:37
  • \$\begingroup\$ @cptpython What you may and may not do after receiving answers \$\endgroup\$ – Mathias Ettinger Dec 13 '16 at 13:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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