1

I am working with another user, and our previous question was Formatting dependent parameters in Python Toolbox?

We gave up on trying to auto populate the drop down and instead are having the user input which band(s) they would like to explode. Everything works except when we try to break the tool by not selecting any output format type. We want an error message to occur when this happens, but we have other problems in the code preventing us from seeing the error message. But these problems don't affect the tool's running if we select the output format.

The error we get is:

UnboundLocalError: local variable 'assignment' referenced before assignment.

Here is all of the code we have tried. We tried adding global in front of our variable, but that didn't work.

import arcpy,os,sys,string


class Toolbox(object):
def __init__(self):
    self.label =  "Exploding Rasters"
    self.alias  = "ER"

    # List of tool classes associated with this toolbox
    self.tools = [ExplodeRasters]





class ExplodeRasters(object):
def __init__(self):
    self.label       = "Explode Rasters"
    self.description = " This tool will take an input multiband raster and " +\
                       " extract all of its individual bands, saving these " +\
                       " bands as separate single band rasters.Exploding Rasters" + \
                       " tool is everythying you've ever hoped for and dreamed of." + \
                       "  It's perfection."




def getParameterInfo(self):

    # Input Features parameter
    in_features = arcpy.Parameter(
        displayName="Input Raster",
        name="in_features",
        datatype="DERasterDataset",
        parameterType="Required",
        direction="Input")

    # create select all bands button
    all_bands = arcpy.Parameter(
        displayName="Select all bands",
        name="Select_All",
        datatype="Boolean",
        parameterType="Required",
        direction="Input")

#Raster types options
    TIFF = arcpy.Parameter(
        displayName="TIFF",
        name ="TIFF",
        datatype="Boolean",
        parameterType="Optional",
        direction="Input")
    BMP = arcpy.Parameter(
        displayName="BMP",
        name="bmp",
        datatype="Boolean",
        parameterType="Optional",
        direction="Input")
    PNG = arcpy.Parameter(
        displayName="PNG",
        name="png",
        datatype="Boolean",
        parameterType="Optional",
        direction="Input")

    # Range of Desired Bands parameter
    select_bands = arcpy.Parameter(
        displayName="Select Bands",
        name="Select_Bands",
        datatype="String",
        parameterType="Optional",
        direction="Input")


    #select bands for NDVI band parameters
    NDVI_red = arcpy.Parameter(
        displayName="Select a red band for NDVI calculation",
        name="NDVI_bRed",
        datatype="DERasterDataset",
        parameterType="Optional",
        direction="Input")

    NDVI_NIR = arcpy.Parameter(
        displayName="Select a NIR band for NDVI calculation",
        name="NDVI_BNIR",
        datatype="DERasterDataset",
        parameterType="Optional",
        direction="Input")

    #out directory
    OutDir = arcpy.Parameter(
        displayName="Output Workspace",
        name="Out_Directory",
        datatype="DEWorkspace",
        parameterType="Required",
        direction="Input")

    # Create filename output prefix
    prefix = arcpy.Parameter(
        displayName="Output filename prefix",
        name="output_prefix",
        datatype="GPString",
        parameterType="Required",
        direction="Input")

    parameters = [in_features, all_bands, select_bands, NDVI_red, NDVI_NIR, prefix, OutDir, TIFF, BMP, PNG]

    return parameters




