ActiveState Code

Recipe 576888: format a number as an ordinal


This function changes a number from an integer or string to it's ordinal value (e.g. 1 to "1st", 2 to "2nd", 3 to "3rd").

Python
 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
#!/usr/bin/env python

def ordinal(value):
    """
    Converts an integer to it's ordinal as a string.
    For example 1 to "1st", 2 to "2nd", 3 to "3rd", etc.
    >>> for x in (1,2,3,'4',11,19,101):
    ...     ordinal(x)
    ...
    u'1st'
    u'2nd'
    u'3rd'
    u'4th'
    u'101st'
    """
    try:
        value = int(value)
    except ValueError:
        return value

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

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

Discussion

This is a quick way to get a more reader-friendly ordinal value for a number. The recipe was inspired by the similarly named "ordinal" template tag from Django's humanize module.

Comments

  1. 1. At 8:43 p.m. on 29 oct 2009, grist said:

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

  2. 2. At 9:02 p.m. on 29 oct 2009, grist said:

    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.

  3. 3. At 9:06 p.m. on 29 oct 2009, grist said:

    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";
    }
    

Sign in to comment