diff sat_website/templatetags/partition.py @ 0:9305c6458e2f

initial commit
author Goffi <goffi@goffi.org>
date Sat, 28 Jul 2012 20:36:32 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sat_website/templatetags/partition.py	Sat Jul 28 20:36:32 2012 +0200
@@ -0,0 +1,166 @@
+"""
+(c) Smiley Chris 2007
+
+This code comes from Django snippets ( http://djangosnippets.org/snippets/401/ )
+According to the Terms of Service ( http://djangosnippets.org/about/tos/ ), the code can be freely used
+
+Template filters to partition lists into rows or columns.
+
+A common use-case is for splitting a list into a table with columns::
+
+    {% load partition %}
+    <table>
+    {% for row in mylist|columns:3 %}
+        <tr>
+        {% for item in row %}
+            <td>{{ item }}</td>
+        {% endfor %}
+        </tr>
+    {% endfor %}
+    </table>
+"""
+
+from django.template import Library
+
+register = Library()
+
+def rows(thelist, n):
+    """
+    Break a list into ``n`` rows, filling up each row to the maximum equal
+    length possible. For example::
+
+        >>> l = range(10)
+
+        >>> rows(l, 2)
+        [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]
+
+        >>> rows(l, 3)
+        [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9]]
+
+        >>> rows(l, 4)
+        [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
+
+        >>> rows(l, 5)
+        [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9]]
+
+        >>> rows(l, 9)
+        [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [], [], [], []]
+
+        # This filter will always return `n` rows, even if some are empty:
+        >>> rows(range(2), 3)
+        [[0], [1], []]
+    """
+    try:
+        n = int(n)
+        thelist = list(thelist)
+    except (ValueError, TypeError):
+        return [thelist]
+    list_len = len(thelist)
+    split = list_len // n
+
+    if list_len % n != 0:
+        split += 1
+    return [thelist[split*i:split*(i+1)] for i in range(n)]
+
+def rows_distributed(thelist, n):
+    """
+    Break a list into ``n`` rows, distributing columns as evenly as possible
+    across the rows. For example::
+
+        >>> l = range(10)
+
+        >>> rows_distributed(l, 2)
+        [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]
+
+        >>> rows_distributed(l, 3)
+        [[0, 1, 2, 3], [4, 5, 6], [7, 8, 9]]
+
+        >>> rows_distributed(l, 4)
+        [[0, 1, 2], [3, 4, 5], [6, 7], [8, 9]]
+
+        >>> rows_distributed(l, 5)
+        [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9]]
+
+        >>> rows_distributed(l, 9)
+        [[0, 1], [2], [3], [4], [5], [6], [7], [8], [9]]
+
+        # This filter will always return `n` rows, even if some are empty:
+        >>> rows(range(2), 3)
+        [[0], [1], []]
+    """
+    try:
+        n = int(n)
+        thelist = list(thelist)
+    except (ValueError, TypeError):
+        return [thelist]
+    list_len = len(thelist)
+    split = list_len // n
+
+    remainder = list_len % n
+    offset = 0
+    rows = []
+    for i in range(n):
+        if remainder:
+            start, end = (split+1)*i, (split+1)*(i+1)
+        else:
+            start, end = split*i+offset, split*(i+1)+offset
+        rows.append(thelist[start:end])
+        if remainder:
+            remainder -= 1
+            offset += 1
+    return rows
+
+def columns(thelist, n):
+    """
+    Break a list into ``n`` columns, filling up each column to the maximum equal
+    length possible. For example::
+
+        >>> from pprint import pprint
+        >>> for i in range(7, 11):
+        ...     print '%sx%s:' % (i, 3)
+        ...     pprint(columns(range(i), 3), width=20)
+        7x3:
+        [[0, 3, 6],
+         [1, 4],
+         [2, 5]]
+        8x3:
+        [[0, 3, 6],
+         [1, 4, 7],
+         [2, 5]]
+        9x3:
+        [[0, 3, 6],
+         [1, 4, 7],
+         [2, 5, 8]]
+        10x3:
+        [[0, 4, 8],
+         [1, 5, 9],
+         [2, 6],
+         [3, 7]]
+
+        # Note that this filter does not guarantee that `n` columns will be
+        # present:
+        >>> pprint(columns(range(4), 3), width=10)
+        [[0, 2],
+         [1, 3]]
+    """
+    try:
+        n = int(n)
+        thelist = list(thelist)
+    except (ValueError, TypeError):
+        return [thelist]
+    list_len = len(thelist)
+    split = list_len // n
+    if list_len % n != 0:
+        split += 1
+    return [thelist[i::split] for i in range(split)]
+
+register.filter(rows)
+register.filter(rows_distributed)
+register.filter(columns)
+
+def _test():
+    import doctest
+    doctest.testmod()
+
+if __name__ == "__main__":
+    _test()