Pulling numbers from ASCII filename not working

I

IamIan

I searched the archives but couldn't find anyone else with this
problem. Basically I'm grabbing all ASCII files in a directory and
doing geoprocessing on them. I need to calculate a z-factor based on
the latitude of the ASCII file being worked on, which is in the
filename. If I type in the code manually it works and reads the
latitude value from the ASCII filename, but when run within ArcGIS it
crashes when it gets to int(LatString). Isnumber() returned false for
Latitude as well. Is there something different about reading values
from an ASCII filename?

import sys, os, win32com.client, string, gc

# Get a list of ASCII files in the workspace for ASCII To Raster
conversion
filenames = os.listdir(gp.workspace)
filenames = [filename.lower()
for filename in filenames
if (filename[-4:].lower() == ".asc" and filename[0] != "-" )]
for filename in filenames:

# For each ASCII file, create Hillshade.
# account for latitude by computing Z units using radians
Latitude = filename[1:3]
LatString = str(Latitude)
LatInt = int(LatString)
radians = LatInt * 0.0174532925
zFactor = 1/(113200 * (cos(radians)))
 
M

mrmakent

First: http://www.catb.org/~esr/faqs/smart-questions.html

You say your program 'crashes' when it gets to 'int(LatString)'. I'm
guessing (and it's entirely a guess, since you don't tell us) that you
are getting an exception like 'ValueError: invalid literal for int():
whatever'. I'm guessing again that 'LatString' doesn't contain what
you think it does at this point. Have you tried inserting a print
statement to show you just what 'LatString' contains?
 
L

Larry Bates

At lest one of the filenames (or directories) being returned by
os.listdir doesn't have integer value where you are looking.
Remember that os.listdir returns subdirectories as well as files.
You may want to look at using glob.glob() instead and limit it
to *.asc.

Secondly,

filenames = [filename.lower() \
for filename in filenames \
if (filename[-4:].lower() == ".asc" and filename[0] != "-" )]

is better rewritten as (not tested):

import glob
filenames=glob.glob(os.path.join(gp.workspace, '*.asc'))
filenames = [f.lower() for f in filenames if not f.startswith('-')]

Larry Bates
 
I

IamIan

The exception I get is "TypeError: Cannot add value 'int' to string." I
have looked at LatString, and it is the string representation of
latitude ('17' etc.). What's odd is that the exception is raised not
when I include LatInt = int(LatString), but when I try to print
LatInt's value or multiply it by another number.

Filenames are along the lines of "N16W110.asc" - is there another way
to get LatString into a number for multiplication purposes?
 
F

Fredrik Lundh

IamIan said:
The exception I get is "TypeError: Cannot add value 'int' to string."

now that you've posted the exception, can you please post the code
you're using, and the *complete* traceback.

(the stuff you posted earlier contained syntax errors, and didn't con-
tain any additions. I suggest using copy/paste, rather than typing
things from memory).

</F>
 
B

Bengt Richter

I searched the archives but couldn't find anyone else with this
problem. Basically I'm grabbing all ASCII files in a directory and
doing geoprocessing on them. I need to calculate a z-factor based on
the latitude of the ASCII file being worked on, which is in the
filename. If I type in the code manually it works and reads the
latitude value from the ASCII filename, but when run within ArcGIS it
crashes when it gets to int(LatString). Isnumber() returned false for
Latitude as well. Is there something different about reading values
from an ASCII filename?
Aren't you curious as to what the value of LatString was that failed?
Don't you know how to find out?
import sys, os, win32com.client, string, gc

# Get a list of ASCII files in the workspace for ASCII To Raster
conversion
filenames = os.listdir(gp.workspace)
filenames = [filename.lower()
for filename in filenames
if (filename[-4:].lower() == ".asc" and filename[0] != "-" )]
indentation of the above two lines would improve readability
for filename in filenames:
I would try print repr(filename) here, to see what you are dealing with
# For each ASCII file, create Hillshade.
# account for latitude by computing Z units using radians
Latitude = filename[1:3]
LatString = str(Latitude)
you probably won't need a print repr(LatString) here if you see the above print
LatInt = int(LatString)
radians = LatInt * 0.0174532925
zFactor = 1/(113200 * (cos(radians)))
BTW, capitalizing the first letter of python variable names is counter to usual convention.

