# Goodrich Python Chapter 5 Questions

## Q R-5.10 Caesar cipher constructor

Modify the Caesar Cipher object constructor to initialize the offset forward/backward alphabets using a list comprehension.

Here are the two key lines from the constructor:

```self._forward = ''.join([chr(ord('A') +((j + shift)%26))    for j in range(26)])
self._backward = ''.join([chr(ord('A')+((j - shift+26)%26)) for j in range(26)])
```

The expressions find the offset, beginning at the letter A (note that all strings passed in are made uppercase), that corresponds to the key "shift". Then we're adding (or subtracting) each sequential integer from 1 to 26, mod 26, so that we move in a circle.

Note that this does no error checking for non letter types, or symbols, or any of that. It's pretty awful in that respect, but it's mainly to illustrate list comprehension.

```\$ cat CaesarCipher.py
"""
Goodrich et al
Data Structures in Python
Chapter 5: Array-Based Sequences

Question R-10

Modify Caesar cipher class to have a 2-line constructor:
build the fwd and backward strings using join and the
appropriate list comprehension syntax
"""

class CaesarCipher:
"""Clas for encrypting/decrypting using Caeesar Cipher"""

def __init__(self,shift):
"""Construct Caesar cipher with the given integer shift"""
self._forward = ''.join([chr(ord('A') +((j + shift)%26))    for j in range(26)])
self._backward = ''.join([chr(ord('A')+((j - shift+26)%26)) for j in range(26)])

def encrypt(self,message):
message = message.upper()
return self._transform(message,self._forward)

def decrypt(self,ciphertext):
ciphertext = ciphertext.upper()
return self._transform(ciphertext,self._backward)

def _transform(self,original,code):
msg = list(original)
for k in range(len(msg)):
if(msg[k].isupper()):
j = ord(msg[k]) - ord('A')
msg[k] = code[j]
return ''.join(msg)

if __name__=="__main__":
c = CaesarCipher(3)
msg = "ALL GAUL IS DIVIDED INTO THREE PARTS"

print("Orig: {0}".format(msg))
coded = c.encrypt(msg)
print("Secret: {0}".format(coded))
plain = c.decrypt(coded)
print("Decrypted: {0}".format(plain))
```

### Output

```\$ python3 CaesarCipher.py
Orig: ALL GAUL IS DIVIDED INTO THREE PARTS
Secret: DOO JDXO LV GLYLGHG LQWR WKUHH SDUWV
Decrypted: ALL GAUL IS DIVIDED INTO THREE PARTS
```