Returns the given int or float as a string of numerals. By default, the fractional part is rounded to two decimals. For example: numerals(4011) => four thousand and eleven numerals(2.25) => two point twenty-five numerals(2.249) => two point twenty-five
(n, round=2)
| 158 | #--- NUMBER TO STRING ------------------------------------------------------------------------------ |
| 159 | |
| 160 | def numerals(n, round=2): |
| 161 | """ Returns the given int or float as a string of numerals. |
| 162 | By default, the fractional part is rounded to two decimals. |
| 163 | For example: |
| 164 | numerals(4011) => four thousand and eleven |
| 165 | numerals(2.25) => two point twenty-five |
| 166 | numerals(2.249) => two point twenty-five |
| 167 | numerals(2.249, round=3) => two point two hundred and forty-nine |
| 168 | Note: due to rounding of float values, float(number(x)) == x is not always True. |
| 169 | """ |
| 170 | if isinstance(n, basestring): |
| 171 | if n.isdigit(): |
| 172 | n = int(n) |
| 173 | else: |
| 174 | # If the float is given as a string, extract the length of the fractional part. |
| 175 | if round is None: |
| 176 | round = len(n.split(".")[1]) |
| 177 | n = float(n) |
| 178 | # For negative numbers, simply prepend minus. |
| 179 | if n < 0: |
| 180 | return "%s %s" % (MINUS, numerals(abs(n))) |
| 181 | # Split the number into integral and fractional part. |
| 182 | # Converting the integral part to a long ensures a better accuracy during the recursion. |
| 183 | i = long(n//1) |
| 184 | f = n-i |
| 185 | # The remainder, which we will stringify in recursion. |
| 186 | r = 0 |
| 187 | if i in NUMERALS_INVERSE: # 11 => eleven |
| 188 | # Map numbers from the dictionary to numerals: 11 => "eleven". |
| 189 | s = NUMERALS_INVERSE[i] |
| 190 | elif i < 100: |
| 191 | # Map tens + digits: 75 => 70+5 => "seventy-five". |
| 192 | s = numerals((i//10)*10) + "-" + numerals(i%10) |
| 193 | elif i < 1000: |
| 194 | # Map hundreds: 500 => 5*100 => "five hundred". |
| 195 | # Store the remainders (tens + digits). |
| 196 | s = numerals(i//100) + " " + ORDER[0] |
| 197 | r = i % 100 |
| 198 | else: |
| 199 | # Map thousands by extracting the order (thousand/million/billion/...). |
| 200 | # Store and recurse the remainder. |
| 201 | s = "" |
| 202 | o, base = 1, 1000 |
| 203 | while i > base: |
| 204 | o+=1; base*=1000 |
| 205 | while o > len(ORDER)-1: |
| 206 | s += " "+ORDER[-1] # This occurs for consecutive thousands: million vigintillion. |
| 207 | o -= len(ORDER)-1 |
| 208 | s = "%s %s%s" % (numerals(i//(base/1000)), (o>1 and ORDER[o-1] or ""), s) |
| 209 | r = i % (base/1000) |
| 210 | if f != 0: |
| 211 | # Map the fractional part: "two point twenty-five" => 2.25. |
| 212 | # We cast it to a string first to find all the leading zeros. |
| 213 | # This actually seems more accurate than calculating the leading zeros, |
| 214 | # see also: http://python.org/doc/2.5.1/tut/node16.html. |
| 215 | # Some rounding occurs. |
| 216 | f = ("%." + str(round is None and 2 or round) + "f") % f |
| 217 | f = f.replace("0.","",1).rstrip("0") |