ArcGIS 10:Doing Python to check for numbers of files in a directory-indentation err

2703
13
08-17-2012 10:53 AM
ScottChang
Deactivated User
Hi all
I am using the following tutorial materials to pick up the Python programming:

(i)                  Python Programming for ArcGIS by David Quinn & Daniel Sheehan (dated: January 27, 2011)

(ii)                Python �?? Check for number of shapefiles in a directory in http://gis.stackexchange.com/questions/30059

I tried the following ArcPy code in my ArcMap 10:
 >>> import arcpy
>>> import os
>>> import glob 
>>> # Check numbers of shapefiles in a directory
>>> path = "C:\\TEMP\\"
>>> first = glob.glob(os.path.join(path,"NavyAnnexPt06move*"))
>>> first 
['C:\\TEMP\\NavyAnnexPt06move.dbf', 'C:\\TEMP\\NavyAnnexPt06move.prj', 'C:\\TEMP\\NavyAnnexPt06move.sbn', 'C:\\TEMP\\NavyAnnexPt06move.sbx', 'C:\\TEMP\\NavyAnnexPt06move.shp', 'C:\\TEMP\\NavyAnnexPt06move.shx']
>>> # Also to check for the only filename in path
 
>>> def file_check(path):
...      """Returns true if in path there is only one basename"""
... import os
... mlist = []I am using the following tutorial materials to pick up the Python programming:
...       for file in os.listdir(path):
...           if os.path.basename(file).split(".")[0] not in mlist:
...              mlist.append(os.path.basename(file).split(".")[0])
...     if len(mlist)>1:
...              return True
...       else:
...              return False
... 

Parsing error <type 'exceptions.IndentationError'>: unexpected indent (line 5)
>>> 


and I got an indentation error. Please help, advise and respond.

Thanks,
Scott Chang
Tags (2)
0 Kudos
13 Replies
curtvprice
MVP Esteemed Contributor
I got an indentation error. Please help, advise and respond.


You must be fanatically consistent with indents. Do not mix tabs and spaces and make sure your indents are absolutely aligned for each block of code.

If you're not using an IDE (IDLE, PythonWin, PyScripter, WingIDE are the big four) I highly recommend it!

Here's an example of your function properly indented:

"""Returns true if in path there is only one basename"""
import os
mlist = [] 
for file in os.listdir(path):
    if os.path.basename(file).split(".")[0] not in mlist:
        mlist.append(os.path.basename(file).split(".")[0])
    if len(mlist)>1:
            return True
        else:
            return False
0 Kudos
ScottChang
Deactivated User
Hi Curtis,  Thanks for your nice response.

I tried to do the "block alignment" things you instructed. But, I still failed to get it right-see the attached file for details.
Please kindly help, advise and respond again.

Thanks,
Scott Chang
0 Kudos
curtvprice
MVP Esteemed Contributor
Scott, here's what you sent:

[ATTACH=CONFIG]17142[/ATTACH]

The error is the entire function's contents need to be indented. The docstring is not a comment, it's actual code, so it must be indented too.

def function():
    """This is my function""" 
    print "Hello world"
    return
0 Kudos
ScottChang
Deactivated User
Hi Curtis, Thanks for your response.

I tried my best to do the whole "block alignment" identation - see the attached file. I executed it and I got: Parsing error <type 'exceptions.IndentationError'>: unindent does not match any outer indentation level (line 10).  I am completely lost now.  Please help, advise and respond again.

Thanks,
Scott Chang

P. S.  I also tried your "def function():  ......."  No "Hello world" is printed out in the Python Window of my ArcGIS 10 Desktop program!!??  Any comments on this thing I tried?
0 Kudos
curtvprice
MVP Esteemed Contributor
   Parsing error <type 'exceptions.IndentationError'>: unindent does not match any outer indentation level (line 10).


