Edgewall Software

Changes between Initial Version and Version 1 of HelperFunctions


Ignore:
Timestamp:
Aug 17, 2006, 7:04:09 PM (18 years ago)
Author:
cmlenz
Comment:

Place to collect helper functions for use in template expressions

Legend:

Unmodified
Added
Removed
Modified
  • HelperFunctions

    v1 v1  
     1= Helper functions for use in Markup templates =
     2[[PageOutline(2)]]
     3Often you need non-trivial presentation logic in templates, but Markup does not (yet) let you drop into straight Python. In Markup, such presentation logic must be either performed in the controller (i.e. the Python code feeding the template with date), or in ''helper functions'' that are called from within template expressions.
     4
     5This page serves as a place where generalized functions that solve common tasks in presentation logic can be collected. At some point, Markup might include a library of such functions.
     6
     7== Python Standard Library ==
     8
     9Many of the Python [http://docs.python.org/lib/built-in-funcs.html builtin functions] (such as `reversed` or `sorted`), as well as those in the [http://docs.python.org/lib/module-itertools.html itertools] package (such as `groupby`), can be quite useful in templates. The builtin functions are available by default, whereas other functions need to be put in the template context data explicitly.
     10
     11== group() ==
     12
     13The following was written by [http://www.cmlenz.net/ Christopher Lenz] for use in the [http://trac.edgewall.org/ Trac project]:
     14
     15{{{
     16#!python
     17def group(iterable, num, predicate=None):
     18    """Combines the elements produced by the given iterable so that every `n`
     19    items are returned as a tuple.
     20   
     21    >>> items = [1, 2, 3, 4]
     22    >>> for item in group(items, 2):
     23    ...     print item
     24    (1, 2)
     25    (3, 4)
     26   
     27    The last tuple is padded with `None` values if its' length is smaller than
     28    `num`.
     29   
     30    >>> items = [1, 2, 3, 4, 5]
     31    >>> for item in group(items, 2):
     32    ...     print item
     33    (1, 2)
     34    (3, 4)
     35    (5, None)
     36   
     37    The optional `predicate` parameter can be used to flag elements that should
     38    not be packed together with other items. Only those elements where the
     39    predicate function returns True are grouped with other elements, otherwise
     40    they are returned as a tuple of length 1:
     41   
     42    >>> items = [1, 2, 3, 4]
     43    >>> for item in group(items, 2, lambda x: x != 3):
     44    ...     print item
     45    (1, 2)
     46    (3,)
     47    (4, None)
     48    """
     49    buf = []
     50    for item in iterable:
     51        flush = predicate and not predicate(item)
     52        if buf and flush:
     53            buf += [None] * (num - len(buf))
     54            yield tuple(buf)
     55            del buf[:]
     56        buf.append(item)
     57        if flush or len(buf) == num:
     58            yield tuple(buf)
     59            del buf[:]
     60    if buf:
     61        buf += [None] * (num - len(buf))
     62        yield tuple(buf)
     63}}}
     64
     65If the `predicate` functionality is not needed, a vastly simpler implementation of that function would be:
     66
     67{{{
     68#!python
     69def group(iterable, num):
     70    """Group an iterable into an n-tuples iterable. Incomplete tuples
     71    are discarded e.g.
     72   
     73    >>> list(group(range(10), 3))
     74    [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, None, None)]
     75    """
     76    return map(None, *[iter(iterable)] * num)
     77}}}
     78
     79See also the Python Cookbook recipe “[http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/303060 Group a list into sequential n-tuples]”.