views:

115

answers:

3

Hi, i am a newbie to python 2.7 , trying to create a simple program, which takes an input string from the user, converts all the characters into their ascii values, adds 2 to all the ascii values and then converts the new values into text. So for example, if the user input is "test" , the output should be "vguv".

This is the code i have written so far :

message = input("enter message to encode")

for ch in message:
     message2 = ord(ch) + 2
     print "\n\n"
     encodedmessage = ""
     for item in message2.split():
            encodedmessage += chr(int(item))

print ("encoded msg in text : "), encodedmessage

It doesnt seem to be working properly, any help would be appreciated. Thanks.

+2  A: 

message2 = ord(ch) + 2 makes message2 an integer, and so of course you cannot then call split on it -- it's a single int representing a single character, why ever would you want to split it?! Plus, you're resetting encodedmessage to the empty string each time through the loop, so once you've fixed the split weirdness (by simply removing it!) you'll only see the last characted of course; move the encodedmessage = '' to before the loop instead.

Alex Martelli
It's bad practice to use the += operator on strings in general, isn't it? You're creating a new string each time it's called. Perhaps it would be better to keep a list of characters and then do `''.join(whateverlist)`?
Alex Bliskovsky
Alex: it is, and I considered this as well. But I think it would confuse the OP, so it's forgiveable on this case.
rbp
@Alex Bliskovsky: Although its often repeated that `''.join()` is faster than string concatenation, I think with modern releases of Python, that is not necessarily true. In fact, in this microtest, http://paste.ubuntu.com/479529/, `python -mtimeit -s'import test' 'test.add_strings(1000)` takes 201us, while `python -mtimeit -s'import test' 'test.join_strings(1000)` takes 250us per loop. I'd be interested to hear if @Alex Martelli would weigh in on this.
unutbu
Ah, it looks like @Alex Martelli has already answered this here: http://stackoverflow.com/questions/1349311/python-string-join-is-faster-than-but-whats-wrong-here/1350289#1350289
unutbu
@Alex, yep, but I agree with @rbp -- there are clearly deeper problems here, tackling them first seems preferable.
Alex Martelli
+1  A: 

You are mixing up characters and strings. When you loop throught a string (such as "message"), on each iteration you'll get a single character. Also, ord(ch) is an integer, a number, so you can't "split" it.

Also, don't use "input", use "raw_input" instead.

What you want is probably something similar to this:

message = raw_input("enter message to encode: ")
encoded_message = ""
for ch in message:
     encoded_ord = ord(ch) + 2

Here you don't have a new message yet, as the loop gies you one character at a time, so I'm renaming the variable to "encoded_ord", which better describes what it holds.

Now, you can turn this "encoded ord" into an encoded character, and add it to the encoded message:

     encoded_ch = chr(encoded_ord)
     encoded_message += chr(encoded_ch)

print "encoded msg in text:", encodedmessage
rbp
+1  A: 

Are you trying to do a rot-13 (or generalized "rot-x") type function?

from string import ascii_uppercase, ascii_lowercase

def rotx(data,rotby):
    total = []
    for char in data:
        if char in ascii_uppercase:
            index = (ascii_uppercase.find(char) + rotby) % 26
            total.append(ascii_uppercase[index])
        elif char in ascii_lowercase:
            index = (ascii_lowercase.find(char) + rotby) % 26
            total.append(ascii_lowercase[index])
        else:
            total.append(char)
    return "".join(total)

Running:

>>> import rotx
>>> rotx.rotx("test",2)
'vguv'
>>> rotx.rotx("IBM-9000",-1)
'HAL-9000'

If you blanket add 2 to ASCII characters, } becomes non-printable, ~ turns into something depending on your character encoding

Nick T