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
-~----------~----~----~----~------~----~------~--~---

Reply via email to