Okay, here's my issue. I want to take a message a user enters, and then take it and convert it to a number, the standard a-z = 1-26, with space equaling 0. I haven't put in any punctuation yet. Anyways, I think I needed a loop, and I made this code to do it:

message = raw_input()

x = 0
y = 0
letters = list(message)
letters_len = len(letters)
message_number = []

while x < letters_len:
    if letters[x] == ' ':
        y = 0
        message_number.append(y)
        x = x+1
    if letters[x] == 'A' or 'a':
        y = 1
        message_number.append(y)
        x = x+1
    if letters[x] == 'B' or 'b':
        y = 2
        message_number.append(y)
        x = x+1
    if letters[x] == 'C' or 'c':
        y = 3
        message_number.append(y)
        x = x+1
    if letters[x] == 'D' or 'd':
        y = 4
        message_number.append(y)
        x = x+1
    if letters[x] == 'E' or 'e':
        y = 5
        message_number.append(y)
        x = x+1
    if letters[x] == 'F' or 'f':
        y = 6
        message_number.append(y)
        x = x+1
    if letters[x] == 'G' or 'g':
        y = 7
        message_number.append(y)
        x = x+1
    if letters[x] == 'H' or 'h':
        y = 8
        message_number.append(y)
        x = x+1
    if letters[x] == 'I' or 'i':
        y = 9
        message_number.append(y)
        x = x+1
    if letters[x] == 'J' or 'j':
        y = 10
        message_number.append(y)
        x = x+1
    if letters[x] == 'K' or 'k':
        y = 11
        message_number.append(y)
        x = x+1
    if letters[x] == 'L' or 'l':
        y = 12
        message_number.append(y)
        x = x+1
    if letters[x] == 'M' or 'm':
        y = 13
        message_number.append(y)
        x = x+1
    if letters[x] == 'N' or 'n':
        y = 14
        message_number.append(y)
        x = x+1
    if letters[x] == 'O' or 'o':
        y = 15
        message_number.append(y)
        x = x+1
    if letters[x] == 'P' or 'p':
        y = 16
        message_number.append(y)
        x = x+1
    if letters[x] == 'Q' or 'q':
        y = 17
        message_number.append(y)
        x = x+1
    if letters[x] == 'R' or 'r':
        y = 18
        message_number.append(y)
        x = x+1
    if letters[x] == 'S' or 's':
        y = 19
        message_number.append(y)
        x = x+1
    if letters[x] == 'T' or 'T':
        y = 20
        message_number.append(y)
        x = x+1
    if letters[x] == 'U' or 'u':
        y = 21
        message_number.append(y)
        x = x+1
    if letters[x] == 'V' or 'v':
        y = 22
        message_number.append(y)
        x = x+1
    if letters[x] == 'W' or 'w':
        y = 23
        message_number.append(y)
        x = x+1
    if letters[x] == 'X' or 'X':
        y = 24
        message_number.append(y)
        x = x+1
    if letters[x] == 'Y' or 'y':
        y = 25
        message_number.append(y)
        x = x+1
    if letters[x] == 'Z' or 'z':
        y = 26
        message_number.append(y)
        x = x+1

Sorry the code is so long. Anyways, here's my issue. I'm using "Get help" as the example message. When I was just using the 'A' or 'a', and i typed print message_number, it came up with (1, 1, 1, 1, 1, 1, 1, 1). Including all letters, it gives an error, and if I print message_number, it shows (1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8). Here's the error:

Traceback (most recent call last):
  File "<pyshell#120>", line 38, in <module>
    if letters[x] == 'I' or 'i':
IndexError: list index out of range

Can anyone help out?

Recommended Answers

All 9 Replies

Member Avatar for masterofpuppets

hi,
a better way to do this is to use a dictionary for the letters instead of all these if..elif statements, like this:

def createLetterDictionary(): # Creates the dictionary of letter-number pairs
    l = {}
    letters = " abcdefghijklmnopqrstuvwxyz"
    for i in range( len( letters ) ):
        l[ letters[ i ] ] = i
    return l


message = raw_input()
 
letters = list( message )
alphabet = createLetterDictionary()
message_number = []

for letter in letters:
    if letter in alphabet: # check if the character is in the dictionary
        message_number.append( alphabet[ letter ] )

print message_number

I'm assuming you've heard of dictionaries, otherwise you can do something like this:

message = raw_input()
 
letters = list( message )
alphabet = " abcdefghijklmnopqrstuvwxyz"
message_number = []

