0

I have a ModelBuilder process that I am converting to python for additional editing. In the process I have both a point and line features(input variables) being buffered and then the resulting polygons merged into a single feature for additional processes. But I want to make the model more versatile so it will run if only one of the inputs (point OR lines) is supplied. Currently it crashes if only one input is supplied. Is there a way to direct the model so that if only one input is provided, it skips the merge step (or successfully merges with null) and then goes to the subsequent steps.

Here's my code:

# Process: Buffer (6)
arcpy.Buffer_analysis(in_points_shp, point_buffer_shp, "buffer", "FULL", "ROUND", "NONE", "", "PLANAR")

# Process: Buffer (11)
arcpy.Buffer_analysis(in_LINE_shp, line_buffer_shp, "buffer", "FULL", "ROUND", "NONE", "", "PLANAR")

# Process: Merge (2)
arcpy.Merge_management("Z:\\supporting_docs\\point_buffer.shp;Z:\\supporting_docs\\line_buffer.shp", merge_output_shp,

...merge output then goes on to other processes. My python skills are currently zero.

1
  • So your end goal is to run this via script tool (that will grab the various input parameters) which will call the python script?
    – artwork21
    Feb 6 '15 at 21:57
1

There are at least two things you could do.

You could define default values for your parameters, and then, if the default does not occur you will execute a certain piece of code.

For example, let's say the first parameter asks for a Point. If the first parameter was entered then it will not be default, so you can go ahead and execute a piece of code (I just used print statements for simplicity, of course you would include your real code instead):

def printSomething(a="default", b="default"):
    if a != "default" and b != "default":
        print a + b
    elif a != "default":
        print a
    else:
        print b

Or you could use something like *args. It might be the "better" approach but that might be a little harder to set up.

Surely there will be other ways, but I think that the first one should be easy to implement and would work fine.

2
  • Thanks, But I'm extremely limited in my Python. Not trying to ask you to do my work for me, but.... With the below Test_line and Test_points as my inputs, what would that look like in reality? # Process: Buffer (6) arcpy.Buffer_analysis(test_points_shp, test_pointsB_shp, "buffer", "FULL", "ROUND", "NONE", "", "PLANAR") # Process: Buffer (11) arcpy.Buffer_analysis(test_LINE_shp, test_linesB_shp, "buffer", "FULL", "ROUND", "NONE", "", "PLANAR")
    – Mike
    Feb 6 '15 at 22:14
  • @Mike Rather than trying to place Python code in a comment you could use the edit button below your question to format it using the {} button, and thus improve your question at the same time.
    – PolyGeo
    Feb 6 '15 at 22:20
1

OK, I see you revised your question a bit.

This script should get you most of the way there. The script will take a list of shapefiles and if there are more than 1 found in the list, it will buffer each shapefile and do a merge. If only one is found, it will only do the buffer.

Just put in your own list of shapefiles in the main function.

import arcpy
import sys
import os

def multibuffer(shapefile_list):

    if len(shapefile_list) == 1:
        dirname = os.path.dirname(shapefile_list[0])
        basename = os.path.basename(shapefile_list[0])
        output_basename = os.path.splitext(basename)[0] + '_buffer' +  os.path.splitext(basename)[1]
        output_filename = os.path.join(dirname, output_basename)

        # You would do your buffer here set your buffer distance to a field or value
        arcpy.Buffer_analysis(shapefile_list[0], output_filename, 5)
        arcpy.AddMessage('Output: {0}'.format(output_filename))
        print 'Output:', output_filename

    elif len(shapefile_list) > 1:
        buffered_shapefile_list = []
        for shapefile in shapefile_list:
            dirname = os.path.dirname(shapefile)
            basename = os.path.basename(shapefile)
            output_basename = os.path.splitext(basename)[0] + '_buffer' +  os.path.splitext(basename)[1]
            output_filename = os.path.join(dirname, output_basename)

            # You would do your buffer here, set your buffer distance to a field or value
            arcpy.Buffer_analysis(shapefile, output_filename, 5)

            # Append the outputs to a list.
            buffered_shapefile_list.append(output_filename)
            arcpy.AddMessage('Output: {0}'.format(output_filename))
            print 'Output:', output_filename

        # Merge buffered shapefiles
        # Pass in list of buffered shapefiles
        # Merge file will be created in directory of last shapefile buffered
        arcpy.Merge_management(buffered_shapefile_list, os.path.join(dirname, 'merged_buffer.shp'))

        arcpy.AddMessage('Buffered files to merge: {0}'.format(str(buffered_shapefile_list)))
        arcpy.AddMessage('Merged file: {0}: '.format(os.path.join(dirname, 'merged_buffer.shp')))
        print 'Buffered files to merge: {0}'.format(str(buffered_shapefile_list))
        print 'Merged file: {0}: '.format(os.path.join(dirname, 'merged_buffer.shp'))


    else:
        print 'No shapefiles specified'


def main():
    #put in list of shapefiles with fill paths
    shapefile_list = ['C:/data/point.shp', 'C:/data/line.shp', 'C:/data/point_2.shp']

    multibuffer(shapefile_list)

if __name__ == '__main__':
    main()

Along the line of what BritishSteel suggested with *args:

You can pass in a set of key-values. Write a function that accepts **kwargs and pass in a dict with your key-value pairs.

# intertools modules required
import itertools

# function that accepts key-value pairs
def show_elevation_temperature(**kwargs):
    for key, value in kwargs.iteritems():
        print 'Key:{0} Value:{1}'.format(key, value)

def main():
    key_values = {'1700': '0',
                  '2500': '-1',
                  '4000': '-2'
                 }

    # call the function and pass in the dict
    show_elevation_temperature(**key_values)

if __name__ == '__main__':
    main()

The output from the funtion above should show:

Key:1700 Value:0
Key:4000 Value:-2
Key:2500 Value:-1

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.