Convert python script to ArcMap Script tool

4345
8
03-16-2011 12:55 PM
KurtEdwards
New Contributor
I am new to using python scripting and need help making my python script into a script tool.  My script converts area measurments into other area units.  It runs fine in pythonwin and gives me correct output but when I try to attach it to a script tool it just bombs.  I could use all the help that anybody would be willing to give me.  Below is my coding for the conversions.  Thanks.

#create an empty dictionary
areaD = {}
# populate dictionary using indexing and assignment with units and conversion factors relative to sqmeter = 1.0
# to convert x sqmeters to any of the other area units multiply by the factor
# to convert x of any of the other area units to sqmeter divide by the factor
# to convert x of any area unit to any of the other area units go over interim sqmeter
# this minimizes the total number of conversion factors
areaD['sqmeter']      = 1.0
areaD['sqmillimeter'] = 1000000.0
areaD['sqcentimeter'] = 10000.0
areaD['sqkilometer']  = 0.000001
areaD['hectare']      = 0.0001
areaD['sqinch']       = 1550.003
areaD['sqfoot']       = 10.76391
areaD['sqyard']       = 1.19599
areaD['acre']         = 0.0002471054
areaD['sqmile']       = 0.0000003861022


def convertArea(x, unit1, unit2):
    """area conversion with error trapping"""
    if (unit1 in areaD) and (unit2 in areaD):
        factor1 = areaD[unit1]
        factor2 = areaD[unit2]
        return factor2*x/factor1
    else:
        return False
number=1
while x != 0:
    number = raw_input ("Number of Units:")
    unit1 = raw_input ("Unit Converting From:")
    unit2 = raw_input ("Unit Converting To:")
    outcome = convertArea(x, unit1, unit2)
    if outcome is not False:
        print "%f %s = %f %s" % (x, unit1, outcome, unit2)
    else:
        print "There was an error converting %s to %s"  % (unit1,unit2)
Tags (2)
0 Kudos
8 Replies
ChrisMathers
Occasional Contributor III
0 Kudos
KurtEdwards
New Contributor
I have tried adding the script to a custom toolbox that I have made.  When I do this the script is added to the toolbox but when I run the tool the tool bombs and gives and error message.  I can't get the script tool to run without bombing.

Any ideas?

Thanks, Kurt
0 Kudos
NiklasNorrthon
Occasional Contributor III
It might be possible to help you if you could give us some details of that "bombing". Quoting an error message and a traceback perhaps...
0 Kudos
KurtEdwards
New Contributor
The error message that I keep getting is as follows:



Executing: AreaConversion 1 sqmeter sqfoot
Start Time: Thu Mar 17 09:33:04 2011
Running script AreaConversion...
<type 'exceptions.EOFError'>: EOF when reading a line
Failed to execute (AreaConversion).
Failed at Thu Mar 17 09:33:04 2011 (Elapsed Time: 0.00 seconds)

Thanks.
0 Kudos
KurtEdwards
New Contributor
I have played around with the syntax of my code and have finally had it work.  My code now looks like this:

#create an empty dictionary
areaD = {}
import arcpy
import arcpy.mapping
import os

# populate dictionary using indexing and assignment with units and conversion factors relative to sqmeter = 1.0
# to convert x sqmeters to any of the other area units multiply by the factor
# to convert x of any of the other area units to sqmeter divide by the factor
# to convert x of any area unit to any of the other area units go over interim sqmeter
# this minimizes the total number of conversion factors

areaD['sqmeter']      = 1.0
areaD['sqmillimeter'] = 1000000.0
areaD['sqcentimeter'] = 10000.0
areaD['sqkilometer']  = 0.000001
areaD['hectare']      = 0.0001
areaD['sqinch']       = 1550.003
areaD['sqfoot']       = 10.76391
areaD['sqyard']       = 1.19599
areaD['acre']         = 0.0002471054
areaD['sqmile']       = 0.0000003861022


def convertArea(x, unit1, unit2):
    """area conversion with error trapping"""
    if (unit1 in areaD) and (unit2 in areaD):
        factor1 = areaD[unit1]
        factor2 = areaD[unit2]
        return factor2*x/factor1
    else:
        return False

