Welcome, guest | Sign In | My Account | Store | Cart

This function converts 0 and positive integers (or their string representations) to their ordinal values. For example, it would convert 0 to "0th", 1 to "1st", 2 to "2nd", 3 to "3rd" and so on.

Python, 54 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#!/usr/bin/env python

def ordinal(value):
    """
    Converts zero or a *postive* integer (or their string 
    representations) to an ordinal value.

    >>> for i in range(1,13):
    ...     ordinal(i)
    ...     
    u'1st'
    u'2nd'
    u'3rd'
    u'4th'
    u'5th'
    u'6th'
    u'7th'
    u'8th'
    u'9th'
    u'10th'
    u'11th'
    u'12th'

    >>> for i in (100, '111', '112',1011):
    ...     ordinal(i)
    ...     
    u'100th'
    u'111th'
    u'112th'
    u'1011th'

    """
    try:
        value = int(value)
    except ValueError:
        return value

    if value % 100//10 != 1:
        if value % 10 == 1:
            ordval = u"%d%s" % (value, "st")
        elif value % 10 == 2:
            ordval = u"%d%s" % (value, "nd")
        elif value % 10 == 3:
            ordval = u"%d%s" % (value, "rd")
        else:
            ordval = u"%d%s" % (value, "th")
    else:
        ordval = u"%d%s" % (value, "th")

    return ordval

if __name__ == '__main__':
    import doctest
    doctest.testmod()

This is a quick way to get a more reader-friendly ordinal value for zero and positive integers (including their string representations). The recipe was inspired by the similarly named "ordinal" template tag from Django's humanize module.

5 comments

grist 14 years, 5 months ago  # | flag

Code doesn't quite work properly... '11' becomes '11st' '12' becomes '12nd'

grist 14 years, 5 months ago  # | flag

Not sure about Python, but in perl I did this...

sub ordinal { my $rawvalue = int(shift); # keep the original so we can return it later my $value = $rawvalue % 100; #only need the last 2 digits for what we're doing my $suffix; if ($value == 11 || $value == 12 || $value == 13) { $suffix = 'th'; } elsif ($value % 10 == 1) { $suffix = 'st'; } elsif ($value % 10 == 2) { $suffix = 'nd'; } elsif ($value % 10 == 3) { $suffix = 'rd'; } else { $suffix = 'th'; } return "$rawvalue$suffix"; }

Which deals correctly with 11,12 etc and also deals with numbers of any length.

grist 14 years, 5 months ago  # | flag

Bah, formatting fail.

sub ordinal {
    my $rawvalue = int(shift);
    my $value = $rawvalue % 100;
    my $suffix;
    if ($value == 11 || $value == 12 || $value == 13) {
        $suffix = 'th';
    } elsif ($value % 10 == 1) {
        $suffix = 'st';
    } elsif ($value % 10 == 2) {
        $suffix = 'nd';
    } elsif ($value % 10 == 3) {
        $suffix = 'rd';
    } else {
        $suffix = 'th';
    }
    return "$rawvalue$suffix";
}
Serdar Tumgoren (author) 14 years, 1 month ago  # | flag

Hi gist, I don't seem to be getting the same errors as you. The function seems to work fine.

>>> ordinal(111)
u'111th'
>>> ordinal('111')
u'111th'
>>> ordinal(112)
u'112th'
>>> ordinal(11)
u'11th'
>>> ordinal('111')
u'111th'
>>> ordinal(12)
u'12th'
>>> ordinal('112')
u'112th'
>>> for x in (1,2,3,'4',11,19,101):
...     ordinal(x)
...     
u'1st'
u'2nd'
u'3rd'
u'4th'
u'11th'
u'19th'
u'101st'
>>>

Can you provide any more specifics that might help debug? If it helps, I'm using the function with Python 2.6.2 on Ubuntu 9.04. Regards, Serdar

Serdar Tumgoren (author) 14 years, 1 month ago  # | flag

Grist, There was indeed a mistake in the original code: I accidentally dropped the outer "else" clause when pasting it over to ActiveState (though my local code was correct, which is why the function was working for me). I've updated the recipe and it should work now. I've also noted more emphatically that this only works for positive integers or their string representations.

Apologies to folks who this might have confused/frustrated.

Cheers!

Created by Serdar Tumgoren on Wed, 19 Aug 2009 (MIT)
Python recipes (4591)
Serdar Tumgoren's recipes (1)

Required Modules

Other Information and Tasks