for letter in range( len( letters ) ):
    if letters[ letter ] in alphabet:
        for i in range( len( alphabet ) ):
            if letters[ letter ] == alphabet[ i ]:
                message_number.append( i )
                break

print message_number

hope this helps :)

Wow, that code is pretty long!

Here's a shortened version:

import string

# Strings are already iterable so we don't need to convert to list
message = raw_input('Enter a string: ')
# Make a string of a space plus all the lower case letters (the first
## 26 indices of the string.letters object is all lowercase).
my_letters = ' ' + string.letters[:26]

message_number = []

# Just iterate over the message, we don't care about index
for each_char in message:
    message_number.append(my_letters.index(each_char.lower()))

print message_number
raw_input('\nPress any key to exit...')

If there's anything you don't understand please don't hesitate to ask.

The error you were reporting was based in your original code:

if letters[x] == ' ':
        y = 0
        message_number.append(y)
        x = x+1
    if letters[x] == 'A' or 'a':
        y = 1
        message_number.append(y)
        x = x+1
    if letters[x] == 'B' or 'b':
        y = 2
        message_number.append(y)
        x = x+1

The first if test is ok, but the second test and all additional tests would always be true because they are improperly formed. What you intended to test needed to be written like this:

if letters[x] == ' ':
        y = 0
        message_number.append(y)
        x = x+1
    if letters[x] == 'A' or letters[x] == 'a':
        y = 1
        message_number.append(y)
        x = x+1
    if letters[x] == 'B' or letters[x] == 'b':
        y = 2
        message_number.append(y)
        x = x+1

But either of the two examples you were given would be a much better solution. Just wanted to make sure you understood why what you had didn't work even if it was a 'brute force' solution.

@ masterofpuppets and Jilm:
Thank you for the shorter code :D That'll help when I create the second version of it. Since I am still learning Python, I want to try and do everything with what I know. And I was going to start using libraries, so that helps a great deal :D By the way, mop, love you name xD Master of Puppets is one of my favorite albums.

@ Murtan:
Thank you for pointing this out for me. :D

Okay, here's something wierd. I'm using this from masterofpuppets:

letters = list( message )
alphabet = " abcdefghijklmnopqrstuvwxyz"
message_number = []

for letter in range( len( letters ) ):
    if letters[ letter ] in alphabet:
        for i in range( len( alphabet ) ):
            if letters[ letter ] == alphabet[ i ]:
                message_number.append( i )
                break

Okay, I get the numbers i need, but it excludes the first. Coding the phrase "Get help" returns: [5, 20, 0, 8, 5, 12, 16]. Oh. Wait... Entering "get help" returns: [7, 5, 20, 0, 8, 5, 12, 16]. Okay... so I guess now I need to learn how to make it all lowercase... That's using the string module... Shall do a search for that. Sorry I'm typing all this here xD It helps me think, and it'd be a good log for anyone doing what i'm doing. When I get this part working, I'll let you know what I'm actually doing

Member Avatar for masterofpuppets

@ hondros
:) yeah.. sorry about that I forgot to mention that you'll need to convert the character into lowercase as well :) Have a go at doing this and if you have any problems we'll be happy to help :)

"string".lower() is simple and you could do it in various places. Here is a really simple way to handle the whole thing:

(letters, alph, di) = (list(raw_input('Enter your string -->').lower()), " abcdefghijklmnopqrstuvwxyz", [])


for lets in letters: 
    if lets in alph: di.append(alf.index(lets))

:D
I got it all finished, all working. Well, my Algebra 2 class just started Matrices, and for an extra credit project, we have to create an encoding matrix, 2x2, and code a message. So, I asked if I could make a program to code a message for me. She said as long as she showed me the program, and the code. :D So, this is all my functions to encode a message. It's very simple for now, but I'm going to make it more complex later, and have it include puntcuation, a caesar shift to begin with, reading files, etc. But anyways, here's my code:

################################
## Hondros' Encoder
## ~ Hondros
import string

a = 0

### Define the encoding matrix
def matrix_input(a):
    print 'First row, first column:'
    A_1_1 = int(raw_input(''))
    print 'First row, second column:'
    A_1_2 = int(raw_input(''))
    print 'Second row, second column:'
    A_2_1 = int(raw_input(""))
    print 'Second row, second column:'
    A_2_2 = int(raw_input(""))
    A_1 = (A_1_1, A_1_2)
    A_2 = (A_2_1, A_2_2)
    A = A_1, A_2
    matrix_input.A = A
    print 'Matrix A is:'
    print A_1
    print A_2


### Find determinant of the matrix
def determinant(encode_matrix):
    A = encode_matrix
    x = A[0][0]*A[1][1]
    y = A[1][0]*A[0][1]
    determinant.d = x - y