def execute(self, parameters, messages):
    in_raster=parameters[0].valueAsText
    ALL = parameters[1].valueAsText
    Bands = parameters[2].valueAsText
    Red = parameters[3].valueAsText
    NIR = parameters[4].valueAsText
    prefix = parameters[5].valueAsText
    Out_Dir = parameters[6].valueAsText
    TIFF = parameters[7].valueAsText
    BMP = parameters[8].valueAsText
    PNG = parameters[9].valueAsText
    messages.addMessage(Bands)


    messages.addMessage("INPUT RASTER=" +in_raster)
    messages.addMessage("\n" + "Yay, you're doing great!") #necessary encouragement for users


    arcpy.env.workspace=in_raster
    arcpy.env.overwriteOutput = True



    if TIFF == "true": #output tif if TIF box is checked
        assignment = ".tif"
        ending = "TIFF"

    if BMP == "true": #output bmp if BMP box is checked
        assignment = ".bmp"
        ending = "BMP"

    if PNG == "true": #output png if PNG box is checked
        assignment = ".png"
        ending = "PNG"

    if TIFF and BMP and PNG == "false":
        messages.addWarningMessage("You forgot to select an extension.")


    if ALL == "true":
        ListBandNames = arcpy.ListRasters()
        for band in ListBandNames:
            bndDesc = arcpy.Describe(band)
            NoData = bndDesc.noDataValue
            outRaster = os.path.join(Out_Dir, prefix + band + assignment)
            arcpy.CopyRaster_management(band, outRaster, format = ending, nodata_value = NoData)

    elif parameters[2].value:
        bands_in_input = []
        ListBandNames = arcpy.ListRasters()
        for band in ListBandNames:
            bndDesc = arcpy.Describe(band)
            bands_in_input.append(band)
            NoData = bndDesc.noDataValue

        UserInput_Select = Bands.split(",")
        UpdatedInput =["Band_" + band for band in UserInput_Select]

        result = []
        for element in bands_in_input:
            if element in UpdatedInput:
                result.append(element)
                outRaster = os.path.join(Out_Dir, prefix + element + assignment)
                arcpy.CopyRaster_management(element, outRaster, format = ending, nodata_value = NoData)             

    else:
        messages.addMessage("No Output Format Selected")

    return
1
  • 1
    You need declare assignmentfor example to "" empty string before you call it,for example put assignment=""before if TIFF == "true"
    – Fran Raga
    Commented Dec 11, 2017 at 7:29

1 Answer 1

1

It depends on what you're trying to do.

if TIFF and BMP and PNG == "false":

That line doesn't do what I think you want. It will evaluate to True if:

  • TIFF is anything other than 0, None, or False,
  • BMP is anything other than 0, None, or False,
  • and PNG is the string "false"

If you wish to add a warning message when all three of those variables are the string "false", then it should read:

if TIFF == 'false' and BMP == 'false' and PNG == "false":

But I don't think you even need that. Instead, the entire block should be:

    if TIFF == "true": #output tif if TIF box is checked
        assignment = ".tif"
        ending = "TIFF"
    elif BMP == "true": #output bmp if BMP box is checked
        assignment = ".bmp"
        ending = "BMP"
    elif PNG == "true": #output png if PNG box is checked
        assignment = ".png"
        ending = "PNG"
    else:
        messages.addWarningMessage("You forgot to select an extension.")

But (and this is where you're error is coming from), you also need to decide what else to do when no output format is selected. Do you want to default to one of the options, or do you want to raise an exception? As it is, if the user didn't select a raster format, the script continues on but without an assignment or an ending.

I'd suggest defaulting:

if BMP == "true":
    assignment = ".bmp"
    ending = "BMP"
elif PNG == "true":
    assignment = ".png"
    ending = "PNG"
else:
    messages.addWarningMessage("You forgot to select an extension. The process will default to using the TIFF format.")
    assignment = '.tif'
    ending = 'TIFF'
2
  • Thank you, Tom! That was very helpful. With your default suggestion, there us no code for if the user wanted to select TIFF and remembered to check off the box. I'll try adding the code for if TIFF and then changing if BMP to elif BMP. Thank you again! Commented Dec 12, 2017 at 3:51
  • @CarlyR, yes, the default was just an example. It depends on what exactly you want. As it is, it will use TIFF if they selected tif (or if they selected nothing), but only if they didn't also select bmp or png. Ideally, this would be radials or a drop-down. They shouldn't have the option to select more than one.
    – Tom
    Commented Dec 12, 2017 at 20:00

Your Answer

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

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