Ordinal number to words in Python

Question:

The problem

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:

  • 1stfirst
  • 2ndsecond
  • 60thsixtieth
  • 523rdfive hundred twenty-third

What I have tried

num2words converts the numbers to words. But it does not work for ordinal terms such as 1st, 2nd, 60th and etc.

The question

How is possible to use python to turn ordinal numbers into words?

Asked By: Michael

||

Answers:

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
Answered By: asongtoruin

Remove the ordinal endings from the strings:

import re

re.findall('d+', stringValue)

and then use

num2words(foundInteger, ordinal=True)
Answered By: Minory

The entire solution

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'
Answered By: Michael

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)
Answered By: nimbusmom
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
Answered By: Zachary Kosove
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.