# Ticket #4394: fraction3.diff

File fraction3.diff, 6.5 KB (added by max.rabkin@…, 12 years ago)

only uses unicode fractions which are supported by IE 5, and doesn't use sup and sub

• ## django/contrib/humanize/templatetags/humanize.py

 return value return (_('one'), _('two'), _('three'), _('four'), _('five'), _('six'), _('seven'), _('eight'), _('nine'))[value-1] register.filter(apnumber) def _to_frac(x, maxdenom=10): """ Convert x to a common fraction. Chooses the closest fraction to x with denominator <= maxdenom. If x is closest to an integer, return that integer; otherwise, return an (integer, numerator, denominator) tuple. """ assert x >= 0, "_to_frac only works on positive numbers." intpart = int(x) x -= intpart bestfrac = 0,1 mindiff = x for denom in range(1,maxdenom+1): # for each denominator, there are two numerators to consider: # the one below x and the one above x for num in (int(x*denom), int(x*denom+1)): diff = abs(float(num)/denom - x) # compare using '<' rather than '<=' to ensure that the # fraction with the smallest denominator is preferred if diff < mindiff: bestfrac = num, denom mindiff = diff if bestfrac[0] == 0: return intpart elif mindiff >= 1-x: return intpart+1 else: return intpart, bestfrac[0], bestfrac[1] _frac_entities = {(1,4): "¼", (1,2): "½", (3,4): "¾", (1, 3): "⅓", (2, 3): "⅔", # browser support for fifths and sixths is incomplete, so we don't use them by default #   (1, 5): "⅕", (2, 5): "⅖", (3, 5): "⅗", (4, 5): "⅘", #   (1, 6): "⅙", (5, 6): "⅚", (1, 8): "⅛", (3, 8): "⅜", (5, 8): "⅝", (7, 8): "⅞"} def html_fraction (number, maxdenom=10, useUnicode=True): """ Convert a float to a common fraction (or an integer if it is closer). If the output is a fraction, the fraction part is wrapped in a span with class "fraction" to enable styling of fractions. If useUnicode is true, unicode entities will be used where available. """ number = float(number) frac = _to_frac(abs(number), maxdenom) if type(frac) == int: string = str(frac) else: intpart, numerator, denominator = frac if useUnicode and (numerator, denominator) in _frac_entities: fracpart = _frac_entities[(numerator, denominator)] else: fracpart = (('' + '%i⁄' + '%i') % (numerator,denominator)) if intpart == 0: string = fracpart else: string = str(intpart) + fracpart if number < 0: return '-'+string else: return string register.filter(html_fraction) def text_fraction (number, maxdenom=10): """Convert a float to a common fraction (or integer if it is closer).""" number = float(number) frac = _to_frac(abs(number), maxdenom) if type(frac) == int: string = str(frac) else: intpart, numerator, denominator = frac if intpart == 0: string = '%i/%i' % frac[1:] else: string = '%i %i/%i' % frac if number < 0: return '-'+string else: return string register.filter(text_fraction)
• ## tests/regressiontests/humanize/tests.py

 'seven', 'eight', 'nine', '10') self.humanize_tester(test_list, result_list, 'apnumber') def test_html_fraction(self): test_list = ['0', '0.5', '1.667', '-0.25', '-1.75', '9.99', '-3.2857'] result_list = ['0', '½', '1⅔', '-¼', '-1¾', '10', '-327'] test_list = test_list + [float(num) for num in test_list] result_list *= 2 self.humanize_tester(test_list, result_list, 'html_fraction') def test_text_fraction(self): test_list = ['0', '0.5', '1.667', '-0.25', '-1.75', '9.99'] result_list = ['0', '1/2', '1 2/3', '-1/4', '-1 3/4', '10'] test_list = test_list + [float(num) for num in test_list] result_list *= 2 self.humanize_tester(test_list, result_list, 'text_fraction') if __name__ == '__main__': unittest.main()
• ## AUTHORS

 plisk Daniel Poelzleithner polpak@yahoo.com Max Rabkin J. Rademaker Michael Radziej Ramiro Morales