2

I have been playing with Python and came across a task from MIT, which is to create coded message (Julius Cesar code where for example you change ABCD letters in message to CDEF). This is what I came up with:

Phrase = input('Type message to encrypt: ')
shiftValue = int(input('Enter shift value: '))

listPhrase = list(Phrase)
listLenght = len(listPhrase)

ascii = []
for ch in listPhrase:
  ascii.append(ord(ch))
print (ascii)

asciiCoded = []
for i in ascii:
    asciiCoded.append(i+shiftValue)
print (asciiCoded)

phraseCoded = []
for i in asciiCoded:
    phraseCoded.append(chr(i))
print (phraseCoded)

stringCoded = ''.join(phraseCoded)
print (stringCoded)

The code works but I have to implement not shifting the ascii value of spaces and special signs in message.

So my idea is to select values in list in range of range(65,90) and range(97,122) and change them while I do not change any others. But how do I do that?

Sнаđошƒаӽ
  • 16,753
  • 12
  • 73
  • 90
RadekE
  • 37
  • 4
  • you can use `isalpha()` method http://stackoverflow.com/questions/15558392/how-to-check-if-character-in-string-is-a-word-character-python – RinaLiu Feb 28 '16 at 13:28

3 Answers3

0

If you want to use that gigantic code :) to do something as simple as that, then you keep a check like so:

asciiCoded = []
for i in ascii:
    if 65 <= i <= 90 or 97 <= i <= 122:  # only letters get changed
        asciiCoded.append(i+shiftValue)
    else:
        asciiCoded.append(i)

But you know what, python can do the whole of that in a single line, using list comprehension. Watch this:

Phrase = input('Type message to encrypt: ')
shiftValue = int(input('Enter shift value: '))

# encoding to cypher, in single line
stringCoded = ''.join(chr(ord(c)+shiftValue) if c.isalpha() else c for c in Phrase)

print(stringCoded)

A little explanation: the list comprehension boils down to this for loop, which is easier to comprehend. Caught something? :)

temp_list = []
for c in Phrase:
    if c.isalpha():
        # shift if the c is alphabet
        temp_list.append(chr(ord(c)+shiftValue))
    else:
        # no shift if c is no alphabet
        temp_list.append(c)

# join the list to form a string
stringCoded = ''.join(temp_list)
Sнаđошƒаӽ
  • 16,753
  • 12
  • 73
  • 90
  • If you don't want to have "magic numbers" floating around, `65`, `90`, `97`, and `122` are `ord('A')`, `ord('Z')`, `ord('a')`, and `ord('z')` respectively. – pzp Feb 28 '16 at 13:47
  • I know, but from OP it seems reasonable to guess that the OP knows it too. So no harm using those magic numbers. Take care, two OPs mean different. :) – Sнаđошƒаӽ Feb 28 '16 at 13:49
  • Shadowfax Could you tell me, or link me to explanation, what does those double parenthesis do? For egsample here: stringCoded = ''.join(temp_list) – RadekE Feb 29 '16 at 14:53
  • @RadekE take a look at this [str.join](https://docs.python.org/3/library/stdtypes.html#str.join), and [this](http://stackoverflow.com/questions/12453580/concatenate-item-in-list-to-strings-python). Hope that will help. – Sнаđошƒаӽ Feb 29 '16 at 15:06
0

Much easier it is to use the maketrans method from the string module:

>>import string
>>
>>caesar = string.maketrans('ABCD', 'CDEF')
>>
>>s = 'CAD BA'
>>
>>print s
>>print s.translate(caesar)
CAD BA
ECF DC

EDIT: This was for Python 2.7

With 3.5 just do

caesar = str.maketrans('ABCD', 'CDEF')

And an easy function to return a mapping.

>>> def encrypt(shift):
...     alphabet = string.ascii_uppercase
...     move = (len(alphabet) + shift) % len(alphabet)
...     map_to = alphabet[move:] + alphabet[:move]
...     return str.maketrans(alphabet, map_to)
>>> "ABC".translate(encrypt(4))
'EFG'

This function uses modulo addition to construct the encrypted caesar string.

jazz
  • 2,371
  • 19
  • 23
  • The OP is tagged with python 3.x. Yours is for python 2.x. And it does not take into account the shiftValue taken as input from the user. And it would be awfully clumsy if A-Z and a-z are to be handled. – Sнаđошƒаӽ Feb 28 '16 at 14:04
  • Thank you Shadowfax. Obviously I am a lazy reader ;-) I have updated my comment to reflect your comment. – jazz Feb 28 '16 at 14:29
-1
asciiCoded = []
final_ascii = ""
for i in ascii:
    final_ascii = i+shiftValue #add shiftValue to ascii value of character
    if final_ascii in range(65,91) or final_ascii in range(97,123): #Condition to skip the special characters
        asciiCoded.append(final_ascii)
    else: 
        asciiCoded.append(i)
print (asciiCoded)