annotate babel/numbers.py @ 434:8f50e65273e6

Adjust tests to match the data in CLDR: German doesn't use a . as thousands separator, but a non-breaking whitespace.
author jruigrok
date Fri, 21 Aug 2009 12:26:00 +0000
parents ea0da9db79ef
children 22965265f699
rev   line source
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
1 # -*- coding: utf-8 -*-
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
2 #
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
3 # Copyright (C) 2007 Edgewall Software
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
4 # All rights reserved.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
5 #
245
be0c679d48c5 Revert accidential change of file header in [260].
cmlenz
parents: 244
diff changeset
6 # This software is licensed as described in the file COPYING, which
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
7 # you should have received as part of this distribution. The terms
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
8 # are also available at http://babel.edgewall.org/wiki/License.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
9 #
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
10 # This software consists of voluntary contributions made by many
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
11 # individuals. For the exact contribution history, see the revision
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
12 # history and logs, available at http://babel.edgewall.org/log/.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
13
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
14 """Locale dependent formatting and parsing of numeric data.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
15
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
16 The default locale for the functions in this module is determined by the
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
17 following environment variables, in that order:
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
18
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
19 * ``LC_NUMERIC``,
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
20 * ``LC_ALL``, and
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
21 * ``LANG``
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
22 """
246
e8bfc65444f3 Updated TODO-items in number.py.
jonas
parents: 245
diff changeset
23 # TODO:
e8bfc65444f3 Updated TODO-items in number.py.
jonas
parents: 245
diff changeset
24 # Padding and rounding increments in pattern:
e8bfc65444f3 Updated TODO-items in number.py.
jonas
parents: 245
diff changeset
25 # - http://www.unicode.org/reports/tr35/ (Appendix G.6)
243
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
26 import math
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
27 import re
218
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
28 try:
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
29 from decimal import Decimal
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
30 have_decimal = True
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
31 except ImportError:
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
32 have_decimal = False
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
33
72
4dcdb1d367ec More explicit module-level function names in `babel.core`. Added `Locale.negotiate` class method.
cmlenz
parents: 50
diff changeset
34 from babel.core import default_locale, Locale
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
35
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
36 __all__ = ['format_number', 'format_decimal', 'format_currency',
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
37 'format_percent', 'format_scientific', 'parse_number',
32
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
38 'parse_decimal', 'NumberFormatError']
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
39 __docformat__ = 'restructuredtext en'
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
40
72
4dcdb1d367ec More explicit module-level function names in `babel.core`. Added `Locale.negotiate` class method.
cmlenz
parents: 50
diff changeset
41 LC_NUMERIC = default_locale('LC_NUMERIC')
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
42
385
cd8761c6f1a6 Improve CLDR import of currency-related data to ignore unsupported features such as symbol choice patterns and pluralized display names. See #93.
cmlenz
parents: 375
diff changeset
43 def get_currency_name(currency, locale=LC_NUMERIC):
cd8761c6f1a6 Improve CLDR import of currency-related data to ignore unsupported features such as symbol choice patterns and pluralized display names. See #93.
cmlenz
parents: 375
diff changeset
44 """Return the name used by the locale for the specified currency.
cd8761c6f1a6 Improve CLDR import of currency-related data to ignore unsupported features such as symbol choice patterns and pluralized display names. See #93.
cmlenz
parents: 375
diff changeset
45
cd8761c6f1a6 Improve CLDR import of currency-related data to ignore unsupported features such as symbol choice patterns and pluralized display names. See #93.
cmlenz
parents: 375
diff changeset
46 >>> get_currency_name('USD', 'en_US')
cd8761c6f1a6 Improve CLDR import of currency-related data to ignore unsupported features such as symbol choice patterns and pluralized display names. See #93.
cmlenz
parents: 375
diff changeset
47 u'US Dollar'
cd8761c6f1a6 Improve CLDR import of currency-related data to ignore unsupported features such as symbol choice patterns and pluralized display names. See #93.
cmlenz
parents: 375
diff changeset
48
cd8761c6f1a6 Improve CLDR import of currency-related data to ignore unsupported features such as symbol choice patterns and pluralized display names. See #93.
cmlenz
parents: 375
diff changeset
49 :param currency: the currency code
cd8761c6f1a6 Improve CLDR import of currency-related data to ignore unsupported features such as symbol choice patterns and pluralized display names. See #93.
cmlenz
parents: 375
diff changeset
50 :param locale: the `Locale` object or locale identifier
cd8761c6f1a6 Improve CLDR import of currency-related data to ignore unsupported features such as symbol choice patterns and pluralized display names. See #93.
cmlenz
parents: 375
diff changeset
51 :return: the currency symbol
cd8761c6f1a6 Improve CLDR import of currency-related data to ignore unsupported features such as symbol choice patterns and pluralized display names. See #93.
cmlenz
parents: 375
diff changeset
52 :rtype: `unicode`
cd8761c6f1a6 Improve CLDR import of currency-related data to ignore unsupported features such as symbol choice patterns and pluralized display names. See #93.
cmlenz
parents: 375
diff changeset
53 :since: version 0.9.4
cd8761c6f1a6 Improve CLDR import of currency-related data to ignore unsupported features such as symbol choice patterns and pluralized display names. See #93.
cmlenz
parents: 375
diff changeset
54 """
cd8761c6f1a6 Improve CLDR import of currency-related data to ignore unsupported features such as symbol choice patterns and pluralized display names. See #93.
cmlenz
parents: 375
diff changeset
55 return Locale.parse(locale).currencies.get(currency, currency)
cd8761c6f1a6 Improve CLDR import of currency-related data to ignore unsupported features such as symbol choice patterns and pluralized display names. See #93.
cmlenz
parents: 375
diff changeset
56
125
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
57 def get_currency_symbol(currency, locale=LC_NUMERIC):
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
58 """Return the symbol used by the locale for the specified currency.
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
59
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
60 >>> get_currency_symbol('USD', 'en_US')
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
61 u'$'
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
62
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
63 :param currency: the currency code
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
64 :param locale: the `Locale` object or locale identifier
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
65 :return: the currency symbol
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
66 :rtype: `unicode`
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
67 """
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
68 return Locale.parse(locale).currency_symbols.get(currency, currency)
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
69
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
70 def get_decimal_symbol(locale=LC_NUMERIC):
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
71 """Return the symbol used by the locale to separate decimal fractions.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
72
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
73 >>> get_decimal_symbol('en_US')
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
74 u'.'
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
75
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
76 :param locale: the `Locale` object or locale identifier
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
77 :return: the decimal symbol
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
78 :rtype: `unicode`
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
79 """
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
80 return Locale.parse(locale).number_symbols.get('decimal', u'.')
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
81
244
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
82 def get_plus_sign_symbol(locale=LC_NUMERIC):
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
83 """Return the plus sign symbol used by the current locale.
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
84
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
85 >>> get_plus_sign_symbol('en_US')
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
86 u'+'
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
87
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
88 :param locale: the `Locale` object or locale identifier
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
89 :return: the plus sign symbol
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
90 :rtype: `unicode`
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
91 """
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
92 return Locale.parse(locale).number_symbols.get('plusSign', u'+')
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
93
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
94 def get_minus_sign_symbol(locale=LC_NUMERIC):
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
95 """Return the plus sign symbol used by the current locale.
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
96
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
97 >>> get_minus_sign_symbol('en_US')
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
98 u'-'
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
99
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
100 :param locale: the `Locale` object or locale identifier
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
101 :return: the plus sign symbol
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
102 :rtype: `unicode`
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
103 """
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
104 return Locale.parse(locale).number_symbols.get('minusSign', u'-')
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
105
243
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
106 def get_exponential_symbol(locale=LC_NUMERIC):
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
107 """Return the symbol used by the locale to separate mantissa and exponent.
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
108
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
109 >>> get_exponential_symbol('en_US')
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
110 u'E'
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
111
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
112 :param locale: the `Locale` object or locale identifier
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
113 :return: the exponential symbol
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
114 :rtype: `unicode`
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
115 """
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
116 return Locale.parse(locale).number_symbols.get('exponential', u'E')
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
117
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
118 def get_group_symbol(locale=LC_NUMERIC):
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
119 """Return the symbol used by the locale to separate groups of thousands.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
120
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
121 >>> get_group_symbol('en_US')
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
122 u','
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
123
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
124 :param locale: the `Locale` object or locale identifier
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
125 :return: the group symbol
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
126 :rtype: `unicode`
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
127 """
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
128 return Locale.parse(locale).number_symbols.get('group', u',')
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
129
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
130 def format_number(number, locale=LC_NUMERIC):
101
1312ad6b624d Add wrapper class bundling the various formatting functions bound to a specific locale and time-zone.
cmlenz
parents: 72
diff changeset
131 """Return the given number formatted for a specific locale.
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
132
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
133 >>> format_number(1099, locale='en_US')
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
134 u'1,099'
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
135
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
136 :param number: the number to format
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
137 :param locale: the `Locale` object or locale identifier
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
138 :return: the formatted number
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
139 :rtype: `unicode`
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
140 """
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
141 # Do we really need this one?
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
142 return format_decimal(number, locale=locale)
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
143
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
144 def format_decimal(number, format=None, locale=LC_NUMERIC):
434
8f50e65273e6 Adjust tests to match the data in CLDR: German doesn't use a . as thousands
jruigrok
parents: 414
diff changeset
145 u"""Return the given decimal number formatted for a specific locale.
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
146
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
147 >>> format_decimal(1.2345, locale='en_US')
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
148 u'1.234'
50
fa8a27b80eb4 Added round-half-even (banker's rounding) support.
jonas
parents: 39
diff changeset
149 >>> format_decimal(1.2346, locale='en_US')
fa8a27b80eb4 Added round-half-even (banker's rounding) support.
jonas
parents: 39
diff changeset
150 u'1.235'
fa8a27b80eb4 Added round-half-even (banker's rounding) support.
jonas
parents: 39
diff changeset
151 >>> format_decimal(-1.2346, locale='en_US')
fa8a27b80eb4 Added round-half-even (banker's rounding) support.
jonas
parents: 39
diff changeset
152 u'-1.235'
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
153 >>> format_decimal(1.2345, locale='sv_SE')
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
154 u'1,234'
50
fa8a27b80eb4 Added round-half-even (banker's rounding) support.
jonas
parents: 39
diff changeset
155 >>> format_decimal(12345, locale='de')
434
8f50e65273e6 Adjust tests to match the data in CLDR: German doesn't use a . as thousands
jruigrok
parents: 414
diff changeset
156 u'12\\xa0345'
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
157
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
158 The appropriate thousands grouping and the decimal separator are used for
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
159 each locale:
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
160
125
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
161 >>> format_decimal(12345.5, locale='en_US')
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
162 u'12,345.5'
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
163
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
164 :param number: the number to format
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
165 :param format:
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
166 :param locale: the `Locale` object or locale identifier
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
167 :return: the formatted decimal number
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
168 :rtype: `unicode`
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
169 """
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
170 locale = Locale.parse(locale)
125
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
171 if not format:
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
172 format = locale.decimal_formats.get(format)
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
173 pattern = parse_pattern(format)
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
174 return pattern.apply(number, locale)
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
175
125
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
176 def format_currency(number, currency, format=None, locale=LC_NUMERIC):
133
7d3d03855980 Minor doc fixes.
cmlenz
parents: 127
diff changeset
177 u"""Return formatted currency value.
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
178
32
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
179 >>> format_currency(1099.98, 'USD', locale='en_US')
125
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
180 u'$1,099.98'
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
181 >>> format_currency(1099.98, 'USD', locale='es_CO')
375
369300a7ebd3 Implement support for aliases in the CLDR data. Closes #68. Also, update to CLDR 1.6, and a much improved `dump_data` script.
cmlenz
parents: 357
diff changeset
182 u'US$\\xa01.099,98'
125
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
183 >>> format_currency(1099.98, 'EUR', locale='de_DE')
434
8f50e65273e6 Adjust tests to match the data in CLDR: German doesn't use a . as thousands
jruigrok
parents: 414
diff changeset
184 u'1\\xa0099,98\\xa0\\u20ac'
125
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
185
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
186 The pattern can also be specified explicitly:
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
187
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
188 >>> format_currency(1099.98, 'EUR', u'\xa4\xa4 #,##0.00', locale='en_US')
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
189 u'EUR 1,099.98'
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
190
26
710090104678 * Reduce size of locale data pickles by only storing the data provided by each locale itself, and merging inherited data at runtime.
cmlenz
parents: 22
diff changeset
191 :param number: the number to format
32
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
192 :param currency: the currency code
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
193 :param locale: the `Locale` object or locale identifier
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
194 :return: the formatted currency value
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
195 :rtype: `unicode`
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
196 """
125
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
197 locale = Locale.parse(locale)
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
198 if not format:
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
199 format = locale.currency_formats.get(format)
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
200 pattern = parse_pattern(format)
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
201 return pattern.apply(number, locale, currency=currency)
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
202
26
710090104678 * Reduce size of locale data pickles by only storing the data provided by each locale itself, and merging inherited data at runtime.
cmlenz
parents: 22
diff changeset
203 def format_percent(number, format=None, locale=LC_NUMERIC):
101
1312ad6b624d Add wrapper class bundling the various formatting functions bound to a specific locale and time-zone.
cmlenz
parents: 72
diff changeset
204 """Return formatted percent value for a specific locale.
22
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
205
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
206 >>> format_percent(0.34, locale='en_US')
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
207 u'34%'
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
208 >>> format_percent(25.1234, locale='en_US')
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
209 u'2,512%'
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
210 >>> format_percent(25.1234, locale='sv_SE')
233
bc22f5aef216 Upgraded to CLDR 1.5 and improved timezone formatting.
cmlenz
parents: 218
diff changeset
211 u'2\\xa0512\\xa0%'
22
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
212
126
0733e852a9e9 Add test for permille number format.
cmlenz
parents: 125
diff changeset
213 The format pattern can also be specified explicitly:
0733e852a9e9 Add test for permille number format.
cmlenz
parents: 125
diff changeset
214
0733e852a9e9 Add test for permille number format.
cmlenz
parents: 125
diff changeset
215 >>> format_percent(25.1234, u'#,##0\u2030', locale='en_US')
0733e852a9e9 Add test for permille number format.
cmlenz
parents: 125
diff changeset
216 u'25,123\u2030'
0733e852a9e9 Add test for permille number format.
cmlenz
parents: 125
diff changeset
217
22
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
218 :param number: the percent number to format
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
219 :param format:
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
220 :param locale: the `Locale` object or locale identifier
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
221 :return: the formatted percent number
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
222 :rtype: `unicode`
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
223 """
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
224 locale = Locale.parse(locale)
125
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
225 if not format:
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
226 format = locale.percent_formats.get(format)
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
227 pattern = parse_pattern(format)
26
710090104678 * Reduce size of locale data pickles by only storing the data provided by each locale itself, and merging inherited data at runtime.
cmlenz
parents: 22
diff changeset
228 return pattern.apply(number, locale)
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
229
243
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
230 def format_scientific(number, format=None, locale=LC_NUMERIC):
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
231 """Return value formatted in scientific notation for a specific locale.
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
232
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
233 >>> format_scientific(10000, locale='en_US')
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
234 u'1E4'
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
235
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
236 The format pattern can also be specified explicitly:
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
237
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
238 >>> format_scientific(1234567, u'##0E00', locale='en_US')
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
239 u'1.23E06'
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
240
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
241 :param number: the number to format
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
242 :param format:
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
243 :param locale: the `Locale` object or locale identifier
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
244 :return: value formatted in scientific notation.
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
245 :rtype: `unicode`
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
246 """
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
247 locale = Locale.parse(locale)
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
248 if not format:
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
249 format = locale.scientific_formats.get(format)
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
250 pattern = parse_pattern(format)
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
251 return pattern.apply(number, locale)
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
252
32
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
253
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
254 class NumberFormatError(ValueError):
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
255 """Exception raised when a string cannot be parsed into a number."""
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
256
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
257
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
258 def parse_number(string, locale=LC_NUMERIC):
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
259 """Parse localized number string into a long integer.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
260
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
261 >>> parse_number('1,099', locale='en_US')
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
262 1099L
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
263 >>> parse_number('1.099', locale='de_DE')
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
264 1099L
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
265
32
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
266 When the given string cannot be parsed, an exception is raised:
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
267
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
268 >>> parse_number('1.099,98', locale='de')
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
269 Traceback (most recent call last):
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
270 ...
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
271 NumberFormatError: '1.099,98' is not a valid number
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
272
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
273 :param string: the string to parse
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
274 :param locale: the `Locale` object or locale identifier
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
275 :return: the parsed number
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
276 :rtype: `long`
32
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
277 :raise `NumberFormatError`: if the string can not be converted to a number
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
278 """
32
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
279 try:
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
280 return long(string.replace(get_group_symbol(locale), ''))
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
281 except ValueError:
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
282 raise NumberFormatError('%r is not a valid number' % string)
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
283
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
284 def parse_decimal(string, locale=LC_NUMERIC):
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
285 """Parse localized decimal string into a float.
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
286
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
287 >>> parse_decimal('1,099.98', locale='en_US')
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
288 1099.98
32
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
289 >>> parse_decimal('1.099,98', locale='de')
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
290 1099.98
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
291
32
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
292 When the given string cannot be parsed, an exception is raised:
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
293
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
294 >>> parse_decimal('2,109,998', locale='de')
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
295 Traceback (most recent call last):
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
296 ...
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
297 NumberFormatError: '2,109,998' is not a valid decimal number
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
298
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
299 :param string: the string to parse
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
300 :param locale: the `Locale` object or locale identifier
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
301 :return: the parsed decimal number
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
302 :rtype: `float`
32
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
303 :raise `NumberFormatError`: if the string can not be converted to a
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
304 decimal number
1
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
305 """
f71ca60f2a4a Import of initial code base.
cmlenz
parents:
diff changeset
306 locale = Locale.parse(locale)
32
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
307 try:
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
308 return float(string.replace(get_group_symbol(locale), '')
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
309 .replace(get_decimal_symbol(locale), '.'))
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
310 except ValueError:
48cf004aa357 Started docs on number formatting/parsing.
cmlenz
parents: 26
diff changeset
311 raise NumberFormatError('%r is not a valid decimal number' % string)
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
312
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
313
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
314 PREFIX_END = r'[^0-9@#.,]'
243
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
315 NUMBER_TOKEN = r'[0-9@#.\-,E+]'
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
316
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
317 PREFIX_PATTERN = r"(?P<prefix>(?:'[^']*'|%s)*)" % PREFIX_END
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
318 NUMBER_PATTERN = r"(?P<number>%s+)" % NUMBER_TOKEN
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
319 SUFFIX_PATTERN = r"(?P<suffix>.*)"
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
320
127
0f3a08b1c7ae Add a couple of CLI tests.
cmlenz
parents: 126
diff changeset
321 number_re = re.compile(r"%s%s%s" % (PREFIX_PATTERN, NUMBER_PATTERN,
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
322 SUFFIX_PATTERN))
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
323
218
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
324 def split_number(value):
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
325 """Convert a number into a (intasstring, fractionasstring) tuple"""
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
326 if have_decimal and isinstance(value, Decimal):
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
327 text = str(value)
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
328 else:
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
329 text = ('%.9f' % value).rstrip('0')
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
330 if '.' in text:
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
331 a, b = text.split('.', 1)
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
332 if b == '0':
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
333 b = ''
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
334 else:
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
335 a, b = text, ''
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
336 return a, b
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
337
212
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
338 def bankersround(value, ndigits=0):
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
339 """Round a number to a given precision.
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
340
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
341 Works like round() except that the round-half-even (banker's rounding)
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
342 algorithm is used instead of round-half-up.
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
343
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
344 >>> bankersround(5.5, 0)
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
345 6.0
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
346 >>> bankersround(6.5, 0)
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
347 6.0
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
348 >>> bankersround(-6.5, 0)
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
349 -6.0
218
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
350 >>> bankersround(1234.0, -2)
212
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
351 1200.0
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
352 """
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
353 sign = int(value < 0) and -1 or 1
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
354 value = abs(value)
218
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
355 a, b = split_number(value)
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
356 digits = a + b
212
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
357 add = 0
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
358 i = len(a) + ndigits
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
359 if i < 0 or i >= len(digits):
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
360 pass
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
361 elif digits[i] > '5':
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
362 add = 1
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
363 elif digits[i] == '5' and digits[i-1] in '13579':
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
364 add = 1
218
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
365 scale = 10**ndigits
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
366 if have_decimal and isinstance(value, Decimal):
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
367 return Decimal(int(value * scale + add)) / scale * sign
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
368 else:
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
369 return float(int(value * scale + add)) / scale * sign
212
02f2c7b9a372 Switched to using our own round() implementation.
jonas
parents: 211
diff changeset
370
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
371 def parse_pattern(pattern):
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
372 """Parse number format patterns"""
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
373 if isinstance(pattern, NumberPattern):
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
374 return pattern
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
375
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
376 # Do we have a negative subpattern?
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
377 if ';' in pattern:
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
378 pattern, neg_pattern = pattern.split(';', 1)
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
379 pos_prefix, number, pos_suffix = number_re.search(pattern).groups()
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
380 neg_prefix, _, neg_suffix = number_re.search(neg_pattern).groups()
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
381 else:
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
382 pos_prefix, number, pos_suffix = number_re.search(pattern).groups()
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
383 neg_prefix = '-' + pos_prefix
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
384 neg_suffix = pos_suffix
243
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
385 if 'E' in number:
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
386 number, exp = number.split('E', 1)
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
387 else:
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
388 exp = None
211
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
389 if '@' in number:
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
390 if '.' in number and '0' in number:
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
391 raise ValueError('Significant digit patterns can not contain '
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
392 '"@" or "0"')
22
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
393 if '.' in number:
414
ea0da9db79ef fix Python 2.3 compat: rearrange set/itemgetter/rsplit/sorted/unicode.decode
pjenvey
parents: 385
diff changeset
394 #integer, fraction = number.rsplit('.', 1)
ea0da9db79ef fix Python 2.3 compat: rearrange set/itemgetter/rsplit/sorted/unicode.decode
pjenvey
parents: 385
diff changeset
395 # 2.3 compat: this is rsplit
ea0da9db79ef fix Python 2.3 compat: rearrange set/itemgetter/rsplit/sorted/unicode.decode
pjenvey
parents: 385
diff changeset
396 parts = number.split('.')
ea0da9db79ef fix Python 2.3 compat: rearrange set/itemgetter/rsplit/sorted/unicode.decode
pjenvey
parents: 385
diff changeset
397 integer, fraction = '.'.join(parts[:-1]), parts[-1]
22
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
398 else:
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
399 integer = number
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
400 fraction = ''
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
401 min_frac = max_frac = 0
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
402
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
403 def parse_precision(p):
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
404 """Calculate the min and max allowed digits"""
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
405 min = max = 0
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
406 for c in p:
211
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
407 if c in '@0':
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
408 min += 1
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
409 max += 1
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
410 elif c == '#':
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
411 max += 1
211
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
412 elif c == ',':
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
413 continue
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
414 else:
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
415 break
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
416 return min, max
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
417
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
418 def parse_grouping(p):
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
419 """Parse primary and secondary digit grouping
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
420
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
421 >>> parse_grouping('##')
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
422 0, 0
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
423 >>> parse_grouping('#,###')
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
424 3, 3
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
425 >>> parse_grouping('#,####,###')
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
426 3, 4
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
427 """
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
428 width = len(p)
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
429 g1 = p.rfind(',')
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
430 if g1 == -1:
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
431 return 1000, 1000
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
432 g1 = width - g1 - 1
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
433 g2 = p[:-g1 - 1].rfind(',')
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
434 if g2 == -1:
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
435 return g1, g1
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
436 g2 = width - g1 - g2 - 2
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
437 return g1, g2
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
438
244
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
439 int_prec = parse_precision(integer)
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
440 frac_prec = parse_precision(fraction)
243
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
441 if exp:
244
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
442 frac_prec = parse_precision(integer+fraction)
243
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
443 exp_plus = exp.startswith('+')
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
444 exp = exp.lstrip('+')
244
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
445 exp_prec = parse_precision(exp)
243
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
446 else:
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
447 exp_plus = None
244
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
448 exp_prec = None
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
449 grouping = parse_grouping(integer)
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
450 return NumberPattern(pattern, (pos_prefix, neg_prefix),
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
451 (pos_suffix, neg_suffix), grouping,
244
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
452 int_prec, frac_prec,
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
453 exp_prec, exp_plus)
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
454
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
455
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
456 class NumberPattern(object):
22
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
457
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
458 def __init__(self, pattern, prefix, suffix, grouping,
244
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
459 int_prec, frac_prec, exp_prec, exp_plus):
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
460 self.pattern = pattern
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
461 self.prefix = prefix
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
462 self.suffix = suffix
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
463 self.grouping = grouping
244
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
464 self.int_prec = int_prec
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
465 self.frac_prec = frac_prec
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
466 self.exp_prec = exp_prec
243
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
467 self.exp_plus = exp_plus
22
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
468 if '%' in ''.join(self.prefix + self.suffix):
218
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
469 self.scale = 100
22
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
470 elif u'‰' in ''.join(self.prefix + self.suffix):
218
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
471 self.scale = 1000
22
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
472 else:
218
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
473 self.scale = 1
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
474
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
475 def __repr__(self):
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
476 return '<%s %r>' % (type(self).__name__, self.pattern)
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
477
125
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
478 def apply(self, value, locale, currency=None):
22
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
479 value *= self.scale
244
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
480 is_negative = int(value < 0)
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
481 if self.exp_prec: # Scientific notation
243
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
482 value = abs(value)
357
68e45b6ac5bb Fix scientific notation for 0. closes #99
aronacher
parents: 246
diff changeset
483 if value:
68e45b6ac5bb Fix scientific notation for 0. closes #99
aronacher
parents: 246
diff changeset
484 exp = int(math.floor(math.log(value, 10)))
68e45b6ac5bb Fix scientific notation for 0. closes #99
aronacher
parents: 246
diff changeset
485 else:
68e45b6ac5bb Fix scientific notation for 0. closes #99
aronacher
parents: 246
diff changeset
486 exp = 0
243
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
487 # Minimum number of integer digits
244
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
488 if self.int_prec[0] == self.int_prec[1]:
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
489 exp -= self.int_prec[0] - 1
243
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
490 # Exponent grouping
244
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
491 elif self.int_prec[1]:
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
492 exp = int(exp) / self.int_prec[1] * self.int_prec[1]
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
493 if not have_decimal or not isinstance(value, Decimal):
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
494 value = float(value)
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
495 if exp < 0:
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
496 value = value * 10**(-exp)
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
497 else:
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
498 value = value / 10**exp
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
499 exp_sign = ''
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
500 if exp < 0:
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
501 exp_sign = get_minus_sign_symbol(locale)
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
502 elif self.exp_plus:
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
503 exp_sign = get_plus_sign_symbol(locale)
243
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
504 exp = abs(exp)
244
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
505 number = u'%s%s%s%s' % \
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
506 (self._format_sigdig(value, self.frac_prec[0],
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
507 self.frac_prec[1]),
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
508 get_exponential_symbol(locale), exp_sign,
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
509 self._format_int(str(exp), self.exp_prec[0],
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
510 self.exp_prec[1], locale))
243
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
511 elif '@' in self.pattern: # Is it a siginificant digits pattern?
211
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
512 text = self._format_sigdig(abs(value),
244
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
513 self.int_prec[0],
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
514 self.int_prec[1])
211
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
515 if '.' in text:
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
516 a, b = text.split('.')
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
517 a = self._format_int(a, 0, 1000, locale)
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
518 if b:
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
519 b = get_decimal_symbol(locale) + b
244
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
520 number = a + b
211
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
521 else:
244
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
522 number = self._format_int(text, 0, 1000, locale)
211
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
523 else: # A normal number pattern
218
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
524 a, b = split_number(bankersround(abs(value),
244
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
525 self.frac_prec[1]))
218
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
526 b = b or '0'
244
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
527 a = self._format_int(a, self.int_prec[0],
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
528 self.int_prec[1], locale)
211
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
529 b = self._format_frac(b, locale)
244
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
530 number = a + b
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
531 retval = u'%s%s%s' % (self.prefix[is_negative], number,
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
532 self.suffix[is_negative])
125
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
533 if u'¤' in retval:
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
534 retval = retval.replace(u'¤¤', currency.upper())
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
535 retval = retval.replace(u'¤', get_currency_symbol(currency, locale))
b75ae5def3b1 Add currency formatting.
cmlenz
parents: 101
diff changeset
536 return retval
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
537
211
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
538 def _format_sigdig(self, value, min, max):
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
539 """Convert value to a string.
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
540
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
541 The resulting string will contain between (min, max) number of
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
542 significant digits.
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
543 """
218
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
544 a, b = split_number(value)
211
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
545 ndecimals = len(a)
218
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
546 if a == '0' and b != '':
211
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
547 ndecimals = 0
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
548 while b.startswith('0'):
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
549 b = b[1:]
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
550 ndecimals -= 1
218
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
551 a, b = split_number(bankersround(value, max - ndecimals))
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
552 digits = len((a + b).lstrip('0'))
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
553 if not digits:
211
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
554 digits = 1
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
555 # Figure out if we need to add any trailing '0':s
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
556 if len(a) >= max and a != '0':
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
557 return a
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
558 if digits < min:
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
559 b += ('0' * (min - digits))
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
560 if b:
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
561 return '%s.%s' % (a, b)
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
562 return a
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
563
1adcbeb4607b Added support for siginificant digits in number patterns.
jonas
parents: 137
diff changeset
564 def _format_int(self, value, min, max, locale):
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
565 width = len(value)
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
566 if width < min:
243
5e4b1fd6b348 Added initial support for scientific notation patterns.
jonas
parents: 233
diff changeset
567 value = '0' * (min - width) + value
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
568 gsize = self.grouping[0]
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
569 ret = ''
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
570 symbol = get_group_symbol(locale)
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
571 while len(value) > gsize:
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
572 ret = symbol + value[-gsize:] + ret
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
573 value = value[:-gsize]
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
574 gsize = self.grouping[1]
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
575 return value + ret
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
576
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
577 def _format_frac(self, value, locale):
244
222ccdeef393 Added `Decimal` support to the scientific notation formatter and some code cleanup. This closes #52.
jonas
parents: 243
diff changeset
578 min, max = self.frac_prec
218
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
579 if len(value) < min:
b566f483b763 Added Decimal support to the number formatter.
jonas
parents: 212
diff changeset
580 value += ('0' * (min - len(value)))
22
7d37639a7411 Implemented babel.numbers.format_percent
jonas
parents: 9
diff changeset
581 if max == 0 or (min == 0 and int(value) == 0):
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
582 return ''
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
583 width = len(value)
50
fa8a27b80eb4 Added round-half-even (banker's rounding) support.
jonas
parents: 39
diff changeset
584 while len(value) > min and value[-1] == '0':
fa8a27b80eb4 Added round-half-even (banker's rounding) support.
jonas
parents: 39
diff changeset
585 value = value[:-1]
9
3be73c6f01f1 Add basic support for number format patterns.
jonas
parents: 1
diff changeset
586 return get_decimal_symbol(locale) + value
Copyright (C) 2012-2017 Edgewall Software