### Find the modified matrix
def modified(encode_matrix):
    B = encode_matrix
    d = determinant.d
    B_1_1 = B[1][1]
    B_1_2 = -B[0][1]
    B_2_1 = -B[1][0]
    B_2_2 = B[0][0]
    B_1 = (B_1_1, B_1_2)
    B_2 = (B_2_1, B_2_2)
    modified.m = (B_1, B_2)


### Find the inverse of the matrix
### This is the decoding matrix
def inverse(encode_matrix):
    d = determinant.d
    di = 1.0/d
    M = modified
    i_1_1 = M[0][0] * di
    i_1_2 = M[0][1] * di
    i_2_1 = M[1][0] * di
    i_2_2 = M[1][1] * di
    i_1 = (i_1_1, i_1_2)
    i_2 = (i_2_1, i_2_2)
    inverse.i = (i_1, i_2)


### The basic algorithim to multiply a 1x2 matix by a 2x2
def multiply_2x2_encode(Z, A):
    C_1_1 = (Z[0]*A[0][0]) + (Z[1]*A[1][0])
    C_1_2 = (Z[0]*A[0][1]) + (Z[1]*A[1][1])
    C = (C_1_1, C_1_2)
    multiply_2x2_encode.C = C


### Turn the message into a number list
###
#####################################################
## Helped by masterofpuppets at daniweb.com forums
def letter_number(message_raw):
    message_raw = message_raw
    message = string.lower(message_raw)
    letters = list(message)
    alphabet = " abcdefghijklmnopqrstuvwxyz"
    message_number = []
    for letter in range( len( letters ) ):
        if letters[ letter ] in alphabet:
            for i in range( len( alphabet ) ):
                if letters[ letter ] == alphabet[ i ]:
                    message_number.append( i )
                    break
    letter_number.message_number = message_number
    letter_number.message = message
#######################################################


### Encode the message using a matrix
def encode(encode_matrix):
    A = matrix_input.A
    letters = list( message )
    letters_len = len(letters)
    coded = []
    x = 0
    while x < (letters_len -1):
        Z = (message_number[x:(x+2)])
        multiply_2x2_encode(Z, A)
        coded.append(multiply_2x2_encode.C)
        x = x+2
    encode.coded = coded



#########################################################
### Start of program
### Woot!
a = 0
message_raw = raw_input("==> ")
letter_number(message_raw)
message = letter_number.message
matrix_input(a)
encode_matrix = matrix_input.A
determinant(encode_matrix)
if determinant.d == 0:
    print 'You cannot use this matrix for coding. Please choose another'
    matrix_input(a)
    encode_matrix = matrix_input.A
    determinant(encode_matrix)
modified(encode_matrix)
modified = modified.m
inverse(encode_matrix)
i = inverse.i
message_number = letter_number.message_number
A = encode_matrix
encode(encode_matrix)
print encode.coded

Try it out!
Granted, I know it's a lot of code, so I'm going to shorten it up later. Feel free to use it however you want, I just ask that I am given credit. And you can feel free to put up your own program for it, or edit mine, here. Give me some ideas for shortening if you wish, but I might not get back here to tell you about it, until I get the whole thing finished, I want to do it myself first :D. Thanks for the help!
Again, sorry for so much code!

By the way, I used the message "Get help" as an example for it. The example matrix was ((2, 3), (-1, -2)) I suggest using multiples of this matrix if you wish to get clean numbers, ie, no fractions/decimals. I'm not sure if decimals work right now, and it wouldn't even show up as a decimal if it turned out as a decimal, it would just round.

...### Turn the message into a number list
###
#####################################################
## Helped by masterofpuppets at daniweb.com forums
def letter_number(message_raw):
    message_raw = message_raw
    message = string.lower(message_raw)
    letters = list(message)
    alphabet = " abcdefghijklmnopqrstuvwxyz"
    message_number = []
    for letter in range( len( letters ) ):
        if letters[ letter ] in alphabet:
            for i in range( len( alphabet ) ):
                if letters[ letter ] == alphabet[ i ]:
                    message_number.append( i )
                    break
    letter_number.message_number = message_number
    letter_number.message = message
#######################################################

All of that can be turned into this:

def letter_number_alt(message):
    alphabet = " abcdefghijklmnopqrstuvwxyz"
    message_number = [alphabet.index(letter) for letter in message.lower() if letter in alphabet]

Also, notice you don't need to import string and use string.lower(string_to_lower) , you can just use string_to_lower.lower()

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.