Regards,
Bengt Richter
 
I

IamIan

Thank you for the replies, I'm new to Python and appreciate your
patience. I'm using Python 2.1.

To reiterate, the ASCII files in the workspace are being read correctly
and their latitude values (coming from the filenames) are successfully
being converted to string. Even doing LatInt = int(LatString) works,
however the second I try to print LatInt's value or use it in
mathematical operations, the code chokes in ArcGIS.

My full code:

# Import system modules
import sys, os, win32com.client

# Create the geoprocessor object
gp = win32com.client.Dispatch("esriGeoprocessing.GpDispatch.1")
print gp.usage("Hillshade_sa")
print gp.usage("RasterToOtherFormat_conversion")
print gp.usage("DefineProjection_management")

# Check license availability
gp.AddMessage ("ArcInfo license is " + str(gp.CheckProduct("ArcInfo")))
gp.SetProduct("ArcInfo")
gp.CheckOutExtension("Spatial")

# Set workspace
workspace = "E:\\GISTest"
gp.workspace = workspace
gp.AddMessage("Workspace = " + gp.workspace)

filenames = os.listdir(gp.workspace)
filenames = [filename.lower()
for filename in filenames
if (filename[-4:].lower() == ".asc" and filename[0] != "-" )]
for filename in filenames:

# For each ASCII file, create Hillshade.
# account for latitude by computing Z units using radians
Latitude = filename[1:3]
LatString = str(Latitude)
LatInt = int(LatString)
gp.AddMessage("LatInt is " + LatInt)
radians = LatInt * 0.0174532925
zFactor = 1/(113200 * (cos(radians)))

The complete traceback:

Traceback (most recent call last):
File "e:\python21\pythonwin\pywin\framework\scriptutils.py", line
310, in RunScript
exec codeObject in __main__.__dict__
File "E:\Documents and
Settings\Administrator\Desktop\Ian\GIS\Python\zOnly.py", line 32, in ?
gp.AddMessage("LatInt is " + LatInt)
TypeError: cannot add type "int" to string


I tried print repr(filename) and it returned the actual filename:
'n16w099.asc' , 'n17w062.asc' , etc.
 
S

Steven D'Aprano

Thank you for the replies, I'm new to Python and appreciate your
patience. I'm using Python 2.1.

To reiterate, the ASCII files in the workspace are being read correctly
and their latitude values (coming from the filenames) are successfully
being converted to string. Even doing LatInt = int(LatString) works,
however the second I try to print LatInt's value or use it in
mathematical operations, the code chokes in ArcGIS.
[snip]

LatString = str(Latitude)
LatInt = int(LatString)
gp.AddMessage("LatInt is " + LatInt)

Dude. You're trying to add a string to an int. What did you think would
happen?
The complete traceback:

Traceback (most recent call last):
File "e:\python21\pythonwin\pywin\framework\scriptutils.py", line
310, in RunScript
exec codeObject in __main__.__dict__
File "E:\Documents and
Settings\Administrator\Desktop\Ian\GIS\Python\zOnly.py", line 32, in ?
gp.AddMessage("LatInt is " + LatInt)
TypeError: cannot add type "int" to string

The traceback tells you exactly what is wrong, and where it is going
wrong: you are trying to add a string to an int.

What you probably want is either gp.AddMessage("LatInt is " + LatString)
or gp.AddMessage("LatInt is %d" % LatInt).
 
I

IamIan

Dude. You're trying to add a string to an int. What did you think would

Dude. I thought it would concatenate the value for LatInt with the rest
of the sentence; I wasn't literally trying to add them. Apparently you
can only concatenate strings like this in Python.
 
S

Steven D'Aprano

Dude. I thought it would concatenate the value for LatInt with the rest
of the sentence; I wasn't literally trying to add them. Apparently you
can only concatenate strings like this in Python.

No. An interactive session is your friend. You can concatenate all sorts
of things, not just strings:
[2, 3, 4] + [5] [2, 3, 4, 5]
(2, 3, 4,) + (5,)
(2, 3, 4, 5)

What should 4 + "5" give you? 9 or "45"?