Your indentation syntax online 10. The "else" statement must be at the same indent level as "if". (see" rel="nofollow" target="_blank">http://docs.python.org/tutorial/controlflow.html](see the Python help) (This was my error - I moved your else in the wrong direction when I was fixing your code.)

I highly recommend going through the Python" rel="nofollow" target="_blank">http://docs.python.org/tutorial/index.html]Python tutorial, it gets you up to speed on things like this fast.

I also tried your "def function():  ......."  No "Hello world" is printed out in the Python Window of my ArcGIS 10 Desktop program!!??  Any comments on this thing I tried?


You need to use arcpy.AddMessage to send messages from script tools. Print only works in your IDE, command line, or an interactive python prompt (">>>") (btw a great place to test code).

Arc 10.1 help: Writing" rel="nofollow" target="_blank">http://resources.arcgis.com/en/help/main/10.1/index.html#//0... messages in script tools
0 Kudos
ScottChang
Deactivated User
Hi Curtis,  Thanks for your nice response.
In the last several days, I went through the first 9 chapters of the Python tutorial, and the basic stuff of 2 Python books ("Python Programming  for the absolute beginner" [3rd Edition] by Michael Dawson and "The Quick Python Book" by Vernon L. Ceder) to pick up the essential, basic skills of Python programming. This morning, I executed the following ArcPy script in the ArcMap 10.0 of my "IAP2011-Quinn.mxd" project:
 >>> import arcpy
>>> import os
>>> import glob 
>>> path = "C:\\TEMP\\"
>>> def file_check(path):
...     """Returns true if path there is only one basename"""
...     import os
...     mlist = []
...     for file in os.listdir(path):
...         if os.path.basename(file).split(".") not in mlist:
...             mlist.append(os.path.basename(file).split(".")[0])
...         if len(mlist)>1:
...             return True
...         else:
...             return False
... 
>>> 

I executed this set of the ArcPy code statements. It ran OK without any error message.  But it did not give me the output.  I do not what it is happening in executing this ArcPy script.  Please kindly help, advise and respond again.

Many Thanks again.
Scott Chang
0 Kudos
curtvprice
MVP Esteemed Contributor
Looking good. Can't overstate the usefulness of that Python tutorial!

Your function looks fine - but you need to run it:

>>> file_check(path)


One little thing, there is another os function that will avoid a bug in your program if there are extra dots in your file name.

instead of using split(), os.path.splitext():


for file in os.listdir(path):
    basename = os.path.splitext(os.path.basename(file))[0]
    if basename not in mlist:
        mlist.append(basename)


Also - your last if statement is inside the loop, I think you want it to dedent so it will run after the for loop is done.
0 Kudos
ScottChang
Deactivated User
Hi Curtis, Thanks for your nice, valuable response.
(1) I got the "False" ouput from my old arcpy script and your new arcpy script.
(2) I copied a new arcpy script for class Circle from Page 187 of Vernon L. Ceder's "The Quick Python Book".  I executed the arcpy script in my ArcGIS 10.0 and I got a  Runtime error <type 'exceptions.AttributeError'>....:
 >>> import arcpy
>>> import os
>>> import glob 
>>> path = "C:\\TEMP\\"
>>> def file_check(path):
...     """Return true if path there is only one basename"""
...     import os
...     mlist = []
...     for file in os.listdir(path):
...         basename = os.path.splitext(os.path.basename(file))[0]
...         if basename not in mlist:
...             mlist.append(basename)
...         if len(mlist)>1:
...             return True
...         else:
...             return False
...    
... 
>>> file_check(path)
False
>>> class Circle:
...     def _init_(self):
...         self.radius = 1
... my_circle = Circle()
... print (2 * 3.14 * my_circle.radius)
... my_circle.radius = 5
... print (2 * 3.14 * my_circle.radius)
... 
Runtime error <type 'exceptions.AttributeError'>: Circle instance has no attribute 'radius'


This is new to me and I have no ideas what is wrong in my arcpy script that was executed in my ArcGIS 10.0. Please kindly help and advise.

Thanks again,
Scott Chang
0 Kudos
ThomasEmge
Esri Contributor
Scott,

the answer is in the Python documentation at http://docs.python.org/tutorial/classes.html

As Curtis suggested I would also recommend that you take your time working through the tutorial. Python is not a "hard" language to learn but it is still a matter of getting the concept right and understanding what the code is doing. If you are not already fluent in other coding languages it simply means that the learning process will take time. Depending on your prior coding experience it might mean that it will take a couple of weeks before you can generate code of the fly.

For classes there special methods invoked throughout the lifetime of an object (an instance of a class). The method called at the creation of the object is called __init__(self[,...]). Notice the double underscores. The arguments are a reference to itself and optionally a list of arguments

class Circle:
    def __init__(self):
        self.radius = 1


which means that at the time of Circle object creation you are adding an attribute called radius and give it the value of 1.
More commonly you might want to write your classes to be a little more flexible such that can influence the radius of the circle at the time of the creation such as:

class Circle:
    def __init__(self, radius = 1):
        self.radius = radius


which means that you can write it like

my_circle = Circle()  # has a radius of 1 as no explicit value was given
my_circle_2 = Circle(2) # has a radius of 2


- Thomas
0 Kudos