I won't say much besides what's here. My disgusting list comprehension in the return
statement is quite a headfullheadful.
"""Hopefully this function will save you the trip to oocalc/excel.
"""
def rangeth(start, stop=None, skip=1):
"""rangeth([start,] stop[, skip])
returns a list of strings as places in a list (1st, 2nd, etc)
>>> rangeth(4)
['0th', '1st', '2nd', '3rd']
"""
if stop is None:
stop, start = start, 0
places = {'1':'st', '2':'nd', '3':'rd'}
return ["{}{}".format(i, places.get(i[-1], 'th')) \
if i[-2:] not in ['11', '12', '13'] else "{}{}".format(i, 'th') \
for i in map(str, range(start, stop, skip))]
Also, can someone explain to me how range
accepts it's parameters? I have my ugly little boilerplate here that I wish didn't exist. I can't find the source for range, as I gave up after thinking it's probably some header file in include
.
EDIT: I found the source code for range
in a question on SO. Thanks for the answers so far!
FINAL
Alright, I have to hand it to both @WinstonEwert
and @DonQuestion
for two new things I learned today: passing *args
to clean up my function's __doc__
, and taking a second look at %10
and //10
in place of numeric string manipulation.
def nth(n):
m = abs(n)
if m % 10 < 4 and m // 10 != 1:
return '{}{}'.format(n, ('th', 'st', 'nd', 'rd')[m % 10])
return '{}{}'.format(n, 'th')
def rangeth(*args):
"""[start ,] stop[, step] -> list of places"""
return list(map(nth, range(*args)))
This works with negative numbers now, which I overlooked at first. Thanks again!