Your description of the problem was *utterly* wrong. You said you get an
error when you try to print LatInt; but that's not true, is it? print
LatInt works fine, I bet. If you had actually posted the traceback, rather
than trying to describe it in your own words, your problem would have been
solved after one post. In other words, you sent us all on a wild goose
chase.

But the main thing is, the traceback was telling you exactly what was
wrong. Listen to it, it knows.
 
D

Dennis Lee Bieber

# For each ASCII file, create Hillshade.
# account for latitude by computing Z units using radians
Latitude = filename[1:3]
LatString = str(Latitude)

That is redundant -- filename is a string, taking part of it will
still be a string, so "Latitude" is already a string and could be fed
into the next line.
I tried print repr(filename) and it returned the actual filename:
'n16w099.asc' , 'n17w062.asc' , etc.

You may have problems with the longitude... those leading zeroes may
be taken as Octal notation...
--
 
D

Dave Hansen

On 25 Jan 2006 12:42:20 -0800, "IamIan" <[email protected]> declaimed the
following in comp.lang.python: [...]
I tried print repr(filename) and it returned the actual filename:
'n16w099.asc' , 'n17w062.asc' , etc.

You may have problems with the longitude... those leading zeroes may
be taken as Octal notation...

Shouldn't be a problem unless you make it one. Int defaults to
decimal, unless you specify a base or tell it to infer the base from
the number format by specifying a base of zero.
50

Hard to interpret "099" as an octal number in any case:

Traceback (most recent call last):
File "<pyshell#59>", line 1, in -toplevel-
a = int("099",0)
ValueError: invalid literal for int(): 099
Regards,
-=Dave
 
B

Bengt Richter

Thank you for the replies, I'm new to Python and appreciate your
patience. I'm using Python 2.1.

To reiterate, the ASCII files in the workspace are being read correctly
and their latitude values (coming from the filenames) are successfully
being converted to string. Even doing LatInt = int(LatString) works,
however the second I try to print LatInt's value or use it in
mathematical operations, the code chokes in ArcGIS.

My full code:

# Import system modules
import sys, os, win32com.client

# Create the geoprocessor object
gp = win32com.client.Dispatch("esriGeoprocessing.GpDispatch.1")
print gp.usage("Hillshade_sa")
print gp.usage("RasterToOtherFormat_conversion")
print gp.usage("DefineProjection_management")

# Check license availability
gp.AddMessage ("ArcInfo license is " + str(gp.CheckProduct("ArcInfo")))
gp.SetProduct("ArcInfo")
gp.CheckOutExtension("Spatial")

# Set workspace
workspace = "E:\\GISTest"
gp.workspace = workspace
gp.AddMessage("Workspace = " + gp.workspace)

filenames = os.listdir(gp.workspace)
filenames = [filename.lower()
for filename in filenames
if (filename[-4:].lower() == ".asc" and filename[0] != "-" )]
for filename in filenames:

# For each ASCII file, create Hillshade.
# account for latitude by computing Z units using radians
Latitude = filename[1:3]
LatString = str(Latitude)
LatInt = int(LatString)
^^^^^^--here you set LatInt to an integer
gp.AddMessage("LatInt is " + LatInt)
radians = LatInt * 0.0174532925
zFactor = 1/(113200 * (cos(radians)))

The complete traceback:

Traceback (most recent call last):
File "e:\python21\pythonwin\pywin\framework\scriptutils.py", line
310, in RunScript
exec codeObject in __main__.__dict__
File "E:\Documents and
Settings\Administrator\Desktop\Ian\GIS\Python\zOnly.py", line 32, in ?
gp.AddMessage("LatInt is " + LatInt)
string--^^^^^^^^^^^^ ^^^^^^--integer
(LatString in place of LatInt might work, since it's a string (so is Latitude))
TypeError: cannot add type "int" to string
^^^^^^^^^^ ^^^ ^^^^^^
This is not lying ;-)
I tried print repr(filename) and it returned the actual filename:
'n16w099.asc' , 'n17w062.asc' , etc.
So you can see Latitude would be '16' '17' etc. right?

On to the next traceback ;-)

Regards,
Bengt Richter
 
I

IamIan

Thanks for the help everyone (especially those that gave more answers
than attitude). It's working perfectly!

Ian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top