x = int (arcpy.GetParameter (0))
unit1 = arcpy.GetParameterAsText(1)
unit2 = arcpy.GetParameterAsText(2)
outcome = convertArea(x, unit1, unit2)
if outcome is not False:
    print "%f %s = %f %s" % (x, unit1, outcome, unit2)
    arcpy.AddMessage("%f %s = %f %s" % (x, unit1, outcome, unit2))
else:
    print "There was an error converting %s to %s"  % (unit1,unit2)
    arcpy.AddMessage("There was an error converting %s to %s"  % (unit1,unit2))

It works in the script tool which is a huge step.  But, I am still getting some problems.  When I run the tool and give it an number that has a decimal like 5.6 it returns an answer calculated at 5.0000.  I don't know why it is droping the .6 and replacing it with .0000. 

I have included screenshots of both the tool menu and the result page.  You can see how it drops the decimal.  Does anyone know why?  Please help.
0 Kudos
MarkWiygul
New Contributor
IDLE 1.2.1      
>>>int (5.6)
5

>>>2.4 + int (5.6)
7.4000000000000004

>>>float (5.6)
5.5999999999999996


Thanks for posting since this is helping me as well! 

Try using 'float' rather than 'int' in your script since 'int' delivers a whole number.  Once that unintended integer paramter got calculated against what Python knew to be a 'float' number type within the conversion expression (Python is dynamically typed), the return value will then come out with incorrect values with a floating decimal and zeros.

Question to help me:  how do you get the script to accept your 3 parameters when running from Toolbox.  The .getparameterAsText method did not call a dialog box.  I then tried setting up variables and parameters within ArcMap's Model Builder without success.  If you created a Model Builder for Toolbox to accept retrieve the parameters, then could you let me know how to get this done?  Thanks!
0 Kudos
MarkWiygul
New Contributor
I figured out the problem I was having with the script not asking for parameters.  I needed to setup the parameters list before hitting the <finish> button while importing the script into a toolbox.

I made a couple of adjustments in the script as well.  In addtional to using 'float' instead of int, I removed the setting up of a 'workspace' and set that to GetParameterAsText(0).  Your script works fantastic!  Have a nice day
0 Kudos
SilasToms
New Contributor
I have a related issue. I have written many ArcGIS specific Python scripts that run fine in IDLE/PythonWin, producing the results expected and putting them in the correct place within my file structure.

However, when I try to add the script to a toolbox as a script tool, I don't have the same success. I usually include iteration in the script (invoking the geoprocessor object as a 9.3 object to use the more pythonic for-loop structure, usually, though I explored using the 9.0-9.2 versions and the while-next structure) to perform the same operation on all feature classes within a feature dataset. The script will run 'successfully', according to the output, and yet, nothing happens.

For instance, I might Clip all the feature classes in the dataset. I'll set the workspace to the feature dataset, and have the operation run and place all the output feature classes listed in that dataset (using gp.listfeatureclasses) in another feature dataset. While again, this works fine in IDLE/PythonWin, it will not run if invoked as a script tool. The basic operation, the Clip, will work if performed (as a script tool) on a single feature class (i.e. no iteration).

Here is an example of the code, and again, it works just fine from a stand alone editor:


import sys, string, os, arcgisscripting

gp = arcgisscripting.create(9.3)
gp.overwriteoutput =1
# Load required toolboxes...
gp.AddToolbox("C:/Program Files/ArcGIS/ArcToolbox/Toolboxes/Data Management Tools.tbx")
gp.AddToolbox("C:/Program Files/ArcGIS/ArcToolbox/Toolboxes/Analysis Tools.tbx")

workspace = 'C:/Example.gdb/FeatureDataset/'
clippedPath = 'C:/Example.gdb/OutputDataset/'
clipfeature = 'C:/Example.gdb/Clip_feature_class'
gp.workspace = workspace

featureClasses = gp.listfeatureclasses()

for feature in featureClasses:
        gp.Clip_analysis(feature, clipfeature,clippedPath +feature+'_clip' , "")


Why won't this work as a script tool?
0 Kudos