Though I'd share it with you, made this one this morning during my
train commute to work ad I need some grouping on GAE.
It's now standalone, and not yet integrated into the DAL.
#!/usr/bin/env python
#coding=utf-8
import cPickle
def group(detail_rows, detail_fields, key_fields=None):
"""
Groups details so we can use min, max etc on iter
Example:
>>> # mimic simple table
>>> detail_row_1 = dict(ab='a', ij='i', low=1, high=9)
>>> detail_row_2 = dict(ab='a', ij='j', low=2, high=8)
>>> detail_row_3 = dict(ab='b', ij='i', low=3, high=7)
>>> detail_row_4 = dict(ab='b', ij='j', low=4, high=6)
>>> detail_rows = [detail_row_1, detail_row_2, detail_row_3,
detail_row_4]
>>> detail_fields = ['low', 'high']
>>> # no grouping
>>> group_fields = None
>>> grouped = group(detail_rows, detail_fields, group_fields)
>>> print grouped
[{'high': [9, 8, 7, 6], 'low': [1, 2, 3, 4]}]
>>> for row in grouped:
... print 'min low: %s max low: %s' % (
... min(row['low']), max(row['low']))
min low: 1 max low: 4
>>> # grouping on 1 field
>>> group_fields = ['ab']
>>> grouped = group(detail_rows, detail_fields, group_fields)
>>> print grouped
[{'high': [7, 6], 'ab': 'b', 'low': [3, 4]}, {'high': [9, 8],
'ab': 'a', 'low': [1, 2]}]
>>> for row in grouped:
... print '%s min low: %s max low: %s' % (
... row['ab'], min(row['low']), max(row['low']))
b min low: 3 max low: 4
a min low: 1 max low: 2
>>> # grouping on multiple fields
>>> group_fields = ['ab', 'ij']
>>> grouped = group(detail_rows, detail_fields, group_fields)
>>> print grouped
[{'high': [6], 'ab': 'b', 'ij': 'j', 'low': [4]}, {'high':
[8], 'ab': 'a', 'ij': 'j', 'low': [2]}, {'high': [9], 'ab': 'a', 'ij':
'i', 'low': [1]}, {'high': [7], 'ab': 'b', 'ij': 'i', 'low': [3]}]
>>> for row in grouped:
... print '%s %s min low: %s max low: %s' % (
... row['ab'], row['ij'], min(row['low']), max(row['low']))
b j min low: 4 max low: 4
a j min low: 2 max low: 2
a i min low: 1 max low: 1
b i min low: 3 max low: 3
"""
# first store details per key in dictionary
groups = {}
for row in detail_rows:
# build the key, and pickle it to a single value
key = {}
if key_fields:
for field in key_fields:
key.update(**{field: row[field]})
pickled_key = cPickle.dumps(key)
init_row = False
if not pickled_key in groups:
init_row = True
groups[pickled_key] = {}
for field in detail_fields:
if init_row:
groups[pickled_key][field] = []
groups[pickled_key][field].append(row[field])
# convert working dictionary to uniform row info
rows = []
for pickled_key in groups:
key = cPickle.loads(pickled_key)
data = groups[pickled_key]
data.update(key)
rows.append(data)
return rows
if __name__ == '__main__':
import doctest
doctest.testmod()
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"web2py Web Framework" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/web2py?hl=en
-~----------~----~----~----~------~----~------~--~---