Select to view content in your preferred language

create variable counter name from string functions and then auto-increment in loop

1540
8
Jump to solution
02-13-2013 02:32 AM
DustinEdge
Deactivated User
Greetings All

hopefully the subject makes sense and if not, here's a longer version:
I have about 350 mdbs in various folders that have the same schemas and has data captured over 2 years.

due to some reporting errors that have now come to light, i need to do a count/append on all the features and report on any discrepanies.

i used the os.walk function to find all the mdbs and then used a check to make sure the source feature class had some features (getcount) and that it matched my blank target checking mdb. if it matched, it appends the data and moves on.

i used a string variable to hold the master list of feature class names:
"defects,photos,building,etc"
to check the source feature class existence, i used a simple string.find(fc, masterlist) != 1

while its easy to create a simple counter to return total number of records written, what i really want to do is have several counters, one for each feature class. and the counter gets called and incremented only when it encounters one of the feature classes with valid features.
Like: defects_count, photos_count, building_count etc

while its easy to build the variable name using string functions (varcounter = fc + "_count") I dont see how i could keep incrementing the number of features found using varcounter = varcounter + countfc.

is python smart enough to figure out that the string i created in a variable is actually another number variable?

Apologies for the long post

thanks in advance
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
T__WayneWhitley
Honored Contributor
I'll just make a brief suggestion -

You already have what I think you called a string variable of fc names for which you want the counts for, is that correct?

What I suggest (with the above assumption) is that since the fc names are already essentially a list, why not set up a python dictionary of those fc names to use as a key and pair them with your index variable counters?

So how it works is when you 'encounter' as you said the valid features, all you have to do is look up the appropriate fc by name in the dictionary and increment the corresponding index (which should be integer type)...easier to track and all the indexes are in a convenient single place to fetch or report on them, say, at the completion of your script.


Enjoy,
Wayne

View solution in original post

0 Kudos
8 Replies
T__WayneWhitley
Honored Contributor
I'll just make a brief suggestion -

You already have what I think you called a string variable of fc names for which you want the counts for, is that correct?

What I suggest (with the above assumption) is that since the fc names are already essentially a list, why not set up a python dictionary of those fc names to use as a key and pair them with your index variable counters?

So how it works is when you 'encounter' as you said the valid features, all you have to do is look up the appropriate fc by name in the dictionary and increment the corresponding index (which should be integer type)...easier to track and all the indexes are in a convenient single place to fetch or report on them, say, at the completion of your script.


Enjoy,
Wayne
0 Kudos
DustinEdge
Deactivated User
Hi Wayne

I suppose I  could  add array instead of  string and add a second value to  item in the array.

I will give it  shot and report back.

cheers
0 Kudos
T__WayneWhitley
Honored Contributor
Yes something like that...do what is comfortable for you.  Note that the functionality is mimicked using the 'dictionary' data structure - and this is native to Python and is fairly easy to use and well-documented, see:

http://docs.python.org/2/tutorial/datastructures.html#dictionaries

I don't have a good ready example, but consider this monkeying within IDLE - I'm not suggested you use it quite this way, but this should give you an idea:
>>> fcNames = {}
>>> type(fcNames)
<type 'dict'>
>>> 
>>> fcNames['fc1'] = 3
>>> print fcNames
{'fc1': 3}
>>> 
>>> fcNames['fc1']
3
>>> 
>>> fcNames['fc2'] = 10
>>>
>>> fcNames
{'fc1': 3, 'fc2': 10}
>>>
>>> for i in range(10):
 i = fcNames['fc1']
 i += 1
 fcNames['fc1'] = i

 
>>> fcNames['fc1']
13
>>> fcNames
{'fc1': 13, 'fc2': 10}
>>> 


Hope that helps shed a tiny light on the subject.  I have used 'lists' a lot, and a little embarrassed to say I haven't used dictionaries that much at all - I'm sure others have much better examples...an array should work too; this is just the 'pythonic' way.

And I should use it more because I see a lot of examples - such as GetInstallInfo and serviceProperties on a Layer (if supported for the layer type).  Both return dictionary data types.

http://resources.arcgis.com/en/help/main/10.1/index.html#/GetInstallInfo/018v00000004000000/
http://resources.arcgis.com/en/help/main/10.1/index.html#//00s300000008000000

Enjoy,
Wayne
0 Kudos
MathewCoyle
Honored Contributor
Wayne has the right idea I think, incrementing a dict counter with fc name as the key would be fairly easy. You can be a little more concise than the posted example.
for i in range(10):
 fcNames['fc1'] += 1
0 Kudos
DustinEdge
Deactivated User
Greetings All

After having a read of dictionaries, it seems the ideal solution in this instance. The code is clean and straightforward which I like.

here's my list of feature classes:
masterlist = "CoreTestLocation,CoverToReo,Defect_Areas"


here's my dictionary:
dcount = {'CoreTestLocation': 0, 'CoverToReo': 0, 'Defect_Areas': 0,}


It gets the number of features:
fcrecs = int(arcpy.GetCount_management(fc).getOutput(0))


here's where the fc variable (from ListFeatureClasses) checks to see if it lives in the masterlist. It then gets the current count for the relevant fc from the dictionary, updates it and then puts the new value back.

if string.find(masterlist,fc) != -1:
[INDENT]print fc + " has " + str(fcrecs) + " features"
currentval = dcount[fc]
newval = currentval + fcrecs
dcount[fc] = newval
[/INDENT]


Thanks for the help
0 Kudos
MathewCoyle
Honored Contributor
I would make a few minor changes.

If your list is coming in as a string for whatever reason you can just do this to make it an actual list.
masterlist = masterlist.split(',')

Then in your loop you can just do this.
if fc in masterlist:
    print('{0} has {1} features'.format(fc, fcrecs))
    dcount[fc] += fcrecs
0 Kudos
DustinEdge
Deactivated User
Hey Mathew

that would be the better way, but I'm not 100% sure that somewhere along the way someone has introduced another featureclass or edited a featureclass's name.

By using the if statement I can catch featureclasses that dont meet the masterlist criteria.

Cheers
0 Kudos
ShaunCavey
Emerging Contributor
Dictionaries are definitely the way to go.  Little confusing at first, but I promise you'll be better off after its all said and done.
0 Kudos