Ticket #4394: fraction.diff
File fraction.diff, 5.6 KB (added by , 17 years ago) |
---|
-
django/contrib/humanize/templatetags/humanize.py
67 67 return value 68 68 return (_('one'), _('two'), _('three'), _('four'), _('five'), _('six'), _('seven'), _('eight'), _('nine'))[value-1] 69 69 register.filter(apnumber) 70 71 def _to_frac(x, maxdenom=10): 72 """ 73 Convert x to a common fraction. 74 75 Chooses the closest fraction to x with denominator <= maxdenom. 76 If x is closest to an integer, return that integer; otherwise, 77 return an (integer, numerator, denominator) tuple. 78 """ 79 80 assert x >= 0, "_to_frac only works on positive numbers." 81 82 intpart = int(x) 83 x -= intpart 84 85 bestfrac = 0,1 86 mindiff = x 87 88 for denom in range(1,maxdenom+1): 89 # for each denominator, there are two numerators to consider: 90 # the one below x and the one above x 91 for num in (int(x*denom), int(x*denom+1)): 92 diff = abs(float(num)/denom - x) 93 94 # compare using '<' rather than '<=' to ensure that the 95 # fraction with the smallest denominator is preferred 96 if diff < mindiff: 97 bestfrac = num, denom 98 mindiff = diff 99 100 if bestfrac[0] == 0: 101 return intpart 102 elif mindiff >= 1-x: 103 return intpart+1 104 else: 105 return intpart, bestfrac[0], bestfrac[1] 106 107 def html_fraction (number, maxdenom=10): 108 """ 109 Convert a float to a common fraction (or an integer if it is closer). 110 111 If the output is a fraction, the fraction part is wrapped in a span 112 with class "fraction" to enable styling of fractions. 113 """ 114 115 number = float(number) 116 frac = _to_frac(abs(number), maxdenom) 117 118 if type(frac) == int: 119 string = str(frac) 120 else: 121 intpart, numerator, denominator = frac 122 if intpart == 0: 123 string = '<span class="fraction"><sup>%i</sup>/<sub>%i</sub></span>' % frac[1:] 124 else: 125 string = '%i<span class="fraction"><sup>%i</sup>/<sub>%i</sub></span>' % frac 126 127 if number < 0: 128 return '-'+string 129 else: 130 return string 131 register.filter(html_fraction) 132 133 def text_fraction (number, maxdenom=10): 134 """Convert a float to a common fraction (or integer if it is closer).""" 135 136 number = float(number) 137 frac = _to_frac(abs(number), maxdenom) 138 139 if type(frac) == int: 140 string = str(frac) 141 else: 142 intpart, numerator, denominator = frac 143 if intpart == 0: 144 string = '%i/%i' % frac[1:] 145 else: 146 string = '%i %i/%i' % frac 147 148 if number < 0: 149 return '-'+string 150 else: 151 return string 152 register.filter(text_fraction) -
tests/regressiontests/humanize/tests.py
48 48 'seven', 'eight', 'nine', '10') 49 49 50 50 self.humanize_tester(test_list, result_list, 'apnumber') 51 52 def test_html_fraction(self): 53 test_list = ['0', '0.5', '1.667', '-0.25', '-1.75', '9.99'] 54 result_list = ['0', 55 '<span class="fraction"><sup>1</sup>/<sub>2</sub></span>', 56 '1<span class="fraction"><sup>2</sup>/<sub>3</sub></span>', 57 '-<span class="fraction"><sup>1</sup>/<sub>4</sub></span>', 58 '-1<span class="fraction"><sup>3</sup>/<sub>4</sub></span>', 59 '10'] 60 61 test_list = test_list + [float(num) for num in test_list] 62 result_list *= 2 63 64 self.humanize_tester(test_list, result_list, 'html_fraction') 65 66 def test_text_fraction(self): 67 test_list = ['0', '0.5', '1.667', '-0.25', '-1.75', '9.99'] 68 result_list = ['0', 69 '1/2', 70 '1 2/3', 71 '-1/4', 72 '-1 3/4', 73 '10'] 74 75 test_list = test_list + [float(num) for num in test_list] 76 result_list *= 2 77 78 self.humanize_tester(test_list, result_list, 'text_fraction') 51 79 52 80 if __name__ == '__main__': 53 81 unittest.main() -
AUTHORS
188 188 plisk 189 189 Daniel Poelzleithner <http://poelzi.org/> 190 190 polpak@yahoo.com 191 Max Rabkin <max.rabkin@gmail.com> 191 192 J. Rademaker 192 193 Michael Radziej <mir@noris.de> 193 194 Ramiro Morales <rm0@gmx.net> -
docs/add_ons.txt
135 135 136 136 You can pass in either an integer or a string representation of an integer. 137 137 138 text_fraction 139 ------------- 140 141 Converts a decimal fraction to a common fraction. 142 143 Examples: 144 145 * ``0.5`` becomes ``'1/2'`` 146 * ``9.99`` becomes ``'10'`` 147 * ``-1.25`` becomes ``'-1 1/4'`` 148 149 You can pass in either an integer or a string representation of an integer. 150 151 html_fraction 152 ------------- 153 154 Like text_fraction, but generates HTML so the fraction is rendered nicely. The 155 fractional part of the output is wrapped in ``<span class="fraction">`` tags. 156 138 157 flatpages 139 158 ========= 140 159