Reputation: 3356
The input is a sentence containing words, numbers and ordinal numbers such as 1st
, 2nd
, 60th
and etc.
The output should contain only words. For example:
1st
→ first
2nd
→ second
60th
→ sixtieth
523rd
→ five hundred twenty-third
num2words
converts the numbers to words. But it does not work for ordinal terms such as 1st
, 2nd
, 60th
and etc.
How is possible to use python to turn ordinal numbers into words?
Upvotes: 6
Views: 4959
Reputation: 1
def get_suffix(num: int) -> str:
last_two_digits = num % 100
last_digit = num % 10
suffix = {1: 'st', 2: 'nd', 3: 'rd'}.get(last_digit, 'th')
if last_two_digits in [11, 12, 13]: suffix = "th"
return suffix
def ordinal_to_english(o_num: int) -> str:
if not isinstance(o_num, int) or o_num < 0:
return "Error: input must be a positive integer"
# Spelling of numbers less than 20
spelling = {
1: "fir",
2: "seco",
3: "thi",
4: "four",
5: "fif",
6: "six",
7: "seven",
8: "eigh",
9: "nin",
10: "ten",
11: "eleven",
12: "twelf",
13: "thirteen",
14: "fourteen",
15: "fifteen",
16: "sixteen",
17: "seventeen",
18: "eighteen",
19: "nineteen"
}
# Spelling of multiples of 10
tens_root = {
2: "twen",
3: "thir",
4: "for",
5: "fif",
6: "six",
7: "seven",
8: "eigh",
9: "ninet"
}
# Spelling of multiples of 100
hundreds_spelling = {
1: "hundred",
2: "two hundred",
3: "three hundred",
4: "four hundred",
5: "five hundred",
6: "six hundred",
7: "seven hundred",
8: "eight hundred",
9: "nine hundred"
}
# Get the last two digits and the last digit of the number
last_two_digits = o_num % 100
last_digit = o_num % 10
tens = last_two_digits // 10
hundreds = o_num // 100 # adjust later for larger numbers
if last_two_digits > 19:
root = tens_root[tens]
if 0 < last_two_digits < 20:
ending_ordinal = spelling[last_two_digits] + get_suffix(last_two_digits)
elif last_two_digits == 0:
ending_ordinal = hundreds_spelling[hundreds] + 'th'
elif last_digit == 0:
ending_ordinal = root + "tieth"
else:
ending_ordinal = spelling[last_digit] + get_suffix(last_digit)
compound_ordinal = root + "ty-" + ending_ordinal
if o_num < 100:
if 0 < last_two_digits < 20 or last_digit == 0:
return ending_ordinal
else:
return compound_ordinal
else:
if 0 < last_two_digits < 20:
return hundreds_spelling[hundreds] + " and " + ending_ordinal
elif last_two_digits == 0:
return ending_ordinal
else:
return hundreds_spelling[hundreds] + " and " + compound_ordinal
Upvotes: 0
Reputation: 3356
import re
from num2words import num2words
def replace_ordinal_numbers(text):
re_results = re.findall('(\d+(st|nd|rd|th))', text)
for enitre_result, suffix in re_results:
num = int(enitre_result[:-len(suffix)])
text = text.replace(enitre_result, num2words(num, ordinal=True))
return text
def replace_numbers(text):
re_results = re.findall('\d+', text)
for term in re_results:
num = int(term)
text = text.replace(term, num2words(num))
return text
def convert_numbers(text):
text = replace_ordinal_numbers(text)
text = replace_numbers(text)
return text
if __name__ == '__main__':
assert convert_numbers('523rd') == 'five hundred and twenty-third'
Upvotes: 6
Reputation: 11
for numbers to ordinal values from 1-12, not sure how to do it the "shorter" way but this way uses basic python functions :)
def integerToOrdinal(x):
if x == 1
ordinal = "first"
if x == 2:
ordinal = "second"
if x == 3:
ordinal = "third"
if x == 4:
ordinal = "fourth"
if x == 5:
ordinal = "fifth"
if x == 6:
ordinal = "sixth"
if x == 7:
ordinal = "seventh"
if x == 8:
ordinal = "eigth"
if x == 9:
ordinal = "ninth"
if x == 10:
ordinal = "tenth"
if x == 11:
ordinal = "eleventh"
if x == 12:
ordinal = "twelfth"
return ordinal
x = int(input())
result = integerToOrdinal(x)
print(result)
Upvotes: -1
Reputation: 114
Remove the ordinal endings from the strings:
import re
re.findall('\d+', stringValue)
and then use
num2words(foundInteger, ordinal=True)
Upvotes: 5
Reputation: 10359
With num2words
, you should be using ordinal=True
to get the output you desire, as noted in its documentation:
from num2words import num2words
print(num2words(1, ordinal=True))
print(num2words(2, ordinal=True))
print(num2words(60, ordinal=True))
print(num2words(523, ordinal=True))
prints:
first
second
sixtieth
five hundred and twenty-third
Upvotes: 10