cdenninger

Sum / Percent Script --> Revised to become Script Tool

Discussion created by cdenninger on Jun 16, 2011
Latest reply on Jun 22, 2011 by cdenninger
This script works on a .txt-type file and outputs in a similar format.  What I really need it to do is pefrom this on a feature class and allow for 5 user-inputs: 1) Input feature class (or table) 2) Input field (ID) 3) Input field (area) 4) Output field1 (sum area) 5) Output field2 (percent of total area).  I can set up the script tool in ArcGIS, however, I really need help with refining the script.

In plain words the script does the following: For each unique ID in the Input field (ID), sum the area of all those rows (from Input field area) and add them to the Output field 1 (sum).  Then for each of those unique IDs calc the percent (using the sum) and add it to Output field2 (percent).  In short, give me the percent% of each part of A, of each part of B, of each part of C, etc.

**Exampe of what the fc table might look like as a final result: **
ID  Area  Area_Sum   Percent  
 A  3.5     103.2         3.39
 A  44.5   103.2         43.12
 A  55.2   103.2         53.49
 B  22.4    76.6          29.24
 B  21.0    76.6          27.42
 B  33.2    76.6          43.34
 C  22.3    55.3         40.33
 C  11.0    55.3         19.89
 C  22.0    55.3         39.78
 D  33.3    110.6       30.11
 D  55.3    110.6       50.00
 D  22.0    110.6       19.89
 E  22.0    155.1       14.18
 E  44.6    155.1       28.76
 E  66.1    155.1       42.62
 E  22.4    155.1       14.44


** Script **
from operator import itemgetter
from collections import defaultdict
from pprint import pprint

class Entry(object):
    pass

with open("areadata.txt") as reader:
    lines = reader.readlines()
    lines = [line.strip().split(",") for line in lines]    
    header, data = lines[0], lines[1:]

    def make_entry(row):
        """From a row sequence with columns of data, makes a dictionary whose
        keys are the header labels and whose values are the column values."""
        entry = Entry()
        for i, val in enumerate(row):
            setattr(entry, header[i], val)
        return entry
# row.append, might need to be row.getvalue or setvalue type
    for line in lines:        
        rows = []
        for row in data:
            # convert values in columns
            column_types = (str, float)
            rows.append([column_types[i](val) 
                             for i, val in enumerate(row)])
        # sort rows by first column
        rows = sorted(rows, key=itemgetter(0))
        # sums dictionary holds a mapping of feature => area sum
        # if key is not present, creates an empty list
        sums = defaultdict(list)
        for row in rows:
            entry = make_entry(row)
            sums[entry.feature].append(entry.area)
        # now that all gathered together, let's sum them
        for key, val in sums.iteritems():
            sums[key] = sum(val)
        # re-iterate over the original list of rows to generate the 
        # new derived columns, sum and percent
        for row in rows:
            entry = make_entry(row)
            sum_ = sums[entry.feature]
            row.append(sum_)
            percent = "%.2f" % ((entry.area / sum_) * 100)
            row.append(percent)
    # print the result in a pretty way
    pprint(rows)


Any help is appreciated.
Thank you!

Outcomes