I cobbled together a function from various sources that takes an integer and returns it as its respective English word formatted as a string. The function is as follows:
def int2word(num, separator="-"):
"""Transforms integers =< 999 into English words
Parameters
----------
num : int
separator : str
Returns
-------
words : str
"""
ones_and_teens = {0: "Zero", 1: 'One', 2: 'Two', 3: 'Three',
4: 'Four', 5: 'Five', 6: 'Six', 7: 'Seven',
8: 'Eight', 9: 'Nine', 10: 'Ten', 11: 'Eleven',
12: 'Twelve', 13: 'Thirteen', 14: 'Fourteen',
15: 'Fifteen', 16: 'Sixteen', 17: 'Seventeen',
18: 'Eighteen', 19: 'Nineteen'}
twenty2ninety = {2: 'Twenty', 3: 'Thirty', 4: 'Forty', 5: 'Fifty',
6: 'Sixty', 7: 'Seventy', 8: 'Eighty', 9: 'Ninety', 0: ""}
if 0 <= num < 19:
return ones_and_teens[num]
elif 20 <= num <= 99:
tens, below_ten = divmod(num, 10)
if below_ten > 0:
words = twenty2ninety[tens] + separator + \
ones_and_teens[below_ten].lower()
else:
words = twenty2ninety[tens]
return words
elif 100 <= num <= 999:
hundreds, below_hundred = divmod(num, 100)
tens, below_ten = divmod(below_hundred, 10)
if below_hundred == 0:
words = ones_and_teens[hundreds] + separator + "hundred"
elif below_ten == 0:
words = ones_and_teens[hundreds] + separator + \
"hundred" + separator + twenty2ninety[tens].lower()
else:
if tens > 0:
words = ones_and_teens[hundreds] + separator + "hundred" + separator + twenty2ninety[
tens].lower() + separator + ones_and_teens[below_ten].lower()
else:
words = ones_and_teens[
hundreds] + separator + "hundred" + separator + ones_and_teens[below_ten].lower()
return words
else:
print("num out of range")
2 Answers 2
There's an easier way.
We have the num2words
module which can be easily installed via pip
:
pip install num2words
The advantage of this module is that it supports multiple languages:
- en (English, default)
- fr (French)
- de (German)
- es (Spanish)
- lt (Lithuanian)
- lv (Latvian)
- en_GB (British English)
- en_IN (Indian English)
- no (Norwegian)
- pl (Polish)
- ru (Russian)
- dk (Danish)
- pt_BR (Brazilian Portuguese)
More, you can even generate ordinal numbers like forty-second.
A small python example for converting numbers to words using num2words
looks like this:
>>> from num2words import num2words
>>> num2words(42)
forty-two
>>> num2words(42, ordinal=True)
forty-second
You can read more about what you can do using this module here
NOTE: In case somebody is wondering why this is not a code review (such as comments on the posted code), is because in the unedited question the author specifically asked if there is already a library for this.
-
7\$\begingroup\$ Well that is just cheating... +1 \$\endgroup\$Michael Richardson– Michael Richardson2017年03月01日 18:59:12 +00:00Commented Mar 1, 2017 at 18:59
-
3\$\begingroup\$ Well, in the un-edited question the author specifically asked if there is already a library for this. \$\endgroup\$ChatterOne– ChatterOne2017年03月01日 22:12:01 +00:00Commented Mar 1, 2017 at 22:12
-
1\$\begingroup\$ @ChatterOne IDK why that got edited out. Are we not supposed to ask about libraries here? So many rules :/ \$\endgroup\$James Draper– James Draper2017年03月02日 05:35:13 +00:00Commented Mar 2, 2017 at 5:35
You have quite a big bug there. In this part:
elif 100 <= num <= 999:
hundreds, below_hundred = divmod(num, 100)
tens, below_ten = divmod(below_hundred, 10)
If you have anything where the last two digits are less than 20, it's going to fail because the result is going to be 1
and 10 - that number (if you have 19
, you'll get 1
and 9
), which leads to a KeyError.
So, any number like 119
, 315
, 417
and so on will make it fail.
I'd say stick with the num2words
that @Dex'ter suggested or be prepared to do quite some debugging.
Explore related questions
See similar questions with these tags.