Coverage for apps/ptf/templatetags/partition.py: 91%

26 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2024-02-28 09:09 +0000

1""" 

2Template filters to partition lists into rows or columns. 

3 

4A common use-case is for splitting a list into a table with columns:: 

5 

6 {% load partition %} 

7 <table> 

8 {% for row in mylist|columns:3 %} 

9 <tr> 

10 {% for item in row %} 

11 <td>{{ item }}</td> 

12 {% endfor %} 

13 </tr> 

14 {% endfor %} 

15 </table> 

16""" 

17from django.template import Library 

18 

19register = Library() 

20 

21 

22def rows(thelist, n): 

23 """ 

24 Break a list into ``n`` rows, filling up each row to the maximum equal 

25 length possible. For example:: 

26 

27 >>> l = range(10) 

28 

29 >>> rows(l, 2) 

30 [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]] 

31 

32 >>> rows(l, 3) 

33 [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9]] 

34 

35 >>> rows(l, 4) 

36 [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]] 

37 

38 >>> rows(l, 5) 

39 [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9]] 

40 

41 >>> rows(l, 9) 

42 [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [], [], [], []] 

43 

44 # This filter will always return `n` rows, even if some are empty: 

45 >>> rows(range(2), 3) 

46 [[0], [1], []] 

47 """ 

48 try: 

49 n = int(n) 

50 thelist = list(thelist) 

51 except (ValueError, TypeError): 

52 return [thelist] 

53 list_len = len(thelist) 

54 split = list_len // n 

55 

56 if list_len % n != 0: 

57 split += 1 

58 return [thelist[split * i : split * (i + 1)] for i in range(n)] 

59 

60 

61def columns(thelist, n): 

62 """ 

63 Break a list into ``n`` columns, filling up each column to the maximum equal 

64 length possible. For example:: 

65 

66 >>> from pprint import pprint 

67 >>> for i in range(7, 11): 

68 ... print '%sx%s:' % (i, 3) 

69 ... pprint(columns(range(i), 3), width=20) 

70 7x3: 

71 [[0, 3, 6], 

72 [1, 4], 

73 [2, 5]] 

74 8x3: 

75 [[0, 3, 6], 

76 [1, 4, 7], 

77 [2, 5]] 

78 9x3: 

79 [[0, 3, 6], 

80 [1, 4, 7], 

81 [2, 5, 8]] 

82 10x3: 

83 [[0, 4, 8], 

84 [1, 5, 9], 

85 [2, 6], 

86 [3, 7]] 

87 

88 # Note that this filter does not guarantee that `n` columns will be 

89 # present: 

90 >>> pprint(columns(range(4), 3), width=10) 

91 [[0, 2], 

92 [1, 3]] 

93 """ 

94 try: 

95 n = int(n) 

96 thelist = list(thelist) 

97 except (ValueError, TypeError): 

98 return [thelist] 

99 list_len = len(thelist) 

100 split = list_len // n 

101 if list_len % n != 0: 101 ↛ 103line 101 didn't jump to line 103, because the condition on line 101 was never false

102 split += 1 

103 return [thelist[i::split] for i in range(split)] 

104 

105 

106register.filter(rows) 

107register.filter(columns)