Sequential Generation from an Index Value

I needed to be able to generate a sequence of letters from a specific index value. Basically, I wanted to loop through a sequence of values and retrieve the corresponding string value. For example, 0 would be A; 4 would be E; 36 would be AK; etc.

0 = A
1 = B
2 = C
3 = D
4 = E
5 = F
21 = V
22 = W
23 = X
24 = Y
25 = Z
26 = AA
27 = AB
28 = AC
36 = AK
37 = AL
38 = AM
39 = AN

I have created a small python script as a proof of concept that does the calculation using two different methods. Method 1, uses a recursive function to build up the correct sequence from the index value. Essentially the code is treating the index integer as a value that has the index into a large 2D are encoded within it. We use the modulus method to extract the index for the particular row. We then subtract the difference from the index to see if there are any more letters stored in the encoded index. Method 1 returns the value of the sequence in the correct order.

Method 1:

def get_name(index):
    """
    Translate the index to a set of letters in sequential order.
    """

    #termination criteria
    if index < 0:
        return ''

    #Take the modulus of the current index and translate it into one of the
    #characters stored in the letters string.
    selected_index = index % lettersCount

    return letters[selected_index] + get_name(math.floor((index - lettersCount)/lettersCount))

Method 2 works in a similar manor, yet simpler, to Method 1. However it calculates the sequence in reverse order. So in order for the result to be useful, the sequence must be reversed.

Method 2:

def get_name2(index, values = []):
    """
    Translate the index to a set of letters in sequential order, but reversed.
    """

    if not values:
        values = []

    #termination criteria
    if index < 0:
        return values

    #Take the modulus of the current index and translate it into one of the
    #characters stored in the letters string.
    selected_index = index % lettersCount
    values.append(letters[selected_index])

    return get_name2(math.floor((index - lettersCount)/lettersCount), values)

Here is a script to demonstrate the methods:

#!/usr/bin/env python3
#-*- coding:utf-8 -*-

"""

    index = 0, value = A
    index = 1, value = B
    index = 2, value = C
    index = 3, value = D
    index = 4, value = E
    index = 5, value = F
    index = 6, value = G
    index = 7, value = H
    index = 8, value = I
    index = 9, value = J
    index = 10, value = K
    index = 11, value = L
    index = 12, value = M
    index = 13, value = N
    index = 14, value = O
    index = 15, value = P
    index = 16, value = Q
    index = 17, value = R
    index = 18, value = S
    index = 19, value = T
    index = 20, value = U
    index = 21, value = V
    index = 22, value = W
    index = 23, value = X
    index = 24, value = Y
    index = 25, value = Z
    index = 26, value = AA
    index = 27, value = AB
    index = 28, value = AC
    index = 29, value = AD
    index = 30, value = AE
    index = 31, value = AF
    index = 32, value = AG
    index = 33, value = AH
    index = 34, value = AI
    index = 35, value = AJ
    index = 36, value = AK
    index = 37, value = AL
    index = 38, value = AM
    index = 39, value = AN
"""

import math
import sys

letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
# letters = 'ABCDEF'
lettersCount = len(letters)

def get_name(index):
    """
    Translate the index to a set of letters in sequential order.
    """

    #termination criteria
    if index < 0:
        return ''

    #Take the modulus of the current index and translate it into one of the
    #characters stored in the letters string.
    selected_index = index % lettersCount

    return letters[selected_index] + get_name(math.floor((index - lettersCount)/lettersCount))

def test1():
    print(letters)
    print('index = 8: ', get_name(8)[::-1])
    print('index = 15: ',get_name(15)[::-1])
    print('index = 17: ',get_name(17)[::-1])
    print('index = 18: ',get_name(18)[::-1])
    print('index = 75: ',get_name(75)[::-1])
    print('index = 1000: ',get_name(1000)[::-1])
    print()

    for i in range(100):
        print('index = {}, value = {}'.format(i, get_name(i)[::-1]))

def get_name2(index, values = []):
    """
    Translate the index to a set of letters in sequential order, but reversed.
    """

    if not values:
        values = []

    #termination criteria
    if index < 0:
        return values

    #Take the modulus of the current index and translate it into one of the
    #characters stored in the letters string.
    selected_index = index % lettersCount
    values.append(letters[selected_index])

    return get_name2(math.floor((index - lettersCount)/lettersCount), values)

def test2():
    print(letters)

    for i in range(1000):
        print('index = {}, value = {}'.format(i,
                                              ''.join(reversed(get_name2(i)))))

def main():
    """
    This runs the rest of the functions in this module
    """

    print('test1')
    test1()

    print('test2')
    test2()

    return 0 # success

if __name__ == '__main__':
    status = main()
    sys.exit(status)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s