Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I'm just starting to get into Python scripting for work..

I'm currently creating a script to automate a process.

Basically, it asks the user the client name, gets a projection if available, creates directory on C: drive for client, creates file geodatabase specific to client, creates required dataset, and creates feature classes specific to clients data. Eventually, it will also add the required fields to each feature class and probably some other things.

I started this not really knowing the proper etiquette of Python scripting for ArcMap. But what I've created so far will only run outside ArcMap I believe. Is this acceptable? Instead of getting user input through arcpy.getparamaterastext(), which I just found out about, I'm using raw_input(). Is this okay? It does work, I'm just not sure if this is a proper way to do scripting.

Here's the code I have so far, PLEASE give me any pointers that you may recognize.

import sys
import arcpy
import os

#Records name of the client
client = raw_input("Enter the name of the client: (letters and underscores only) \n")

#Records filepath of client to be created
clientpath = "C:/" + client

#Inquires if projection file exists
projection = raw_input("Is there a .prj or .shp available with correct projection? Y or N \n")

#Records the projection location if available
if projection.upper() == "Y":
    spatialr = raw_input("Drag the .prj or .shp here to record the filepath \n")
    nspatialr = spatialr.replace('"', "")
elif projection.upper() == "N":
    alert = raw_input("You must add the spatial reference manually, hit enter to continue. \n")
elif projection.upper() != "N" or "Y":
    exit = raw_input("That is not a valid response. Try again. \n")
    sys.exit()

#Checks if client folder exists; if not, creates one
if not os.path.exists(clientpath):
    os.makedirs(clientpath)

#Variable for file geodatabase location
FGBpath = clientpath + "/" + client + ".gdb"

#Checks if client file geodatabase exists; if not, creates one
if not arcpy.Exists(FGBpath):
    arcpy.CreateFileGDB_management(clientpath, client)

#Variable for dataset location
FDatasetpath = clientpath + "/" + client + ".gdb" + "/Network"

#Checks if dataset exists; if not, creates one
if not arcpy.Exists(FDatasetpath):
    if projection.upper() == "Y":
        arcpy.CreateFeatureDataset_management(FGBpath, "Network", nspatialr)
    elif projection.upper() == "N":
        arcpy.CreateFeatureDataset_management(FGBpath, "Network")

#Variable for cable feature class location
FCcablepath = clientpath + "/" + client + ".gdb" + "/Network" + "/cable"

#Checks if cable feature class exists; if not, creates one
if not arcpy.Exists(FCcablepath):
    if projection.upper() == "Y":
        arcpy.CreateFeatureclass_management (FDatasetpath, "cable", "POLYLINE", "", "", "", nspatialr)
    elif projection.upper() == "N":
        arcpy.CreateFeatureclass_management (FDatasetpath, "cable", "POLYLINE")

#Variable for splice point feature class location
FCsplicepath = clientpath + "/" + client + ".gdb" + "/Network" + "/splice_point"

#Checks if splice point feature class exists; if not, creates one
if not arcpy.Exists(FCsplicepath):
    if projection == 'Y' or projection == 'y':
        arcpy.CreateFeatureclass_management (FDatasetpath, "splice_point", "POINT", "", "", "", nspatialr)
    elif projection == 'N' or projection == 'n':
        arcpy.CreateFeatureclass_management (FDatasetpath, "splice_point", "POINT")

exit = raw_input("\n\n File geodatabase, dataset, and the cable \n and splice point feature classes successfully created. \n\n Hit enter to exit.")

I still have some work to do, like adding the needed fields.

Any tips would be much appreciated!

share|improve this question

2 Answers 2

up vote 13 down vote accepted

First of all, I see you made your way here from reddit... I thought I recognized this script. Welcome!

How you get your inputs depends 100% on who the end user will be, but you're right, you won't be able to use raw_input in ArcMap at all. If you are going to be the only one using the script, there's nothing wrong with getting your inputs through raw_input, or hard coding paths as variables into your script. However, if anyone else will be using the script that may or may not have any scripting experience, it is best to use getParameterAsText() and implement your script as a script tool in ArcMap. Creating a script tool will give the user an interface that is similar to the one used by most ESRI tools (such as standard tools like buffer, etc...).

One thing to point out is that the way you have your raw_inputs designed creates a step by step interaction between the user and the script. If this is run using getParameterAsText() in ArcMap, the step by step will go away, and it will just be a series of settings that are input prior to running the script.

One of the main purposes for scripting is automation. If you are going to be running this on multiple datasets, you should check out loops. If you've come this far, you've probably read about them at least, but as an example for how you could use them: say you have multiple datasets that you need to perform the same operation on. You can write the code for the processes that need to be accomplished once, then include a 'for' loop that takes a list of datasets and performs the operation on each of them.

For things like spatial reference, you can 'steal' a spatial reference from an existing shapefile using arcpy.Describe() , or you can get a spatial reference input using getParameterAsText() (as long as you define the parameter as a spatial reference input when setting up the script tool). Using raw_input to get path names is a bit cumbersome.

share|improve this answer
3  
+1, I would definitely switch over to taking parameters vs. raw_input. Not many end users will want to use a command line interface vs. a GUI, especially when they are used to something like ArcGIS's geoprocessing tools. –  blah238 Oct 22 '12 at 22:39
    
You're good. Thanks for the reply ... again. This script will only be used by me or a coworker, so there should be no problem using the command line for this one. But, I think I will try to replicate it using a script tool for practice. Thanks for showing me the describe() function and loops are next on my list. PS- I'd give you an upvote, but I'm too much of a noob to even do that (: –  ian Oct 22 '12 at 23:16

In addition to @egdetti's great suggestions, you can greatly simplify your script by making some assumptions instead of writing if/else logic for every little condition.

For example:

  • Instead of checking whether each item exists beforehand, just assume it does and overwrite it by setting arcpy.env.overwriteOutput = True. Now you may have some reason why you need to check beforehand but more often than not overwriting is fine.

  • Instead of checking whether the spatial reference option was set, and calling the same command two different ways, just pass the spatial reference variable to the command once and let it handle null or empty strings (which it will just fine).

  • Use os.path.join to join file path elements instead of using string concatenation, which is fraught with perils.

    E.g. instead of:

    FGBpath = clientpath + "/" + client + ".gdb"
    

    Use:

    FGBpath = os.path.join(clientpath, client + ".gdb")
    
share|improve this answer
    
Awesome! Just the kind of tips I was looking for, thanks! Do you know of any type of list that shows the most common functions/libraries people use? Such as the os.path.join? There are so many that it's kind of overwhelming. I'd +1 you if I could. They should allow me to upvote questions, just not downvote them! –  ian Oct 22 '12 at 23:07
2  
I assume you've already gone through the official Python tutorial? It has handy sections (1, 2) on the standard library. Another good resource is Doug Hellmann's Module of the Week list: doughellmann.com/PyMOTW/contents.html –  blah238 Oct 22 '12 at 23:13
    
Also, better to be overwhelmed than underwhelmed, I say! –  blah238 Oct 22 '12 at 23:14
    
Well, I hate to admit it, but I haven't gone through the tutorial yet. I kind of just jumped into it. I took a C++ class years ago, so I kind of know the basics but I definitely need to thoroughly look through the tutorial. I've always been a dive in head first kind of person. Thanks for the links. –  ian Oct 22 '12 at 23:19
    
You might like diveintopython.net too, then :) –  blah238 Oct 22 '12 at 23:30

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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