Feed Sign in with OpenID OpenID

Simon Willison’s Weblog

Python snippet: ordinalth(n)

Blogged so I don’t lose it (blogging as external memory):

def ordinalth(n):
    """ 1 => 1st, 2 => 2nd etc """
    last = n - n / 10 * 10
    if last == 1:
        return '%dst' % n
    if last == 2:
        return '%dnd' % n
    if last == 3:
        return '%drd' % n
    return '%dth' % n

Update: See comments for improved version.

This is Python snippet: ordinalth(n) by Simon Willison, posted on 8th October 2003.

View blog reactions

Next: "Getting" Python

Previous: Yahoo News Search RSS feeds

11 comments

  1. Nice trick Simon, but i would remove if's completely:

    def ordinalth2(n):

    t = '%dth', '%dst', '%dnd', '%drd', '%dth', '%dth', '%dth' , '%dth' , '%dth', '%dth'

    last = n - (n / 10 * 10)

    return t[last] % n

    if you pass 21 to ordinalth and ordinalth they both retiurn "21st", mmm...

    deelan - 8th October 2003 15:42 - #

  2. Watch out for 11st, 12nd, 13rd.

    talon - 8th October 2003 15:44 - #

  3. last = n % 10

    Sam Ruby - 8th October 2003 15:58 - #

  4. Improved version, taking the above comments in to account:

    def ordinalth(n):
        t = 'th st nd rd th th th th th th'.split()
        if n in (11, 12, 13): #special case
            return '%dth' % n
        return str(n) + t[n % 10]

    Test code:

    for i in range(1, 101):
        print ordinalth(i)

    (I've finally enabled the <pre> tag)

    Simon Willison - 8th October 2003 16:11 - #

  5. That should be

    if (n % 100) in (11, 12, 13):

    Curioso - 8th October 2003 16:24 - #

  6. You're absolutely right, I hadn't spotted that.

    Simon Willison - 8th October 2003 16:30 - #

  7. You missed 111th. Untested, but should work (just need to mod 100 for the 11th..13th):

    def ordinalth(n):
        t = 'th st nd rd th th th th th th'.split()
        if n % 100 in (11, 12, 13): #special case
            return '%dth' % n
        return str(n) + t[n % 10]
    

    Brian Harnish - 8th October 2003 16:32 - #

  8. Nice! "blogging as external memory" HAH! What is the computer analogous to that incredible display of rapid-fire collaboration following a simple "note to self"?

    DeanG - 8th October 2003 17:11 - #

  9. I whipped this up last week:
    def inttoord(i):
        ordinal = [ ('th', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th'),
                    ('th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th')]
        ones = i % 10
        tens = (i % 100) / 10
        return str(i) + ordinal[tens==1][ones]

    Bill - 8th October 2003 17:32 - #

  10. whoa, you guys are geniuses. i don't know what this is but it looks complicated. im bad at math and shit.

    ryandjess@aaaaaaatt.net - 29th December 2003 15:40 - #

  11. I like to avoid all procedural statements and program functionally (as a lisp programmer might), avoiding repetitious code as much as possible. Here's my implementation.
    def ordinalth(n):
    	"""Return the ordinal with 'st', 'th', or 'nd' appended as appropriate.
    	>>> map( ordinalth, xrange( -5, 22 ) )
    	['-5th', '-4th', '-3rd', '-2nd', '-1st', '0th', '1st', '2nd', '3rd', '4th', '5th', '6th', '7th', '8th', '9th', '10th', '11th', '12th', '13th', '14th', '15th', '16th', '17th', '18th', '19th', '20th', '21st']
    	"""
    	# zero through three map to 'th', 'st', 'nd', 'rd'
    	t = ( 'th', 'st', 'nd', 'rd' )
    	# special case: ones digit is > 3
    	ones = abs( n ) % 10
    	forceth = ones > 3
    	# special case: n ends in 11, 12, 13
    	forceth |= abs( n ) % 100 in (11, 12, 13)
    	index = [ ones, 0 ][forceth]
    	return '%d%s' % ( n, t[index] )
    

    Jason R. Coombs - 14th May 2004 17:22 - #

Comments are closed.

Previously hosted at http://simon.incutio.com/archive/2003/10/08/externalMemory

A django site